Repository: FHIR/sushi
Pull request #458 (2020-05-21 20:30:17)

Fix only rule on profile of reference
Fixes https://github.com/FHIR/sushi/issues/451.

Now, if you make an `only` rule on a profile of Reference, SUSHI correctly tracks that profile under `type.profile`, instead of `type.targetProfile`. The tests in https://github.com/FHIR/sushi/commit/a55e3b282450e7b5501c5cea5bff7d1e90424242 will fail, but then pass on https://github.com/FHIR/sushi/commit/3a4c62c1692375b0d509f685ec69fcdd2570473b. Additionally, you can test out using the example linked in the issue. On master, you will get errors and incorrect output. On this branch, the errors will go away, and the `FixedStartReference` will be correctly created.


Patch:
diff --git a/src/fhirtypes/ElementDefinition.ts b/src/fhirtypes/ElementDefinition.ts
index 995e7e3..fc3690f 100644
--- a/src/fhirtypes/ElementDefinition.ts
+++ b/src/fhirtypes/ElementDefinition.ts
@@ -855,7 +855,7 @@ export class ElementDefinition {
     for (const match of matches) {
       if (match.metadata.id === newType.code) {
         continue;
-      } else if (match.code === 'Reference') {
+      } else if (match.code === 'Reference' && match.metadata.sdType !== 'Reference') {
         matchedTargetProfiles.push(match.metadata.url);
       } else {
         matchedProfiles.push(match.metadata.url);


Test patch:
diff --git a/test/fhirtypes/ElementDefinition.constrainType.test.ts b/test/fhirtypes/ElementDefinition.constrainType.test.ts
index 178ff9d..8756292 100644
--- a/test/fhirtypes/ElementDefinition.constrainType.test.ts
+++ b/test/fhirtypes/ElementDefinition.constrainType.test.ts
@@ -7,10 +7,12 @@ import { Type } from '../../src/utils';
 import cloneDeep from 'lodash/cloneDeep';
 import path from 'path';
 import { OnlyRule } from '../../src/fshtypes/rules';
+import { readFileSync } from 'fs-extra';
 
 describe('ElementDefinition', () => {
   let defs: FHIRDefinitions;
   let observation: StructureDefinition;
+  let extension: StructureDefinition;
   let fisher: TestFisher;
   beforeAll(() => {
     defs = new FHIRDefinitions();
@@ -23,6 +25,7 @@ describe('ElementDefinition', () => {
   });
   beforeEach(() => {
     observation = fisher.fishForStructureDefinition('Observation');
+    extension = fisher.fishForStructureDefinition('Extension');
   });
 
   describe('#constrainType()', () => {
@@ -84,6 +87,32 @@ describe('ElementDefinition', () => {
       );
     });
 
+    it('should allow a choice to be constrained to a profile of Reference', () => {
+      const def = JSON.parse(
+        readFileSync(
+          path.join(
+            __dirname,
+            '..',
+            'testhelpers',
+            'testdefs',
+            'StructureDefinition-reference-with-type.json'
+          ),
+          'utf-8'
+        ).trim()
+      );
+      defs.add(def);
+      const valueX = extension.elements.find(e => e.id === 'Extension.value[x]');
+      const valueConstraint = new OnlyRule('value[x]');
+      valueConstraint.types = [{ type: 'ReferenceWithType' }];
+      valueX.constrainType(valueConstraint, fisher);
+      expect(valueX.type).toHaveLength(1);
+      expect(valueX.type[0]).toEqual(
+        new ElementDefinitionType('Reference').withProfiles(
+          'http://example.org/StructureDefinition/reference-with-type'
+        )
+      );
+    });
+
     it('should allow a resource type to be constrained to multiple profiles', () => {
       const valueX = observation.elements.find(e => e.id === 'Observation.value[x]');
       const valueConstraint = new OnlyRule('value[x]');
diff --git a/test/testhelpers/testdefs/StructureDefinition-reference-with-type.json b/test/testhelpers/testdefs/StructureDefinition-reference-with-type.json
new file mode 100644
index 0000000..56a1c37
--- /dev/null
+++ b/test/testhelpers/testdefs/StructureDefinition-reference-with-type.json
@@ -0,0 +1,29 @@
+{
+  "resourceType": "StructureDefinition",
+  "id": "reference-with-type",
+  "url": "http://example.org/StructureDefinition/reference-with-type",
+  "version": "0.1.0",
+  "name": "ReferenceWithType",
+  "title": "Reference with Required Type",
+  "status": "active",
+  "fhirVersion": "4.0.1",
+  "kind": "complex-type",
+  "abstract": false,
+  "type": "Reference",
+  "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Reference",
+  "derivation": "constraint",
+  "differential": {
+    "element": [
+      {
+        "id": "Reference",
+        "path": "Reference"
+      },
+      {
+        "id": "Reference.type",
+        "path": "Reference.type",
+        "min": 1,
+        "max": "1"
+      }
+    ]
+  }
+}