Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Commit

Permalink
feat: enhance numeric and quantity search (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
carvantes committed Apr 20, 2021
1 parent 2a836a4 commit e950aca
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 16 deletions.
116 changes: 105 additions & 11 deletions integration-tests/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { AxiosInstance } from 'axios';
import waitForExpect from 'wait-for-expect';
import {
aFewMinutesAgoAsDate,
expectResourceToBePartOfSearchResults,
expectResourceToNotBePartOfSearchResults,
getFhirClient,
Expand All @@ -13,18 +14,18 @@ import {

jest.setTimeout(60 * 1000);

const waitForPatientToBeSearchable = async (client: AxiosInstance, patient: any) => {
const waitForResourceToBeSearchable = async (client: AxiosInstance, resource: any) => {
return waitForExpect(
expectResourceToBePartOfSearchResults.bind(
null,
client,
{
url: 'Patient',
url: resource.resourceType,
params: {
_id: patient.id,
_id: resource.id,
},
},
patient,
resource,
),
20000,
3000,
Expand All @@ -40,9 +41,9 @@ describe('search', () => {
const testPatient: ReturnType<typeof randomPatient> = (await client.post('Patient', randomPatient())).data;

// wait for the patient to be asynchronously written to ES
await waitForPatientToBeSearchable(client, testPatient);
await waitForResourceToBeSearchable(client, testPatient);

const aFewMinutesAgo = new Date(Date.now() - 1000 * 60 * 10).toJSON();
const aFewMinutesAgo = aFewMinutesAgoAsDate();

const p = (params: any) => ({ url: 'Patient', params: { _lastUpdated: `ge${aFewMinutesAgo}`, ...params } });
const testsParams = [
Expand Down Expand Up @@ -73,9 +74,9 @@ describe('search', () => {
const testPatient: ReturnType<typeof randomPatient> = (await client.post('Patient', randomPatientData)).data;

// wait for the patient to be asynchronously written to ES
await waitForPatientToBeSearchable(client, testPatient);
await waitForResourceToBeSearchable(client, testPatient);

const aFewMinutesAgo = new Date(Date.now() - 1000 * 60 * 10).toJSON();
const aFewMinutesAgo = aFewMinutesAgoAsDate();
const p = (params: any) => ({ url: 'Patient', params: { _lastUpdated: `ge${aFewMinutesAgo}`, ...params } });

const testsParamsThatMatch = [
Expand Down Expand Up @@ -138,10 +139,10 @@ describe('search', () => {
).data;

// wait for the patient to be asynchronously written to ES
await waitForPatientToBeSearchable(client, testPatient);
await waitForPatientToBeSearchable(client, testPatientNoSystem);
await waitForResourceToBeSearchable(client, testPatient);
await waitForResourceToBeSearchable(client, testPatientNoSystem);

const aFewMinutesAgo = new Date(Date.now() - 1000 * 60 * 10).toJSON();
const aFewMinutesAgo = aFewMinutesAgoAsDate();
const p = (params: any) => ({ url: 'Patient', params: { _lastUpdated: `ge${aFewMinutesAgo}`, ...params } });

const testsParamsThatMatch = [
Expand All @@ -161,6 +162,99 @@ describe('search', () => {
);
});

test('quantity', async () => {
const observation = {
resourceType: 'Observation',
status: 'final',
code: {
coding: [
{
system: 'http://loinc.org',
code: '29463-7',
display: 'Body Weight',
},
],
},
valueQuantity: {
value: 185,
unit: 'lbs',
system: 'http://unitsofmeasure.org',
code: '[lb_av]',
},
};

const testObservation = (await client.post('Observation', observation)).data;
await waitForResourceToBeSearchable(client, testObservation);

const aFewMinutesAgo = aFewMinutesAgoAsDate();

const testsParams = [
{ 'value-quantity': '185|http://unitsofmeasure.org|[lb_av]' },
{ 'value-quantity': '185||[lb_av]' },
{ 'value-quantity': '185' },
{ 'value-quantity': 'ge185' },
{ 'value-quantity': 'le185' },
{ 'value-quantity': 'gt184.5' },
{ 'value-quantity': 'sa184.5' },
{ 'value-quantity': 'lt200' },
{ 'value-quantity': 'eb200' },
{ 'value-quantity': 'eq1.8e2' },
].map(params => ({
url: 'Observation',
params: { _lastUpdated: `ge${aFewMinutesAgo}`, ...params },
}));

// eslint-disable-next-line no-restricted-syntax
for (const testParams of testsParams) {
// eslint-disable-next-line no-await-in-loop
await expectResourceToBePartOfSearchResults(client, testParams, testObservation);
}
});

test('numeric', async () => {
const chargeItem = {
resourceType: 'ChargeItem',
status: 'billable',
code: {
coding: [
{
code: '01510',
display: 'Zusatzpauschale für Beobachtung nach diagnostischer Koronarangiografie',
},
],
},
subject: {
reference: 'Patient/example',
},
factorOverride: 0.8,
};

const testChargeItem = (await client.post('ChargeItem', chargeItem)).data;
await waitForResourceToBeSearchable(client, testChargeItem);

const aFewMinutesAgo = aFewMinutesAgoAsDate();

const testsParams = [
{ 'factor-override': '0.8' },
{ 'factor-override': 'ge0.8' },
{ 'factor-override': 'le0.8' },
{ 'factor-override': 'gt0.5' },
{ 'factor-override': 'sa0.5' },
{ 'factor-override': 'lt1' },
{ 'factor-override': 'eb1' },
{ 'factor-override': 'eq8e-1' },
].map(params => ({
url: 'ChargeItem',
params: { _lastUpdated: `ge${aFewMinutesAgo}`, ...params },
}));

// eslint-disable-next-line no-restricted-syntax
for (const testParams of testsParams) {
// eslint-disable-next-line no-await-in-loop
await expectResourceToBePartOfSearchResults(client, testParams, testChargeItem);
}
});

test('invalid search parameter should fail with 400', async () => {
await expect(client.get('Patient', { params: { someInvalidSearchParam: 'someValue' } })).rejects.toMatchObject({
response: { status: 400 },
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,5 @@ export const expectResourceToNotBePartOfSearchResults = async (
]);
await expectSearchResultsToFulfillExpectation(client, search, bundleEntryExpectation);
};

export const aFewMinutesAgoAsDate = () => new Date(Date.now() - 1000 * 60 * 10).toJSON();
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"fhir-works-on-aws-interface": "8.1.1",
"fhir-works-on-aws-persistence-ddb": "3.3.2",
"fhir-works-on-aws-routing": "5.1.1",
"fhir-works-on-aws-search-es": "2.3.0",
"fhir-works-on-aws-search-es": "2.4.0",
"serverless-http": "^2.3.1",
"yargs": "^16.2.0"
},
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5796,10 +5796,10 @@ fhir-works-on-aws-routing@5.1.1:
serverless-http "^2.3.1"
uuid "^3.4.0"

fhir-works-on-aws-search-es@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/fhir-works-on-aws-search-es/-/fhir-works-on-aws-search-es-2.3.0.tgz#ba0785195f60f7c31d94bcb248c6781b667bc151"
integrity sha512-/4JFYViCAQUrawKOi4pcyPptMYFo42YMx/DRvejrRozaRV2mOJHEpdZsvvzogHO9FNWvuraC0v9ZWz46H21u6w==
fhir-works-on-aws-search-es@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/fhir-works-on-aws-search-es/-/fhir-works-on-aws-search-es-2.4.0.tgz#377df0c966142c8456b16bac6c5301492d5e1525"
integrity sha512-Kvul3re3yYjgAX8b2Ru/sV0frTEcA+Z9/RU+zCkicv04tGxT7W+HyR1AQdq4+mE3aACIhaaBAVRyn6ui+JXXZQ==
dependencies:
"@elastic/elasticsearch" "7"
aws-elasticsearch-connector "^8.2.0"
Expand Down

0 comments on commit e950aca

Please sign in to comment.