Skip to content

Commit df15512

Browse files
[PRMP-861] [WIP] Add types and request functions for document review (#940)
1 parent 05e8f98 commit df15512

File tree

4 files changed

+207
-0
lines changed

4 files changed

+207
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { describe, it, expect, vi, beforeEach, afterEach, Mocked } from 'vitest';
2+
import axios from 'axios';
3+
import { uploadDocumentForReview, getDocumentReviewStatus } from './documentReview';
4+
import { AuthHeaders } from '../../types/blocks/authHeaders';
5+
import { DOCUMENT_UPLOAD_STATE, UploadDocument } from '../../types/pages/UploadDocumentsPage/types';
6+
import { endpoints } from '../../types/generic/endpoints';
7+
import { DOCUMENT_TYPE } from '../utils/documentType';
8+
9+
vi.mock('axios');
10+
const mockedAxios = axios as Mocked<typeof axios>;
11+
(mockedAxios.get as any) = vi.fn();
12+
13+
describe('documentReview', () => {
14+
const mockAuthHeaders: AuthHeaders = {
15+
authorization: 'Bearer token',
16+
"Content-Type": 'string',
17+
};
18+
19+
const mockDocument: UploadDocument = {
20+
id: 'doc-123',
21+
versionId: 'v1',
22+
docType: DOCUMENT_TYPE.LLOYD_GEORGE,
23+
file: { name: 'test-document.pdf' } as File,
24+
state: DOCUMENT_UPLOAD_STATE.UPLOADING,
25+
attempts: 0,
26+
};
27+
28+
const mockArgs = {
29+
document: mockDocument,
30+
nhsNumber: '1234567890',
31+
baseUrl: 'https://api.example.com',
32+
baseHeaders: mockAuthHeaders,
33+
};
34+
35+
beforeEach(() => {
36+
vi.clearAllMocks();
37+
});
38+
39+
afterEach(() => {
40+
vi.restoreAllMocks();
41+
});
42+
43+
describe('uploadDocumentForReview', () => {
44+
it('should successfully upload document for review', async () => {
45+
const mockResponse = { data: { reviewId: 'review-123', status: 'pending' } };
46+
mockedAxios.post.mockResolvedValue(mockResponse);
47+
48+
const result = await uploadDocumentForReview(mockArgs);
49+
50+
expect(mockedAxios.post).toHaveBeenCalledWith(
51+
`${mockArgs.baseUrl}${endpoints.DOCUMENT_REVIEW}`,
52+
JSON.stringify({
53+
nhsNumber: mockArgs.nhsNumber,
54+
snomedCode: mockArgs.document.docType,
55+
documents: [mockArgs.document.file.name],
56+
}),
57+
{
58+
headers: mockAuthHeaders,
59+
params: {
60+
patientId: mockArgs.nhsNumber,
61+
},
62+
}
63+
);
64+
expect(result).toEqual(mockResponse.data);
65+
});
66+
67+
it('should throw error when request fails', async () => {
68+
const mockError = new Error('Network error');
69+
mockedAxios.post.mockRejectedValue(mockError);
70+
71+
await expect(uploadDocumentForReview(mockArgs)).rejects.toThrow('Network error');
72+
});
73+
});
74+
75+
describe('getDocumentReviewStatus', () => {
76+
it('should successfully get document review status', async () => {
77+
const mockResponse = { data: { status: 'completed', result: 'approved' } };
78+
mockedAxios.get.mockResolvedValue(mockResponse);
79+
80+
const result = await getDocumentReviewStatus(mockArgs);
81+
82+
expect(mockedAxios.get).toHaveBeenCalledWith(
83+
`${mockArgs.baseUrl}${endpoints.DOCUMENT_REVIEW}/${mockArgs.document.id}/${mockArgs.document.versionId}/Status`,
84+
{
85+
headers: mockAuthHeaders,
86+
params: {
87+
patientId: mockArgs.nhsNumber,
88+
},
89+
}
90+
);
91+
expect(result).toEqual(mockResponse.data);
92+
});
93+
94+
it('should throw error when status request fails', async () => {
95+
const mockError = new Error('Status fetch failed');
96+
mockedAxios.get.mockRejectedValue(mockError);
97+
98+
await expect(getDocumentReviewStatus(mockArgs)).rejects.toThrow('Status fetch failed');
99+
});
100+
});
101+
});
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { AuthHeaders } from '../../types/blocks/authHeaders';
2+
import { endpoints } from '../../types/generic/endpoints';
3+
import { UploadDocument } from '../../types/pages/UploadDocumentsPage/types';
4+
5+
import axios, { AxiosError } from 'axios';
6+
import { DocumentReviewDto, DocumentReviewStatusDto } from '../../types/blocks/documentReview';
7+
8+
type DocumentReviewArgs = {
9+
document: UploadDocument;
10+
nhsNumber: string;
11+
baseUrl: string;
12+
baseHeaders: AuthHeaders;
13+
};
14+
15+
export const uploadDocumentForReview = async ({
16+
nhsNumber,
17+
document,
18+
baseUrl,
19+
baseHeaders,
20+
}: DocumentReviewArgs): Promise<DocumentReviewDto> => {
21+
const requestBody = {
22+
nhsNumber,
23+
snomedCode: document.docType,
24+
documents: [document.file.name],
25+
};
26+
27+
const gatewayUrl = baseUrl + endpoints.DOCUMENT_REVIEW;
28+
29+
try {
30+
const { data } = await axios.post<DocumentReviewDto>(gatewayUrl, JSON.stringify(requestBody), {
31+
headers: {
32+
...baseHeaders,
33+
},
34+
params: {
35+
patientId: nhsNumber,
36+
},
37+
});
38+
39+
return data;
40+
} catch (e) {
41+
const error = e as AxiosError;
42+
throw error;
43+
}
44+
};
45+
46+
export const getDocumentReviewStatus = async ({
47+
document,
48+
baseUrl,
49+
baseHeaders,
50+
nhsNumber,
51+
}: DocumentReviewArgs): Promise<DocumentReviewStatusDto> => {
52+
const documentStatusUrl = `${baseUrl}${endpoints.DOCUMENT_REVIEW}/${document.id}/${document.versionId}/Status`;
53+
54+
try {
55+
const { data } = await axios.get<DocumentReviewStatusDto>(documentStatusUrl, {
56+
headers: {
57+
...baseHeaders,
58+
},
59+
params: {
60+
patientId: nhsNumber,
61+
},
62+
});
63+
64+
return data;
65+
} catch (e) {
66+
const error = e as AxiosError;
67+
throw error;
68+
}
69+
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { DOCUMENT_TYPE } from '../../helpers/utils/documentType';
2+
3+
export type DocumentReviewDto = {
4+
id: string;
5+
uploadDate: number;
6+
files: DocumentReviewFile[];
7+
documentSnomedCodeType: DOCUMENT_TYPE;
8+
version: string;
9+
};
10+
11+
type DocumentReviewFile = {
12+
fileName: string;
13+
presignedUrl: string;
14+
};
15+
16+
export type DocumentReviewStatusDto = {
17+
id: string;
18+
status: string;
19+
version: string;
20+
reviewReason: string;
21+
};
22+
23+
export enum DocumentReviewStatus {
24+
PENDING_REVIEW = "PENDING_REVIEW",
25+
APPROVED = "APPROVED",
26+
APPROVED_PENDING_DOCUMENTS = "APPROVED_PENDING_DOCUMENTS",
27+
REJECTED = "REJECTED",
28+
AWAITING_DOCUMENTS = "AWAITING_DOCUMENTS",
29+
REJECTED_DUPLICATE = "REJECTED_DUPLICATE",
30+
REASSIGNED = "REASSIGNED",
31+
REASSIGNED_PATIENT_UNKNOWN = "REASSIGNED_PATIENT_UNKNOWN",
32+
NEVER_REVIEWED = "NEVER_REVIEWED",
33+
REVIEW_PENDING_UPLOAD = "REVIEW_PENDING_UPLOAD",
34+
VIRUS_SCAN_FAILED = "VIRUS_SCAN_FAILED",
35+
}

app/src/types/generic/endpoints.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ export enum endpoints {
1919

2020
ODS_REPORT = '/OdsReport',
2121
MOCK_LOGIN = 'Auth/MockLogin',
22+
23+
DOCUMENT_REVIEW = '/DocumentReview',
2224
}

0 commit comments

Comments
 (0)