Actualizados los tests de bus-gateway!

This commit is contained in:
Alejandro Gomez Auad 2026-04-30 21:18:12 +00:00
parent ca4db597cc
commit b1cf91d992
5 changed files with 100 additions and 163 deletions

View File

@ -20,5 +20,9 @@
},
"devDependencies": {
"jest": "^30.3.0"
},
"jest": {
"testEnvironment": "node",
"setupFiles": ["./tests/setup.js"]
}
}

View File

@ -3,16 +3,14 @@ const axios = require('axios');
const { getBusToken } = require('../../utils/busAuth');
const {
createDocumentReference,
postDocumentReference,
searchDocumentReferenceBySubject,
searchDocumentReferenceByPatient,
findDocumentReferenceBySubject,
findDocumentReferenceByPatient,
searchDocumentReference,
} = require('../../services/documentReference');
jest.mock('axios');
const BUS_URL = process.env.BUS_URL;
const REGISTRY_URL = process.env.DOCUMENT_REGISTRY_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.DOCUMENT_REGISTRY_SCOPE;
@ -29,128 +27,66 @@ async function acquireToken() {
return getBusToken(BUS_URL, BUS_JWT_SECRET, BUS_ISSUER, BUS_SCOPE);
}
const CUSTODIAN_ID = 'efector-001';
const BUNDLE_URL = 'http://hapi-fhir-host:8080/fhir/Bundle/abc123';
// Internal URL used by the document registry (replaced by maskPrivateURL)
const INTERNAL_REGISTRY_BASE = 'https://federador.qa-bus-interoperabilidad.svc.cluster.local:8080/fhir/DocumentReference';
const IPS_BUNDLE = {
resourceType: 'Bundle',
id: 'bundle-001',
entry: [
{
resource: {
resourceType: 'Patient',
identifier: [
{ system: 'https://federador.msal.gob.ar/patient-id', value: '5037097' },
],
},
},
],
const DOCUMENT_REFERENCE = {
resourceType: 'DocumentReference',
status: 'current',
subject: {
identifier: { system: 'https://federador.msal.gob.ar/patient-id', value: '5037097' },
},
};
describe('createDocumentReference', () => {
it('builds a DocumentReference from IPS bundle using the first patient identifier', () => {
const dr = createDocumentReference(IPS_BUNDLE, CUSTODIAN_ID, BUNDLE_URL);
expect(dr.resourceType).toBe('DocumentReference');
expect(dr.status).toBe('current');
expect(dr.type.coding[0].code).toBe('60591-5');
expect(dr.subject.identifier).toEqual({
system: 'https://federador.msal.gob.ar/patient-id',
value: '5037097',
});
expect(dr.custodian.identifier).toEqual({
system: 'https://federador.msal.gob.ar/uri',
value: CUSTODIAN_ID,
});
expect(dr.content[0].attachment.url).toBe(BUNDLE_URL);
});
it('uses subjectIdentifier when provided instead of patient identifier', () => {
const subjectIdentifier = { system: 'http://www.renaper.gob.ar/dni', value: '30945027' };
const dr = createDocumentReference(IPS_BUNDLE, CUSTODIAN_ID, BUNDLE_URL, subjectIdentifier);
expect(dr.subject.identifier).toEqual(subjectIdentifier);
});
it('falls back to Bundle/{id} when bundleUrl is not provided', () => {
const dr = createDocumentReference(IPS_BUNDLE, CUSTODIAN_ID);
expect(dr.content[0].attachment.url).toBe(`Bundle/${IPS_BUNDLE.id}`);
});
it('throws when the bundle has no Patient entry', () => {
const bundleWithoutPatient = { ...IPS_BUNDLE, entry: [] };
expect(() => createDocumentReference(bundleWithoutPatient, CUSTODIAN_ID)).toThrow(
'IPS Bundle does not contain a Patient resource'
);
});
it('throws when the patient has no identifier', () => {
const bundleNoIdentifier = {
...IPS_BUNDLE,
entry: [{ resource: { resourceType: 'Patient', identifier: [] } }],
};
expect(() => createDocumentReference(bundleNoIdentifier, CUSTODIAN_ID)).toThrow(
'Patient resource has no identifier'
);
});
});
describe('postDocumentReference', () => {
it('POSTs a DocumentReference to /fhir/DocumentReference and returns response data', async () => {
it('POSTs a DocumentReference to the registry and returns the created resource', async () => {
const token = await acquireToken();
const responseData = { resourceType: 'DocumentReference', id: 'dr-001' };
mockRequest.post.mockResolvedValue({ data: responseData });
const result = await postDocumentReference(REGISTRY_URL, token, IPS_BUNDLE, CUSTODIAN_ID, BUNDLE_URL);
expect(axios.create).toHaveBeenCalledWith({
baseURL: REGISTRY_URL,
headers: {
'Content-Type': 'application/fhir+json',
'Authorization': `Bearer ${token}`,
},
mockRequest.post.mockResolvedValue({
data: {},
headers: { location: `${INTERNAL_REGISTRY_BASE}/dr-001` },
});
expect(mockRequest.post).toHaveBeenCalledWith(
'/fhir/DocumentReference',
expect.objectContaining({ resourceType: 'DocumentReference' })
);
mockRequest.get.mockResolvedValue({ data: responseData });
const result = await createDocumentReference(token, DOCUMENT_REFERENCE);
expect(mockRequest.post).toHaveBeenCalledWith(expect.anything(), DOCUMENT_REFERENCE);
expect(result).toEqual(responseData);
});
});
describe('searchDocumentReferenceBySubject', () => {
describe('findDocumentReferenceBySubject', () => {
it('GETs /fhir/DocumentReference with subject param as system|value', async () => {
const token = await acquireToken();
const bundle = { resourceType: 'Bundle', entry: [] };
mockRequest.get.mockResolvedValue({ data: bundle });
const result = await searchDocumentReferenceBySubject(
REGISTRY_URL, token,
const result = await findDocumentReferenceBySubject(
token,
'https://federador.msal.gob.ar/patient-id',
'5037097'
);
expect(mockRequest.get).toHaveBeenCalledWith('/fhir/DocumentReference', {
params: { subject: 'https://federador.msal.gob.ar/patient-id|5037097' },
});
expect(mockRequest.get).toHaveBeenCalledWith(
expect.anything(),
{ params: { subject: 'https://federador.msal.gob.ar/patient-id|5037097' } }
);
expect(result).toEqual(bundle);
});
});
describe('searchDocumentReferenceByPatient', () => {
it('GETs /fhir/DocumentReference with patient param', async () => {
describe('findDocumentReferenceByPatient', () => {
it('GETs /fhir/DocumentReference with patient ID as subject param', async () => {
const token = await acquireToken();
const bundle = { resourceType: 'Bundle', entry: [] };
mockRequest.get.mockResolvedValue({ data: bundle });
const result = await searchDocumentReferenceByPatient(REGISTRY_URL, token, '5037097');
const result = await findDocumentReferenceByPatient(token, 'http://mpi/fhir/Patient/123');
expect(mockRequest.get).toHaveBeenCalledWith('/fhir/DocumentReference', {
params: { patient: '5037097' },
});
expect(mockRequest.get).toHaveBeenCalledWith(
expect.anything(),
{ params: { subject: 'http://mpi/fhir/Patient/123' } }
);
expect(result).toEqual(bundle);
});
});
@ -165,15 +101,18 @@ describe('searchDocumentReference', () => {
const custodian = { system: 'https://federador.msal.gob.ar/uri', value: 'efector-001' };
const type = { system: 'http://loinc.org', value: '60591-5' };
const result = await searchDocumentReference(REGISTRY_URL, token, subject, custodian, type);
const result = await searchDocumentReference(token, subject, custodian, type);
expect(mockRequest.get).toHaveBeenCalledWith('/fhir/DocumentReference', {
params: {
subject: 'https://federador.msal.gob.ar/patient-id|5037097',
custodian: 'https://federador.msal.gob.ar/uri|efector-001',
type: 'http://loinc.org|60591-5',
},
});
expect(mockRequest.get).toHaveBeenCalledWith(
expect.anything(),
{
params: {
subject: 'https://federador.msal.gob.ar/patient-id|5037097',
custodian: 'https://federador.msal.gob.ar/uri|efector-001',
type: 'http://loinc.org|60591-5',
},
}
);
expect(result).toEqual(bundle);
});
});

View File

@ -1,17 +1,16 @@
require('dotenv').config();
const axios = require('axios');
const { getBusToken } = require('../../utils/busAuth');
const { postPatient, getPatientById, searchPatient, matchPatient } = require('../../services/patient');
const { createPatient, findPatientById, findPatient, findPatientByMatch } = 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() };
const mockRequest = { get: jest.fn(), post: jest.fn(), put: jest.fn() };
beforeEach(() => {
jest.clearAllMocks();
@ -23,49 +22,49 @@ async function acquireToken() {
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 () => {
// Internal URL used by the MPI service (replaced by maskPrivateURL)
const INTERNAL_MPI_BASE = 'https://federador.qa-bus-interoperabilidad.svc.cluster.local:8080/masterfile-federacion-service/fhir/Patient';
describe('createPatient', () => {
it('POSTs the patient to the MPI and returns the created resource', 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}`,
},
mockRequest.post.mockResolvedValue({
data: {},
headers: { location: `${INTERNAL_MPI_BASE}/1` },
});
expect(mockRequest.post).toHaveBeenCalledWith('/fhir/Patient', patient);
mockRequest.get.mockResolvedValue({ data: responseData });
const result = await createPatient(token, patient);
expect(mockRequest.post).toHaveBeenCalledWith(expect.anything(), patient);
expect(result).toEqual(responseData);
});
});
describe('getPatientById', () => {
it('GETs /fhir/Patient/:id and returns response data', async () => {
describe('findPatientById', () => {
it('GETs the patient by 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');
const result = await findPatientById(token, '42');
expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient/42');
expect(mockRequest.get).toHaveBeenCalledWith(expect.anything());
expect(result).toEqual(responseData);
});
});
describe('searchPatient', () => {
describe('findPatient', () => {
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, {});
const result = await findPatient(token, {});
expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient', { params: {} });
expect(mockRequest.get).toHaveBeenCalledWith(expect.anything(), { params: {} });
expect(result).toEqual(bundle);
});
@ -73,7 +72,7 @@ describe('searchPatient', () => {
const token = await acquireToken();
mockRequest.get.mockResolvedValue({ data: {} });
await searchPatient(MPI_URL, token, {
await findPatient(token, {
name: 'Juan',
family: 'Perez',
birthdate: '1983-04-17',
@ -81,7 +80,7 @@ describe('searchPatient', () => {
phone: '1141233100',
});
expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient', {
expect(mockRequest.get).toHaveBeenCalledWith(expect.anything(), {
params: {
name: 'Juan',
family: 'Perez',
@ -92,42 +91,28 @@ describe('searchPatient', () => {
});
});
it('combines identifierSystem and identifierValue into identifier param', async () => {
it('passes the identifier param directly when provided as system|value string', async () => {
const token = await acquireToken();
mockRequest.get.mockResolvedValue({ data: {} });
await searchPatient(MPI_URL, token, {
identifierSystem: 'http://www.renaper.gob.ar/dni',
identifierValue: '30945027',
});
await findPatient(token, { identifier: 'http://www.renaper.gob.ar/dni|30945027' });
expect(mockRequest.get).toHaveBeenCalledWith('/fhir/Patient', {
expect(mockRequest.get).toHaveBeenCalledWith(expect.anything(), {
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 () => {
describe('findPatientByMatch', () => {
it('POSTs a Parameters resource to $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);
const result = await findPatientByMatch(token, patient);
expect(mockRequest.post).toHaveBeenCalledWith('/fhir/Patient/$match', {
expect(mockRequest.post).toHaveBeenCalledWith(expect.anything(), {
resourceType: 'Parameters',
parameter: [{ name: 'resource', resource: patient }],
});
@ -139,9 +124,9 @@ describe('matchPatient', () => {
const patient = { resourceType: 'Patient' };
mockRequest.post.mockResolvedValue({ data: {} });
await matchPatient(MPI_URL, token, patient, 3);
await findPatientByMatch(token, patient, 3);
expect(mockRequest.post).toHaveBeenCalledWith('/fhir/Patient/$match', {
expect(mockRequest.post).toHaveBeenCalledWith(expect.anything(), {
resourceType: 'Parameters',
parameter: [
{ name: 'resource', resource: patient },
@ -155,7 +140,7 @@ describe('matchPatient', () => {
const patient = { resourceType: 'Patient' };
mockRequest.post.mockResolvedValue({ data: {} });
await matchPatient(MPI_URL, token, patient);
await findPatientByMatch(token, patient);
const call = mockRequest.post.mock.calls[0];
const parameters = call[1];

View File

@ -0,0 +1,8 @@
process.env.BUS_URL = 'http://bus-host:8080';
process.env.BUS_JWT_SECRET = 'test-secret';
process.env.BUS_ISSUER = 'https://test-repositorio-url';
process.env.MPI_SCOPE = 'Patient/*.read,Patient/*.write';
process.env.DOCUMENT_REGISTRY_SCOPE = 'DocumentReference/*.read,DocumentReference/*.write';
process.env.FHIR_URL = 'http://hapi-fhir-host:8080/fhir';
process.env.MPI_URL = 'http://mpi-host:8080';
process.env.DOCUMENT_REGISTRY_URL = 'http://document-registry-host:8080';

View File

@ -89,19 +89,20 @@ describe('getBusToken', () => {
});
describe('createBusRequest', () => {
it('creates an axios instance with the correct baseURL and headers', () => {
it('creates an axios instance with Authorization and Content-Type headers', () => {
const mockInstance = { get: jest.fn(), post: jest.fn() };
axios.create.mockReturnValue(mockInstance);
const token = 'my-token';
createBusRequest(BUS_URL, token);
createBusRequest(token);
expect(axios.create).toHaveBeenCalledWith({
baseURL: BUS_URL,
headers: {
'Content-Type': 'application/fhir+json',
'Authorization': `Bearer ${token}`,
},
});
expect(axios.create).toHaveBeenCalledWith(
expect.objectContaining({
headers: {
'Content-Type': 'application/fhir+json',
'Authorization': `Bearer ${token}`,
},
})
);
});
});