Repository: FHIR/sushi (ts)

Issue:
SUSHI reports duplicate "undefined" resource
A user has reported receiving the following message:
> **error** Ignoring FSH definition for undefined since it duplicates existing pre-defined resource. To use the FSH definition, remove the conflicting file from "input". If you do want the FSH definition to be ignored, please comment the definition out to remove this error.

Pull request description:
Default to resourceType and id when reporting duplicate resources
Fixes #642.

We were logging a message that used `resource.url`, but it was possible that `resource` was an instance, and did not have a `url` on it. We can guarantee that every resource, instances included, will have a `resourceType` and `id`, so if the `url` is undefined, we now use the `resourceType` and `id` when logging the error message.

Patch:
diff --git a/src/utils/Processing.ts b/src/utils/Processing.ts
index b264c6a..f032ff0 100644
--- a/src/utils/Processing.ts
+++ b/src/utils/Processing.ts
@@ -245,7 +245,9 @@ export function writeFHIRResources(
         count++;
       } else {
         logger.error(
-          `Ignoring FSH definition for ${resource.url} since it duplicates existing pre-defined resource. ` +
+          `Ignoring FSH definition for ${
+            resource.url ?? `${resource.resourceType}/${resource.id}`
+          } since it duplicates existing pre-defined resource. ` +
             'To use the FSH definition, remove the conflicting file from "input". ' +
             'If you do want the FSH definition to be ignored, please comment the definition out ' +
             'to remove this error.'


Test patch:
diff --git a/test/utils/Processing.test.ts b/test/utils/Processing.test.ts
index 374d1af..fd16b2b 100644
--- a/test/utils/Processing.test.ts
+++ b/test/utils/Processing.test.ts
@@ -403,6 +403,14 @@ describe('Processing', () => {
       myFSHDefinedProfile.id = 'my-duplicate-profile';
       myFSHDefinedProfile.url = 'http://example.com/StructureDefinition/my-duplicate-profile';
 
+      const myPredefinedInstance = new InstanceDefinition();
+      myPredefinedInstance.id = 'my-duplicate-instance';
+      myPredefinedInstance.resourceType = 'Patient';
+      defs.addPredefinedResource('Patient-my-duplicate-instance.json', myPredefinedInstance);
+      const myFSHDefinedInstance = new InstanceDefinition();
+      myFSHDefinedInstance.id = 'my-duplicate-instance';
+      myFSHDefinedInstance.resourceType = 'Patient';
+
       outPackage.profiles.push(myProfile, myFSHDefinedProfile);
       outPackage.extensions.push(myExtension);
       outPackage.valueSets.push(myValueSet);
@@ -416,7 +424,8 @@ describe('Processing', () => {
         myOperationDefinition,
         myExtensionInstance,
         myProfileInstance,
-        myOtherInstance
+        myOtherInstance,
+        myFSHDefinedInstance
       );
     });
 
@@ -463,9 +472,26 @@ describe('Processing', () => {
             )
           )
         ).toBeFalsy();
-        expect(loggerSpy.getLastMessage('error')).toMatch(
-          /Ignoring FSH definition for .*my-duplicate-profile/
-        );
+        expect(
+          loggerSpy
+            .getAllMessages('error')
+            .some(error => error.match(/Ignoring FSH definition for .*my-duplicate-profile/))
+        ).toBeTruthy();
+        expect(
+          fs.existsSync(
+            path.join(
+              tempIGPubRoot,
+              'fsh-generated',
+              'resources',
+              'Patient-my-duplicate-instance.json'
+            )
+          )
+        ).toBeFalsy();
+        expect(
+          loggerSpy
+            .getAllMessages('error')
+            .some(error => error.match(/Ignoring FSH definition for .*my-duplicate-instance/))
+        ).toBeTruthy();
       });
     });