it('supports repeated query params', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .get('/Patient?_include=Observation&_include=MedicationRequest') .reply(200, () => readStreamFor('search-results.json')); const response = await this.fhirClient.resourceSearch({ resourceType: 'Patient', searchParams: { _include: ['Observation', 'MedicationRequest'] }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.id).to.equal('95a2de95-08c7-418e-b4d0-2dd6fc8cc37e'); });
context('with a relative reference', function () { it('requests the resource from baseUrl and returns it', async function () { const resourceType = 'Patient'; const id = 'eb3271e1-ae1b-4644-9332-41e32c829486'; const reference = `${resourceType}/${id}`; nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .get(`/${reference}`) .reply(200, () => readStreamFor('patient.json')); const response = await this.resolver.resolve({ reference }); expect(response.resourceType).to.equal(resourceType); expect(response.id).to.equal(id); }); });
describe('#bearerToken=', function () { it('sets the header Authorization to a Bearer token', async function () { this.fhirClient.bearerToken = 'XYZ'; nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .matchHeader('Authorization', 'Bearer XYZ') .get('/Patient/test-access-token') .reply(200, () => readStreamFor('patient.json')); await this.fhirClient.read({ resourceType: 'Patient', id: 'test-access-token' }); }); it('sets the header only for the current instance', async function () { const otherFHIRClient = new Client({ baseUrl: this.baseUrl }); this.fhirClient.bearerToken = 'XYZ'; nock(this.baseUrl, { badheaders: ['Authorization'] }) .matchHeader('accept', 'application/json+fhir') .get('/Patient/test-access-token') .reply(200, () => readStreamFor('patient.json')); await otherFHIRClient.read({ resourceType: 'Patient', id: 'test-access-token' }); }); });
it('builds a request with custom headers', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .matchHeader('abc', 'XYZ') .post('/') .reply(200, () => readStreamFor('batch-results.json')); const body = readFixture('batch-request.json'); const response = await this.fhirClient.batch({ body, options: { headers: { abc: 'XYZ' } }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.type).to.equal('batch-response'); });
it('returns a matching batch response bundle', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .post('/') .reply(200, () => readStreamFor('batch-results.json')); const body = readFixture('batch-request.json'); const response = await this.fhirClient.batch({ body }); expect(response.resourceType).to.equal('Bundle'); expect(response.type).to.equal('batch-response'); expect(response.entry[0].resource.resourceType).to.equal('OperationOutcome'); expect(response.entry[0].resource.text.status).to.equal('generated'); expect(response.entry[1].response.status).to.equal('201 Created'); expect(response.entry[2].response.status).to.equal('200 OK'); expect(response.entry[3].response.status).to.equal('204 No Content'); expect(response.entry[4].response.status).to.equal('200 OK'); expect(response.entry[4].resource.resourceType).to.equal('Bundle'); });
it('builds a request with custom headers', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .matchHeader('abc', 'XYZ') .get('/Patient/385800201/Condition') .reply(200, () => readStreamFor('compartment-search-results.json')); const response = await this.fhirClient.compartmentSearch({ compartment: { resourceType: 'Patient', id: 385800201 }, resourceType: 'Condition', options: { headers: { abc: 'XYZ' } }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.type).to.equal('searchset'); expect(response.total).to.equal(6); });
it('returns a matching search results bundle without query params', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .get('/Patient/385800201/Condition') .reply(200, () => readStreamFor('compartment-search-results.json')); const response = await this.fhirClient.compartmentSearch({ compartment: { resourceType: 'Patient', id: 385800201 }, resourceType: 'Condition', }); expect(response.resourceType).to.equal('Bundle'); expect(response.type).to.equal('searchset'); expect(response.total).to.equal(6); });
it('supports searching with no query parameters', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .get('/Patient') .times(2) .reply(200, () => readStreamFor('search-results.json')); let response = await this.fhirClient.resourceSearch({ resourceType: 'Patient', }); expect(response.resourceType).to.equal('Bundle'); expect(response.id).to.equal('95a2de95-08c7-418e-b4d0-2dd6fc8cc37e'); response = await this.fhirClient.resourceSearch({ resourceType: 'Patient', searchParams: {}, }); expect(response.resourceType).to.equal('Bundle'); expect(response.id).to.equal('95a2de95-08c7-418e-b4d0-2dd6fc8cc37e'); });
it('performs a POST search', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .matchHeader('content-type', 'application/x-www-form-urlencoded') .post('/Patient/_search', 'name=abbott') .reply(200, () => readStreamFor('search-results.json')); const response = await this.fhirClient.resourceSearch({ resourceType: 'Patient', searchParams: { name: 'abbott' }, options: { postSearch: true }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.id).to.equal('95a2de95-08c7-418e-b4d0-2dd6fc8cc37e'); });
it('performs a POST search', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .matchHeader('content-type', 'application/x-www-form-urlencoded') .post('/Patient/385800201/Condition/_search', 'category=problem') .reply(200, () => readStreamFor('compartment-search-with-query-results.json')); const response = await this.fhirClient.compartmentSearch({ compartment: { resourceType: 'Patient', id: 385800201 }, resourceType: 'Condition', searchParams: { category: 'problem' }, options: { postSearch: true }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.type).to.equal('searchset'); expect(response.total).to.equal(6); });
it('builds a request with custom headers', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .matchHeader('abc', 'XYZ') .get('/Patient?name=abbott') .reply(200, () => readStreamFor('search-results.json')); const response = await this.fhirClient.resourceSearch({ resourceType: 'Patient', searchParams: { name: 'abbott' }, options: { headers: { abc: 'XYZ' } }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.id).to.equal('95a2de95-08c7-418e-b4d0-2dd6fc8cc37e'); });
it('returns a matching search results bundle', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .get('/Patient?name=abbott') .reply(200, () => readStreamFor('search-results.json')); const response = await this.fhirClient.resourceSearch({ resourceType: 'Patient', searchParams: { name: 'abbott' }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.id).to.equal('95a2de95-08c7-418e-b4d0-2dd6fc8cc37e'); });
it('returns a matching search results bundle with query params', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .get('/Patient/385800201/Condition?category=problem') .reply(200, () => readStreamFor('compartment-search-with-query-results.json')); const response = await this.fhirClient.compartmentSearch({ compartment: { resourceType: 'Patient', id: 385800201 }, resourceType: 'Condition', searchParams: { category: 'problem' }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.type).to.equal('searchset'); expect(response.total).to.equal(6); });
it('supports repeated query params', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .get('/Patient/385800201/Condition?_include=Observation&_include=MedicationRequest&category=problem') .reply(200, () => readStreamFor('compartment-search-with-query-results.json')); const response = await this.fhirClient.compartmentSearch({ compartment: { resourceType: 'Patient', id: 385800201 }, resourceType: 'Condition', searchParams: { category: 'problem', _include: ['Observation', 'MedicationRequest'], }, }); expect(response.resourceType).to.equal('Bundle'); expect(response.type).to.equal('searchset'); expect(response.total).to.equal(6); });
it('returns a bundle of errors if any operations are unsuccessful', async function () { nock(this.baseUrl) .matchHeader('accept', 'application/json+fhir') .post('/') .reply(200, () => readStreamFor('batch-error-results.json')); const body = readFixture('batch-error-request.json'); const response = await this.fhirClient.batch({ body }); expect(response.resourceType).to.equal('Bundle'); expect(response.type).to.equal('batch-response'); expect(response.entry[0].resource.resourceType).to.equal('OperationOutcome'); expect(response.entry[0].resource.text.status).to.equal('generated'); expect(response.entry[1].response.status).to.equal('500 Internal Server Error'); expect(response.entry[2].response.status).to.equal('500 Internal Server Error'); expect(response.entry[3].response.status).to.equal('404 Not Found'); // A search operation yielding zero results returns an empty bundle despite failures expect(response.entry[4].response.status).to.equal('200 OK'); expect(response.entry[4].resource.resourceType).to.equal('Bundle'); });