Skip to content

Commit

Permalink
Merge pull request #112 from mechanik-daniel/fix-extension-value-error
Browse files Browse the repository at this point in the history
Fix extension value error
  • Loading branch information
mechanik-daniel authored Nov 27, 2024
2 parents 5c5a8c9 + a9df3b3 commit fec4b38
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 47 deletions.
3 changes: 3 additions & 0 deletions src/helpers/jsonataFuncs/getMandatoriesOfElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import { getElementDefinition } from '../parser/getElementDefinition';
import { getStructureDefinition } from '../jsonataFunctions';
import { getMandatoriesOfStructure } from './getMandatoriesOfStructure';

const dev = process.env.NODE_ENV === 'dev';

export const getMandatoriesOfElement = async (structId: string, relativePath: string): Promise<any> => {
if (dev) console.log({ func: getMandatoriesOfElement, structId, relativePath });
/* for primitives, return the primitive if it has a fixed value */
/* for complex types, return an object containing all mandatory */
/* decendants that have fixed values down the chain */
Expand Down
12 changes: 11 additions & 1 deletion src/helpers/jsonataFuncs/getMandatoriesOfStructure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@
import { getSnapshot } from '../parser/getSnapshot';
import { replaceColonsWithBrackets } from '../stringFunctions';
import { getMandatoriesOfElement } from './getMandatoriesOfElement';
import { returnPathWithoutX } from '../parser/returnPathWithoutX'
import { initCapOnce } from '../stringFunctions';

const dev = process.env.NODE_ENV === 'dev';

export const getMandatoriesOfStructure = async (structId: string): Promise<any> => {
if (dev) console.log({ func: getMandatoriesOfStructure, structId });
const snapshot = await getSnapshot(structId);
const rootMandatories = snapshot.snapshot.element.filter(item => item.min > 0 && item.id.split('.').length === 2);
const res = {};
for (const item of rootMandatories) {
const idSuffix = item.id.substring(item.id.indexOf(snapshot.type) + snapshot.type.length + 1);
const typeCount = item.type.length;
const isPoly = item.id.endsWith('[x]');
const idSuffixRaw = item.id.substring(item.id.indexOf(snapshot.type) + snapshot.type.length + 1);
const idSuffix = isPoly && typeCount === 1 ? returnPathWithoutX(idSuffixRaw) + initCapOnce(item.type[0].code) : idSuffixRaw;
if (dev) console.log({ itemId: item.id, idSuffix });
// if id suffix ends with [x] and there's a single type - fix the id accordingly
const val = await getMandatoriesOfElement(structId, idSuffix);
if (val) {
if (item.base.max > '1' || item.base.max === '*' || item.max > '1' || item.max === '*') {
Expand Down
12 changes: 7 additions & 5 deletions src/helpers/jsonataFunctions/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { getStructureDefinition } from './getStructureDefinition';
import { logInfo, logWarn } from './log';
import { registerTable } from './registerTable';

const dev = process.env.NODE_ENV === 'dev';

const compiledExpression = async (expression: string): Promise<jsonata.Expression> => {
const { compiledExpressions } = getCache();
// takes a fume expression string and compiles it into a jsonata expression
Expand Down Expand Up @@ -104,11 +106,11 @@ export const transform = async (input, expression: string, extraBindings: Record
bindings.v2codeLookup = v2.v2codeLookup;
bindings.v2tableUrl = v2.v2tableUrl;
bindings.toJsonataString = compiler.toJsonataString;
bindings.getMandatoriesOfElement = compiler.getMandatoriesOfElement;
bindings.getMandatoriesOfStructure = compiler.getMandatoriesOfStructure;
bindings.getElementDefinition = compiler.getElementDefinition;
bindings.replaceColonsWithBrackets = compiler.replaceColonsWithBrackets;
bindings.removeComments = removeComments;
if (dev) bindings.getMandatoriesOfElement = compiler.getMandatoriesOfElement;
if (dev) bindings.getMandatoriesOfStructure = compiler.getMandatoriesOfStructure;
if (dev) bindings.getElementDefinition = compiler.getElementDefinition;
if (dev) bindings.replaceColonsWithBrackets = compiler.replaceColonsWithBrackets;
if (dev) bindings.removeComments = removeComments;
bindings.getCodeSystem = conformance.getCodeSystem;
bindings.getValueSet = conformance.getValueSet;
// end of debug functions
Expand Down
112 changes: 72 additions & 40 deletions tests/root/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,46 +329,48 @@ describe('integration tests', () => {

// IL-Core-Vital-Signs: ['valueQuantity']
// eslint-disable-next-line @typescript-eslint/quotes
fume = "InstanceOf: il-core-vital-signs\r\n* status = 'final'\r\n* code.coding\r\n * system = 'http://loinc.org'\r\n * code = '8310-5'\r\n* subject.display = 'aaa'\r\n* effectiveDateTime = '2024-06-04T13:36:49.823Z'\r\n* valueQuantity\r\n * system = 'http://unitsofmeasure.org'\r\n * code = value\r\n * value = '100'";
correct = await request(globalThis.app).post('/').send({ input: { value: 'kg' }, fume });
wrong = await request(globalThis.app).post('/').send({ input: { value: 'parsecs' }, fume });
expect(correct.body).toStrictEqual({
resourceType: 'Observation',
meta: {
profile: [
'http://fhir.health.gov.il/StructureDefinition/il-core-vital-signs'
]
},
category: [
{
coding: [
{
system: 'http://terminology.hl7.org/CodeSystem/observation-category',
code: 'vital-signs'
}
]
}
],
status: 'final',
code: {
coding: [
{
system: 'http://loinc.org',
code: '8310-5'
}
]
},
subject: {
display: 'aaa'
},
effectiveDateTime: '2024-06-04T13:36:49.823Z',
valueQuantity: {
system: 'http://unitsofmeasure.org',
code: 'kg',
value: 100
}
});
expect(wrong.body.message).toBe('Transformation error: The code \'http://unitsofmeasure.org#parsecs\' is invalid for element Observation.valueQuantity. This code is not in the required value set');

// THIS TEST IS CANCELLED UNTIL ISSUE 111 IS RESOLVED! https://github.com/Outburn-IL/fume-community/issues/111
// fume = "InstanceOf: il-core-vital-signs\r\n* status = 'final'\r\n* code.coding\r\n * system = 'http://loinc.org'\r\n * code = '8310-5'\r\n* subject.display = 'aaa'\r\n* effectiveDateTime = '2024-06-04T13:36:49.823Z'\r\n* valueQuantity\r\n * system = 'http://unitsofmeasure.org'\r\n * code = value\r\n * value = '100'";
// correct = await request(globalThis.app).post('/').send({ input: { value: 'kg' }, fume });
// wrong = await request(globalThis.app).post('/').send({ input: { value: 'parsecs' }, fume });
// expect(correct.body).toStrictEqual({
// resourceType: 'Observation',
// meta: {
// profile: [
// 'http://fhir.health.gov.il/StructureDefinition/il-core-vital-signs'
// ]
// },
// category: [
// {
// coding: [
// {
// system: 'http://terminology.hl7.org/CodeSystem/observation-category',
// code: 'vital-signs'
// }
// ]
// }
// ],
// status: 'final',
// code: {
// coding: [
// {
// system: 'http://loinc.org',
// code: '8310-5'
// }
// ]
// },
// subject: {
// display: 'aaa'
// },
// effectiveDateTime: '2024-06-04T13:36:49.823Z',
// valueQuantity: {
// system: 'http://unitsofmeasure.org',
// code: 'kg',
// value: 100
// }
// });
// expect(wrong.body.message).toBe('Transformation error: The code \'http://unitsofmeasure.org#parsecs\' is invalid for element Observation.valueQuantity. This code is not in the required value set');

// IL-Core-Address: country
// eslint-disable-next-line @typescript-eslint/quotes
Expand Down Expand Up @@ -1191,4 +1193,34 @@ describe('integration tests', () => {
]
});
});

test('Correct value[x] name in a fixed value extension profile', async () => {
const mapping = `
InstanceOf: Patient
* extension[HearingLossDisability]
`;
const requestBody = {
input: {},
fume: mapping
};

const res = await request(globalThis.app).post('/').send(requestBody);
expect(res.body).toStrictEqual({
resourceType: 'Patient',
extension: [
{
url: 'http://hl7.org/fhir/StructureDefinition/patient-disability',
valueCodeableConcept: {
coding: [
{
code: '15188001',
system: 'http://snomed.info/sct',
display: 'Hearing loss (disorder)'
}
]
}
}
]
});
});
});
2 changes: 1 addition & 1 deletion tests/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ async function setup () {
globalThis.fumeServer = new FumeServer();
await globalThis.fumeServer.warmUp({
FHIR_SERVER_BASE: LOCAL_FHIR_API,
FHIR_PACKAGES: '[email protected]'
FHIR_PACKAGES: '[email protected],[email protected]'
});
globalThis.app = globalThis.fumeServer.getExpressApp();
console.log('server started!');
Expand Down

0 comments on commit fec4b38

Please sign in to comment.