diff --git a/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.test.tsx b/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.test.tsx index 0610078059..8b6eede4e6 100644 --- a/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.test.tsx +++ b/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.test.tsx @@ -15,6 +15,7 @@ import { UploadDocumentType, DOCUMENT_UPLOAD_STATE, } from '../../../../types/pages/UploadDocumentsPage/types'; +import { NHS_NUMBER_UNKNOWN } from '../../../../helpers/constants/numbers'; const mockNavigate = vi.fn(); const mockSetPatientDetails = vi.fn(); @@ -25,7 +26,7 @@ vi.mock('react-router-dom', async (): Promise => { const actual = await vi.importActual('react-router-dom'); return { ...actual, - useNavigate: (): Mock => mockNavigate, + useNavigate: () => mockNavigate, useParams: (): { reviewId: string } => ({ reviewId: 'test-review-123' }), }; }); @@ -105,8 +106,8 @@ const renderComponent = (reviewData?: ReviewDetails, reviewSnoMed?: DOCUMENT_TYP ); }; -describe('ReviewDetailsPage', () => { - const testReviewSnoMed: DOCUMENT_TYPE = '16521000000101' as DOCUMENT_TYPE; +describe('ReviewDetailsStage', () => { + const testReviewSnomed: DOCUMENT_TYPE = '16521000000101' as DOCUMENT_TYPE; const mockPatientDetails = buildPatientDetails({ givenName: ['Lillie'], familyName: 'Dae', @@ -117,9 +118,9 @@ describe('ReviewDetailsPage', () => { const mockReviewData = new ReviewDetails( 'test-review-123', - testReviewSnoMed, + testReviewSnomed, '2023-01-01T00:00:00Z', - 'test.uploader@example.com', + 'M85143', '2023-01-01T00:00:00Z', 'Test review reason', '1', @@ -652,6 +653,43 @@ describe('ReviewDetailsPage', () => { }); }); + describe('Navigation - Unknown NHS Number', () => { + it('navigates to patient search page when NHS number is unknown', async () => { + const mockLoadReviewData = vi.fn().mockResolvedValue(undefined); + + const unknownNhsNumberReviewData = new ReviewDetails( + 'test-review-123', + testReviewSnomed, + '2023-01-01T00:00:00Z', + 'M85143', + '2023-01-01T00:00:00Z', + 'Test review reason', + '1', + NHS_NUMBER_UNKNOWN, + ); + + render( + , + ); + + await waitFor( + () => { + expect(mockNavigate).toHaveBeenCalledWith( + '/admin/reviews/test-review-123/search-patient', + undefined, + ); + }, + { timeout: 2000 }, + ); + }); + }); + describe('Form submission with react-hook-form', () => { beforeEach(() => { vi.spyOn(isLocalModule, 'isLocal', 'get').mockReturnValue(true); @@ -1118,7 +1156,7 @@ describe('ReviewDetailsPage', () => { vi.spyOn(isLocalModule, 'isLocal', 'get').mockReturnValue(true); const reviewWithReason = new ReviewDetails( 'test-review-123', - testReviewSnoMed, + testReviewSnomed, '2023-01-01T00:00:00Z', 'test.uploader@example.com', '2023-01-01T00:00:00Z', @@ -1140,7 +1178,7 @@ describe('ReviewDetailsPage', () => { vi.spyOn(isLocalModule, 'isLocal', 'get').mockReturnValue(true); const reviewWithNullFiles = new ReviewDetails( 'test-review-123', - testReviewSnoMed, + testReviewSnomed, '2023-01-01T00:00:00Z', 'test.uploader@example.com', '2023-01-01T00:00:00Z', diff --git a/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx b/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx index 78001edb14..61c232acc1 100644 --- a/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx +++ b/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx @@ -34,6 +34,7 @@ import { AxiosError } from 'axios'; import { errorToParams } from '../../../../helpers/utils/errorToParams'; import waitForSeconds from '../../../../helpers/utils/waitForSeconds'; import DocumentUploadLloydGeorgePreview from '../../_documentUpload/documentUploadLloydGeorgePreview/DocumentUploadLloydGeorgePreview'; +import { NHS_NUMBER_UNKNOWN } from '../../../../helpers/constants/numbers'; export type ReviewsDetailsStageProps = { reviewData: ReviewDetails; @@ -146,10 +147,13 @@ const ReviewsDetailsStage = ({ setisLoadingPatientDetails(false); return; } + if (reviewData.nhsNumber === NHS_NUMBER_UNKNOWN) { + setisLoadingPatientDetails(false); + return; + } const getPatientDetails = async (): Promise => { if (!isFetchingReviewDetailsRef.current) { isFetchingReviewDetailsRef.current = true; - await handlePatientSearch({ nhsNumber: reviewData.nhsNumber, setSearchingState: () => {}, @@ -178,6 +182,14 @@ const ReviewsDetailsStage = ({ while (retryCount < maxRetries) { try { await loadReviewData(); + if (reviewData.nhsNumber === NHS_NUMBER_UNKNOWN) { + navigateUrlParam( + routeChildren.ADMIN_REVIEW_SEARCH_PATIENT, + { reviewId: reviewId! }, + navigate, + ); + return; + } break; } catch (e) { retryCount += 1; diff --git a/app/src/components/blocks/_admin/reviewsPage/ReviewsPage.tsx b/app/src/components/blocks/_admin/reviewsPage/ReviewsPage.tsx index 3d6f9bddbd..d1e669750b 100644 --- a/app/src/components/blocks/_admin/reviewsPage/ReviewsPage.tsx +++ b/app/src/components/blocks/_admin/reviewsPage/ReviewsPage.tsx @@ -22,6 +22,7 @@ import SpinnerV2 from '../../../generic/spinnerV2/SpinnerV2'; import { REPORT_TYPE } from '../../../../types/generic/reports'; import { AxiosError } from 'axios'; import { errorToParams } from '../../../../helpers/utils/errorToParams'; +import { NHS_NUMBER_UNKNOWN } from '../../../../helpers/constants/numbers'; export type ReviewsPageProps = { setReviewData: Dispatch>; @@ -64,7 +65,7 @@ const ReviewTableRows = ({ return ( - {review.nhsNumber === '0000000000' + {review.nhsNumber === NHS_NUMBER_UNKNOWN ? 'N/A' : formatNhsNumber(review.nhsNumber)} diff --git a/app/src/helpers/constants/numbers.ts b/app/src/helpers/constants/numbers.ts new file mode 100644 index 0000000000..98ad51a95d --- /dev/null +++ b/app/src/helpers/constants/numbers.ts @@ -0,0 +1 @@ +export const NHS_NUMBER_UNKNOWN = '0000000000'; diff --git a/app/src/helpers/requests/getReviews.test.ts b/app/src/helpers/requests/getReviews.test.ts index b63cf94709..0ef8d30d2d 100644 --- a/app/src/helpers/requests/getReviews.test.ts +++ b/app/src/helpers/requests/getReviews.test.ts @@ -1534,7 +1534,7 @@ describe('getReviews.ts', () => { vi.clearAllMocks(); }); - test('does not fetch existing document when doc type is not singleDocumentOnly', async () => { + test('does not fetch existing document when doc type is not singleDocumentOnly and NHS number is unknown', async () => { const reviewData = new ReviewDetails( 'review-2', DOCUMENT_TYPE.EHR, @@ -1543,7 +1543,7 @@ describe('getReviews.ts', () => { '2024-01-01', 'reason', '7', - '9000000001', + '0000000000', // NHS_NUMBER_UNKNOWN ); const reviewDto: GetDocumentReviewDto = { @@ -1559,10 +1559,56 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-2/7`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-2/7`)) { + return Promise.resolve({ status: 200, data: reviewDto }); + } + if (url === 'https://example.com/ehr.pdf') { + return Promise.resolve({ status: 200, data: new Blob(['file']) }); + } + return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); + }); + + const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); + + expect(result.aborted).toBe(false); + expect(result.hasExistingRecordInStorage).toBe(false); + expect(mockedGetDocumentSearchResults).not.toHaveBeenCalled(); + expect(mockedGetDocument).not.toHaveBeenCalled(); + + expect(result.existingUploadDocuments).toHaveLength(0); + expect(result.additionalFiles).toHaveLength(1); + expect(result.uploadDocuments).toHaveLength(1); + expect(result.uploadDocuments[0].type).toBe('REVIEW'); + expect(result.uploadDocuments[0].file.name).toBe('ehr.pdf'); + expect(result.uploadDocuments[0].file.type).toBe('application/pdf'); + }); + + test('does not fetch existing document when doc type is singleDocumentOnly and NHS number is unknown', async () => { + const reviewData = new ReviewDetails( + 'review-2', + DOCUMENT_TYPE.LLOYD_GEORGE, + '2024-01-01', + 'uploader', + '2024-01-01', + 'reason', + '7', + '0000000000', // NHS_NUMBER_UNKNOWN + ); + + const reviewDto: GetDocumentReviewDto = { + id: 'review-2', + uploadDate: '2024-01-01T10:00:00Z', + documentSnomedCodeType: DOCUMENT_TYPE.LLOYD_GEORGE, + files: [ + { + fileName: 'ehr.pdf', + presignedUrl: 'https://example.com/ehr.pdf', + }, + ], + }; + + mockedAxios.get.mockImplementation((url) => { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-2/7`)) { return Promise.resolve({ status: 200, data: reviewDto }); } if (url === 'https://example.com/ehr.pdf') { @@ -1629,10 +1675,7 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-3/2`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-3/2`)) { return Promise.resolve({ status: 200, data: reviewDto }); } if (url === 'https://example.com/existing.pdf') { @@ -1684,7 +1727,13 @@ describe('getReviews.ts', () => { ], } as GetDocumentReviewDto; - mockedAxios.get.mockResolvedValueOnce({ status: 200, data: reviewDto }); + mockedGetDocumentSearchResults.mockResolvedValue([]); + mockedAxios.get.mockImplementation((url) => { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-4/1`)) { + return Promise.resolve({ status: 200, data: reviewDto }); + } + return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); + }); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); @@ -1726,18 +1775,16 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-5/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-5/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); }); + mockedGetDocumentSearchResults.mockResolvedValue([]); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); expect(result.aborted).toBe(false); @@ -1781,14 +1828,12 @@ describe('getReviews.ts', () => { ], }; + mockedGetDocumentSearchResults.mockResolvedValue([]); mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-6/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-6/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); @@ -1797,12 +1842,9 @@ describe('getReviews.ts', () => { const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); expect(result.uploadDocuments).toHaveLength(3); - // Verify files are created with correct names and extensions expect(result.uploadDocuments[0].file.name).toBe('document.pdf'); expect(result.uploadDocuments[1].file.name).toBe('image.jpg'); expect(result.uploadDocuments[2].file.name).toBe('archive.zip'); - // Note: File types are set by fileExtensionToContentType helper - // The blob type doesn't affect the File type since it's explicitly set in the File constructor }); test('handles files without extension', async () => { @@ -1830,18 +1872,16 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-7/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-7/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); }); + mockedGetDocumentSearchResults.mockResolvedValue([]); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); expect(result.uploadDocuments).toHaveLength(1); @@ -1875,18 +1915,16 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-8/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-8/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); }); + mockedGetDocumentSearchResults.mockResolvedValue([]); await getReviewData({ baseUrl, baseHeaders, reviewData }); expect(addReviewFilesSpy).toHaveBeenCalledWith(reviewDto); @@ -1905,6 +1943,7 @@ describe('getReviews.ts', () => { '9000000001', ); + mockedGetDocumentSearchResults.mockResolvedValue([]); mockedAxios.get.mockRejectedValue(new Error('Network error')); await expect(getReviewData({ baseUrl, baseHeaders, reviewData })).rejects.toThrow( @@ -1936,6 +1975,7 @@ describe('getReviews.ts', () => { ], }; + mockedGetDocumentSearchResults.mockResolvedValue([]); mockedAxios.get.mockImplementation((url) => { if (url.includes('/document-review/')) { return Promise.resolve({ status: 200, data: reviewDto }); @@ -2024,18 +2064,16 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-13/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-13/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); }); + mockedGetDocumentSearchResults.mockResolvedValue([]); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); const doc = result.uploadDocuments[0]; @@ -2095,13 +2133,10 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-14/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-14/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); @@ -2164,13 +2199,10 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-15/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-15/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); @@ -2213,13 +2245,10 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-16/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-16/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); @@ -2278,13 +2307,10 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-17/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-17/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); @@ -2345,13 +2371,10 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-18/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-18/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); @@ -2395,18 +2418,16 @@ describe('getReviews.ts', () => { }; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-19/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-19/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); }); + mockedGetDocumentSearchResults.mockResolvedValue([]); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); const ids = result.uploadDocuments.map((doc) => doc.id); @@ -2435,6 +2456,7 @@ describe('getReviews.ts', () => { files: [], }; + mockedGetDocumentSearchResults.mockResolvedValue([]); mockedAxios.get.mockResolvedValue({ status: 200, data: reviewDto }); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); @@ -2469,6 +2491,7 @@ describe('getReviews.ts', () => { ], } as unknown as GetDocumentReviewDto; + mockedGetDocumentSearchResults.mockResolvedValue([]); mockedAxios.get.mockResolvedValue({ status: 200, data: reviewDto }); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); @@ -2514,25 +2537,21 @@ describe('getReviews.ts', () => { let blobFetchCount = 0; mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-22/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-22/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - // Only count blob fetches (presigned URLs) - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + + if (url.startsWith('https://example.com/')) { blobFetchCount += 1; return Promise.resolve({ status: 200, data: new Blob(['file']) }); } return Promise.reject(new Error(`Unexpected url: ${String(url)}`)); }); + mockedGetDocumentSearchResults.mockResolvedValue([]); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); expect(result.aborted).toBe(true); - // The first file (file1.pdf) has a valid URL and gets fetched before - // the second file's empty URL is encountered, causing the abort expect(blobFetchCount).toBe(1); }); @@ -2563,23 +2582,20 @@ describe('getReviews.ts', () => { const mockBlob = new Blob(['test content'], { type: 'application/pdf' }); mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-23/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-23/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: mockBlob }); } return Promise.reject(new Error('Unexpected URL')); }); + mockedGetDocumentSearchResults.mockResolvedValue([]); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); expect(result.aborted).toBe(false); expect(result.uploadDocuments).toHaveLength(1); - // Verify getReviewById was called with empty string fallback expect(mockedAxios.get).toHaveBeenCalledWith( expect.stringContaining('patientId='), expect.anything(), @@ -2604,7 +2620,7 @@ describe('getReviews.ts', () => { documentSnomedCodeType: DOCUMENT_TYPE.EHR, files: [ { - fileName: '', // empty filename - split('.').pop() returns undefined + fileName: '', presignedUrl: 'https://example.com/emptyname', }, ], @@ -2613,23 +2629,20 @@ describe('getReviews.ts', () => { const mockBlob = new Blob(['test content'], { type: 'application/octet-stream' }); mockedAxios.get.mockImplementation((url) => { - if ( - typeof url === 'string' && - url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-24/1`) - ) { + if (url.startsWith(`${baseUrl}${endpoints.DOCUMENT_REVIEW}/review-24/1`)) { return Promise.resolve({ status: 200, data: reviewDto }); } - if (typeof url === 'string' && url.startsWith('https://example.com/')) { + if (url.startsWith('https://example.com/')) { return Promise.resolve({ status: 200, data: mockBlob }); } return Promise.reject(new Error('Unexpected URL')); }); + mockedGetDocumentSearchResults.mockResolvedValue([]); const result = await getReviewData({ baseUrl, baseHeaders, reviewData }); expect(result.aborted).toBe(false); expect(result.uploadDocuments).toHaveLength(1); - // File should be created with empty string as fallback for extension expect(result.uploadDocuments[0].file.name).toBe(''); }); }); diff --git a/app/src/helpers/requests/getReviews.ts b/app/src/helpers/requests/getReviews.ts index f65ab854ea..f8adfdbb4a 100644 --- a/app/src/helpers/requests/getReviews.ts +++ b/app/src/helpers/requests/getReviews.ts @@ -14,6 +14,7 @@ import getDocumentSearchResults, { DocumentSearchResultsArgs } from './getDocume import getDocument from './getDocument'; import { fileExtensionToContentType } from '../utils/fileExtensionToContentType'; import { AuthHeaders } from '../../types/blocks/authHeaders'; +import { NHS_NUMBER_UNKNOWN } from '../constants/numbers'; const getReviews = async ( baseUrl: string, @@ -135,7 +136,7 @@ export const getReviewData = async ({ let hasExistingRecordInStorage = false; - if (docTypeConfig.singleDocumentOnly) { + if (docTypeConfig.singleDocumentOnly && reviewData.nhsNumber !== NHS_NUMBER_UNKNOWN) { const params: DocumentSearchResultsArgs = { nhsNumber: reviewData.nhsNumber, baseUrl, diff --git a/app/src/pages/adminRoutesPage/AdminRoutesPage.tsx b/app/src/pages/adminRoutesPage/AdminRoutesPage.tsx index e24239bf63..49f04efce2 100644 --- a/app/src/pages/adminRoutesPage/AdminRoutesPage.tsx +++ b/app/src/pages/adminRoutesPage/AdminRoutesPage.tsx @@ -16,7 +16,6 @@ import ReviewDetailsPatientSearchStage from '../../components/blocks/_admin/revi import { ReviewsPage } from '../../components/blocks/_admin/reviewsPage/ReviewsPage'; import PatientVerifyPage from '../../components/blocks/generic/patientVerifyPage/PatientVerifyPage'; import useConfig from '../../helpers/hooks/useConfig'; -import usePatient from '../../helpers/hooks/usePatient'; import { getLastURLPath } from '../../helpers/utils/urlManipulations'; import { routeChildren, routes } from '../../types/generic/routes'; import { AdminPage } from '../adminPage/AdminPage'; @@ -40,7 +39,6 @@ export enum CompleteState { const AdminRoutesPage = (): JSX.Element => { const config = useConfig(); const navigate = useNavigate(); - const patientDetails = usePatient(); const baseUrl = useBaseAPIUrl(); const baseHeaders = useBaseAPIHeaders(); const [hasExistingRecordInStorage, setHasExistingRecordInStorage] = useState(false); @@ -66,17 +64,7 @@ const AdminRoutesPage = (): JSX.Element => { } const patientVerifyOnSubmit = (setInputError: Dispatch>): void => { - if (patientDetails?.deceased) { - navigate(routeChildren.PATIENT_ACCESS_AUDIT_DECEASED); - return; - } - - if (patientDetails?.active) { - navigate(routeChildren.ADMIN_REVIEW_COMPLETE_PATIENT_MATCH); - return; - } - - navigate(routeChildren.ADMIN_REVIEW_SEARCH_PATIENT); + navigate(routeChildren.ADMIN_REVIEW_COMPLETE_PATIENT_MATCH); }; const loadData = async (): Promise => {