require('dotenv').config(); const axios = require('axios'); const { getBusToken } = require('../../utils/busAuth'); const { postPatient, getPatientById, searchPatient, matchPatient } = require('../../services/patient'); jest.mock('axios'); const BUS_URL = process.env.BUS_URL; const MPI_URL = process.env.MPI_URL || process.env.BUS_URL; const BUS_JWT_SECRET = process.env.BUS_JWT_SECRET; const BUS_ISSUER = process.env.BUS_ISSUER; const BUS_SCOPE = process.env.MPI_SCOPE; const mockRequest = { get: jest.fn(), post: jest.fn() }; beforeEach(() => { jest.clearAllMocks(); axios.create.mockReturnValue(mockRequest); }); async function acquireToken() { axios.post.mockResolvedValueOnce({ data: { accessToken: 'acquired-token' } }); return getBusToken(BUS_URL, BUS_JWT_SECRET, BUS_ISSUER, BUS_SCOPE); } describe('postPatient', () => { it('POSTs the patient to /fhir/Patient and returns response data', async () => { const token = await acquireToken(); const patient = { resourceType: 'Patient', id: '1' }; const responseData = { resourceType: 'Patient', id: '1', meta: {} }; mockRequest.post.mockResolvedValue({ data: responseData }); const result = await postPatient(MPI_URL, token, patient); expect(axios.create).toHaveBeenCalledWith({ baseURL: MPI_URL, headers: { 'Content-Type': 'application/fhir+json', 'Authorization': `Bearer ${token}`, }, }); expect(mockRequest.post).toHaveBeenCalledWith('/fhir/Patient', patient); expect(result).toEqual(responseData); }); }); describe('getPatientById', () => { it('GETs /fhir/Patient/:id and returns response data', async () => { const token = await acquireToken(); const responseData = { resourceType: 'Patient', id: '42' }; mockRequest.get.mockResolvedValue({ data: responseData }); const result = await getPatientById(MPI_URL, token, '42'); expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient/42'); expect(result).toEqual(responseData); }); }); describe('searchPatient', () => { it('GETs /fhir/Patient with no params when criteria is empty', async () => { const token = await acquireToken(); const bundle = { resourceType: 'Bundle', entry: [] }; mockRequest.get.mockResolvedValue({ data: bundle }); const result = await searchPatient(MPI_URL, token, {}); expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient', { params: {} }); expect(result).toEqual(bundle); }); it('maps criteria fields to query params', async () => { const token = await acquireToken(); mockRequest.get.mockResolvedValue({ data: {} }); await searchPatient(MPI_URL, token, { name: 'Juan', family: 'Perez', birthdate: '1983-04-17', gender: 'male', phone: '1141233100', }); expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient', { params: { name: 'Juan', family: 'Perez', birthdate: '1983-04-17', gender: 'male', phone: '1141233100', }, }); }); it('combines identifierSystem and identifierValue into identifier param', async () => { const token = await acquireToken(); mockRequest.get.mockResolvedValue({ data: {} }); await searchPatient(MPI_URL, token, { identifierSystem: 'http://www.renaper.gob.ar/dni', identifierValue: '30945027', }); expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient', { params: { identifier: 'http://www.renaper.gob.ar/dni|30945027' }, }); }); it('uses identifierValue alone when identifierSystem is not provided', async () => { const token = await acquireToken(); mockRequest.get.mockResolvedValue({ data: {} }); await searchPatient(MPI_URL, token, { identifierValue: '30945027' }); expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient', { params: { identifier: '30945027' }, }); }); }); describe('matchPatient', () => { it('POSTs a Parameters resource to /fhir/Patient/$match', async () => { const token = await acquireToken(); const patient = { resourceType: 'Patient', id: '1' }; const bundle = { resourceType: 'Bundle', entry: [] }; mockRequest.post.mockResolvedValue({ data: bundle }); const result = await matchPatient(MPI_URL, token, patient); expect(mockRequest.post).toHaveBeenCalledWith('/fhir/Patient/$match', { resourceType: 'Parameters', parameter: [{ name: 'resource', resource: patient }], }); expect(result).toEqual(bundle); }); it('includes count parameter when provided', async () => { const token = await acquireToken(); const patient = { resourceType: 'Patient' }; mockRequest.post.mockResolvedValue({ data: {} }); await matchPatient(MPI_URL, token, patient, 3); expect(mockRequest.post).toHaveBeenCalledWith('/fhir/Patient/$match', { resourceType: 'Parameters', parameter: [ { name: 'resource', resource: patient }, { name: 'count', valueInteger: 3 }, ], }); }); it('does not include count parameter when not provided', async () => { const token = await acquireToken(); const patient = { resourceType: 'Patient' }; mockRequest.post.mockResolvedValue({ data: {} }); await matchPatient(MPI_URL, token, patient); const call = mockRequest.post.mock.calls[0]; const parameters = call[1]; expect(parameters.parameter).toHaveLength(1); }); });