Skip to content

Commit dddaedd

Browse files
authored
[PRMP-1547] Allow not my record journey for non active patients (#1148)
1 parent 2c7b795 commit dddaedd

File tree

8 files changed

+13
-210
lines changed

8 files changed

+13
-210
lines changed

app/cypress/e2e/0-ndr-core-tests/gp_user_workflows/patient_search_and_verify_workflow.cy.js

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ describe('GP Workflow: Patient search and verify', () => {
118118
);
119119

120120
it(
121-
'Does not show verify patient view when the user does not have access to the patient',
121+
'Does not show verify patient view when the patient is not found on PDS',
122122
{ tags: 'regression' },
123123
() => {
124124
setup(role);
@@ -148,63 +148,6 @@ describe('GP Workflow: Patient search and verify', () => {
148148
);
149149
});
150150

151-
it(
152-
'Does not show the upload documents page when upload patient is verified and inactive as a GP_Clinical',
153-
{ tags: 'regression' },
154-
() => {
155-
setup(Roles.GP_CLINICAL);
156-
157-
cy.intercept('GET', '/SearchPatient*', {
158-
statusCode: 200,
159-
body: patient,
160-
}).as('search');
161-
162-
cy.get('#nhs-number-input').click();
163-
cy.get('#nhs-number-input').type(testPatient);
164-
165-
cy.get('#search-submit').click();
166-
cy.wait('@search');
167-
168-
cy.get('#nhs-number-input--error-message').should('be.visible');
169-
cy.get('#nhs-number-input--error-message').should(
170-
'include.text',
171-
"Error: You cannot access this patient's record",
172-
);
173-
cy.get('#error-box-summary').should('be.visible');
174-
cy.get('#error-box-summary').should('have.text', 'There is a problem');
175-
},
176-
);
177-
178-
it(
179-
'Does not show the upload documents page when upload patient is disabled and patient is inactive as a GP_ADMIN',
180-
{ tags: 'regression' },
181-
() => {
182-
setup(Roles.GP_ADMIN, {
183-
uploadArfWorkflowEnabled: false,
184-
});
185-
186-
cy.intercept('GET', '/SearchPatient*', (req) => {
187-
req.reply({
188-
statusCode: 200,
189-
body: patient,
190-
});
191-
}).as('search');
192-
193-
cy.get('#nhs-number-input').click();
194-
cy.get('#nhs-number-input').type(testPatient);
195-
196-
cy.get('#search-submit').click();
197-
cy.wait('@search');
198-
199-
cy.get('#nhs-number-input--error-message').should('be.visible');
200-
cy.get('#nhs-number-input--error-message').should(
201-
'include.text',
202-
"Error: You cannot access this patient's record",
203-
);
204-
cy.get('#error-box-summary').should('be.visible');
205-
cy.get('#error-box-summary').should('have.text', 'There is a problem');
206-
},
207-
);
208151
});
209152

210153
function setup(role, featureFlags) {

app/src/components/blocks/_admin/reviewDetailsPatientSearchStage/ReviewDetailsPatientSearchStage.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,7 @@ const ReviewDetailsPatientSearchStage = ({
104104
handleSuccess,
105105
baseUrl,
106106
baseHeaders,
107-
userIsGPAdmin: false,
108-
userIsGPClinical: false,
109107
mockLocal: config.mockLocal,
110-
featureFlags: config.featureFlags,
111108
};
112109

113110
const result = await handleSearch(args);

app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,7 @@ const ReviewsDetailsStage = ({
165165
},
166166
baseUrl,
167167
baseHeaders,
168-
userIsGPAdmin: role === 'GP_ADMIN',
169-
userIsGPClinical: role === 'GP_CLINICAL',
170168
mockLocal: config.mockLocal,
171-
featureFlags: config.featureFlags,
172169
});
173170
setisLoadingPatientDetails(false);
174171
} catch (error) {

app/src/components/blocks/generic/patientVerifyPage/PatientVerifyPage.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,17 +402,17 @@ describe('handleSearch', () => {
402402
});
403403

404404
describe('Inactive Patient Handling', () => {
405-
it('returns error for inactive patient when user is GP Clinical', async () => {
405+
it('allows inactive patient when user is GP Clinical', async () => {
406406
const inactivePatient = buildPatientDetails({ active: false, deceased: false });
407407
mockGetPatientDetails.mockResolvedValue(inactivePatient);
408408

409409
const result = await handleSearch({ ...defaultArgs, userIsGPClinical: true } as any);
410410

411-
expect(result).toEqual([expect.any(String), 404, undefined]);
412-
expect(mockHandleSuccess).not.toHaveBeenCalled();
411+
expect(mockHandleSuccess).toHaveBeenCalledWith(inactivePatient);
412+
expect(result).toBeUndefined();
413413
});
414414

415-
it('returns error for inactive patient when user is GP Admin with disabled features', async () => {
415+
it('allows inactive patient when user is GP Admin with disabled features', async () => {
416416
const inactivePatient = buildPatientDetails({ active: false, deceased: false });
417417
mockGetPatientDetails.mockResolvedValue(inactivePatient);
418418

@@ -422,8 +422,8 @@ describe('handleSearch', () => {
422422
featureFlags: { uploadArfWorkflowEnabled: false, uploadLambdaEnabled: false },
423423
} as any);
424424

425-
expect(result).toEqual([expect.any(String), 404, undefined]);
426-
expect(mockHandleSuccess).not.toHaveBeenCalled();
425+
expect(mockHandleSuccess).toHaveBeenCalledWith(inactivePatient);
426+
expect(result).toBeUndefined();
427427
});
428428

429429
it('allows inactive patient for GP Admin with enabled features', async () => {

app/src/helpers/utils/handlePatientSearch.test.ts

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ describe('handleSearch', () => {
4343
handleSuccess,
4444
baseUrl,
4545
baseHeaders,
46-
userIsGPAdmin: false,
47-
userIsGPClinical: true,
4846
mockLocal: { patientIsActive: true, patientIsDeceased: false } as any,
49-
featureFlags: { uploadArfWorkflowEnabled: true, uploadLambdaEnabled: true } as any,
5047
});
5148

5249
expect(setSearchingState).toHaveBeenCalledWith(PATIENT_SEARCH_STATES.SEARCHING);
@@ -61,10 +58,7 @@ describe('handleSearch', () => {
6158
handleSuccess,
6259
baseUrl,
6360
baseHeaders,
64-
userIsGPAdmin: false,
65-
userIsGPClinical: true,
6661
mockLocal: { patientIsActive: true, patientIsDeceased: false } as any,
67-
featureFlags: { uploadArfWorkflowEnabled: true, uploadLambdaEnabled: true } as any,
6862
});
6963

7064
expect(mockGetPatientDetails).toHaveBeenCalledWith({
@@ -74,42 +68,34 @@ describe('handleSearch', () => {
7468
});
7569
});
7670

77-
it('returns SP_4003 for inactive non-deceased patient when user is clinical', async () => {
71+
it('allow inactive non-deceased patient when user is clinical', async () => {
7872
mockGetPatientDetails.mockResolvedValueOnce({ active: false, deceased: false } as any);
7973

80-
const result = await handleSearch({
74+
await handleSearch({
8175
nhsNumber: '1234567890',
8276
setSearchingState,
8377
handleSuccess,
8478
baseUrl,
8579
baseHeaders,
86-
userIsGPAdmin: false,
87-
userIsGPClinical: true,
8880
mockLocal: { patientIsActive: true, patientIsDeceased: false } as any,
89-
featureFlags: { uploadArfWorkflowEnabled: true, uploadLambdaEnabled: true } as any,
9081
});
9182

92-
expect(handleSuccess).not.toHaveBeenCalled();
93-
expect(result).toEqual([errorCodes['SP_4003'], 404, undefined]);
83+
expect(handleSuccess).toHaveBeenCalled();
9484
});
9585

96-
it('returns SP_4003 for inactive non-deceased patient when user is admin and either flag is disabled', async () => {
86+
it('allow inactive non-deceased patient when user is admin and either flag is disabled', async () => {
9787
mockGetPatientDetails.mockResolvedValueOnce({ active: false, deceased: false } as any);
9888

99-
const result = await handleSearch({
89+
await handleSearch({
10090
nhsNumber: '1234567890',
10191
setSearchingState,
10292
handleSuccess,
10393
baseUrl,
10494
baseHeaders,
105-
userIsGPAdmin: true,
106-
userIsGPClinical: false,
10795
mockLocal: { patientIsActive: true, patientIsDeceased: false } as any,
108-
featureFlags: { uploadArfWorkflowEnabled: false, uploadLambdaEnabled: true } as any,
10996
});
11097

111-
expect(handleSuccess).not.toHaveBeenCalled();
112-
expect(result).toEqual([errorCodes['SP_4003'], 404, undefined]);
98+
expect(handleSuccess).toHaveBeenCalled();
11399
});
114100

115101
it('allows inactive non-deceased patient when user is admin and both flags are enabled', async () => {
@@ -122,10 +108,7 @@ describe('handleSearch', () => {
122108
handleSuccess,
123109
baseUrl,
124110
baseHeaders,
125-
userIsGPAdmin: true,
126-
userIsGPClinical: false,
127111
mockLocal: { patientIsActive: true, patientIsDeceased: false } as any,
128-
featureFlags: { uploadArfWorkflowEnabled: true, uploadLambdaEnabled: true } as any,
129112
});
130113

131114
expect(result).toBeUndefined();
@@ -142,10 +125,7 @@ describe('handleSearch', () => {
142125
handleSuccess,
143126
baseUrl,
144127
baseHeaders,
145-
userIsGPAdmin: false,
146-
userIsGPClinical: true,
147128
mockLocal: { patientIsActive: false, patientIsDeceased: true } as any,
148-
featureFlags: { uploadArfWorkflowEnabled: true, uploadLambdaEnabled: true } as any,
149129
});
150130

151131
expect(result).toBeUndefined();
@@ -167,10 +147,7 @@ describe('handleSearch', () => {
167147
handleSuccess,
168148
baseUrl,
169149
baseHeaders,
170-
userIsGPAdmin: false,
171-
userIsGPClinical: true,
172150
mockLocal: { patientIsActive: true, patientIsDeceased: false } as any,
173-
featureFlags: { uploadArfWorkflowEnabled: true, uploadLambdaEnabled: true } as any,
174151
});
175152

176153
expect(result).toEqual(['Enter a valid patient NHS number.', 400, error]);
@@ -186,10 +163,7 @@ describe('handleSearch', () => {
186163
handleSuccess,
187164
baseUrl,
188165
baseHeaders,
189-
userIsGPAdmin: false,
190-
userIsGPClinical: true,
191166
mockLocal: { patientIsActive: true, patientIsDeceased: false } as any,
192-
featureFlags: { uploadArfWorkflowEnabled: true, uploadLambdaEnabled: true } as any,
193167
});
194168

195169
expect(result).toEqual([null, 403, error]);
@@ -205,10 +179,7 @@ describe('handleSearch', () => {
205179
handleSuccess,
206180
baseUrl,
207181
baseHeaders,
208-
userIsGPAdmin: false,
209-
userIsGPClinical: true,
210182
mockLocal: { patientIsActive: true, patientIsDeceased: false } as any,
211-
featureFlags: { uploadArfWorkflowEnabled: true, uploadLambdaEnabled: true } as any,
212183
});
213184

214185
expect(result).toEqual([errorCodes['SP_4003'], 404, error]);

app/src/helpers/utils/handlePatientSearch.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { AxiosError } from 'axios';
22
import { Dispatch, SetStateAction } from 'react';
33
import { LocalFlags } from '../../providers/configProvider/ConfigProvider';
44
import { AuthHeaders } from '../../types/blocks/authHeaders';
5-
import { FeatureFlags } from '../../types/generic/featureFlags';
65
import { PatientDetails } from '../../types/generic/patientDetails';
76
import { routes } from '../../types/generic/routes';
87
import getPatientDetails from '../requests/getPatientDetails';
@@ -24,10 +23,7 @@ export type HandleSearchArgs = {
2423
handleSuccess: (patientDetails: PatientDetails) => void;
2524
baseUrl: string;
2625
baseHeaders: AuthHeaders;
27-
userIsGPAdmin: boolean;
28-
userIsGPClinical: boolean;
2926
mockLocal: LocalFlags;
30-
featureFlags: FeatureFlags;
3127
};
3228

3329
type handleSearchReturnType = [
@@ -42,10 +38,7 @@ export const handleSearch = async ({
4238
handleSuccess,
4339
baseUrl,
4440
baseHeaders,
45-
userIsGPAdmin,
46-
userIsGPClinical,
4741
mockLocal,
48-
featureFlags,
4942
}: HandleSearchArgs): Promise<handleSearchReturnType | undefined> => {
5043
setSearchingState(PATIENT_SEARCH_STATES.SEARCHING);
5144

@@ -58,16 +51,6 @@ export const handleSearch = async ({
5851
baseHeaders,
5952
});
6053

61-
if (!patientDetails.active && !patientDetails.deceased) {
62-
if (
63-
userIsGPClinical ||
64-
(userIsGPAdmin &&
65-
(!featureFlags.uploadArfWorkflowEnabled || !featureFlags.uploadLambdaEnabled))
66-
) {
67-
return [errorCodes['SP_4003'], 404, undefined];
68-
}
69-
}
70-
7154
handleSuccess(patientDetails);
7255
} catch (e) {
7356
const error = e as AxiosError;

app/src/pages/patientSearchPage/PatientSearchPage.test.tsx

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -134,32 +134,6 @@ describe('PatientSearchPage', () => {
134134
).toHaveLength(2);
135135
});
136136

137-
it('returns an input error when user does not have access to patient data', async () => {
138-
const errorResponse = {
139-
response: {
140-
status: 404,
141-
message: '404 Not found.',
142-
data: {
143-
err_code: 'SP_4003',
144-
},
145-
},
146-
};
147-
148-
mockedAxios.get.mockImplementation(() => Promise.reject(errorResponse));
149-
150-
renderPatientSearchPage();
151-
await userEvent.type(
152-
screen.getByRole('textbox', { name: 'Enter NHS number' }),
153-
'0987654321',
154-
);
155-
await userEvent.click(screen.getByRole('button', { name: 'Search' }));
156-
expect(
157-
await screen.findAllByText(
158-
"You cannot access this patient's record because they are not registered at your practice. The patient's current practice can access this record if it's stored in this service.",
159-
),
160-
).toHaveLength(2);
161-
});
162-
163137
it('returns patient info when patient is inactive and deceased', async () => {
164138
const patientDetails = buildPatientDetails({
165139
active: false,
@@ -180,30 +154,6 @@ describe('PatientSearchPage', () => {
180154
});
181155
});
182156

183-
it('returns an error when patient is inactive and not deceased and user is clinical', async () => {
184-
const patientDetails = buildPatientDetails({
185-
active: false,
186-
deceased: false,
187-
});
188-
189-
mockedAxios.get.mockImplementation(() => Promise.resolve({ data: patientDetails }));
190-
191-
mockedUseRole.mockReturnValue(REPOSITORY_ROLE.GP_CLINICAL);
192-
193-
renderPatientSearchPage();
194-
await userEvent.type(
195-
screen.getByRole('textbox', { name: 'Enter NHS number' }),
196-
'9000000000',
197-
);
198-
await userEvent.click(screen.getByRole('button', { name: 'Search' }));
199-
200-
expect(
201-
await screen.findAllByText(
202-
"You cannot access this patient's record because they are not registered at your practice. The patient's current practice can access this record if it's stored in this service.",
203-
),
204-
).toHaveLength(2);
205-
});
206-
207157
it('returns a service error when service is down', async () => {
208158
const errorResponse = {
209159
response: {
@@ -343,26 +293,6 @@ describe('PatientSearchPage', () => {
343293
});
344294
});
345295

346-
it('display input error when patient is inactive and upload feature is disabled', async () => {
347-
const role = REPOSITORY_ROLE.GP_ADMIN;
348-
mockedUseRole.mockReturnValue(role);
349-
mockedAxios.get.mockImplementation(() =>
350-
Promise.resolve({ data: { ...buildPatientDetails(), active: false } }),
351-
);
352-
353-
renderPatientSearchPage();
354-
await userEvent.type(
355-
screen.getByRole('textbox', { name: 'Enter NHS number' }),
356-
'0987654321',
357-
);
358-
await userEvent.click(screen.getByRole('button', { name: 'Search' }));
359-
expect(
360-
await screen.findAllByText(
361-
"You cannot access this patient's record because they are not registered at your practice. The patient's current practice can access this record if it's stored in this service.",
362-
),
363-
).toHaveLength(2);
364-
});
365-
366296
it('navigates to home page when Go to home link is clicked', async () => {
367297
renderPatientSearchPage();
368298
await userEvent.click(screen.getByTestId('go-to-home-link'));

0 commit comments

Comments
 (0)