Skip to content

Commit a46b53e

Browse files
committed
Increase Redaction Code Coverage
1 parent dd9e932 commit a46b53e

File tree

5 files changed

+284
-30
lines changed

5 files changed

+284
-30
lines changed

src/main/java/de/medizininformatikinitiative/torch/util/Redaction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public Base redact(ExtractionRedactionWrapper wrapper) {
8181

8282
if (!validProfiles.equals(wrapper.profiles())) {
8383
logger.error("Missing Profiles in Resource {} {}: {} for requested profiles {}", resource.getResourceType(), resource.getId(), resourceProfiles, wrapper.profiles());
84-
throw new RuntimeException("Resource is missing required profiles: " + resourceProfiles);
84+
throw new RuntimeException("Resource is missing required profiles: " + wrapper.profiles());
8585
}
8686
} else {
8787
resourceProfiles = wrapper.profiles().stream().map(CanonicalType::new).toList();

src/test/java/de/medizininformatikinitiative/torch/RedactionTest.java

Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
import org.hl7.fhir.r4.model.CanonicalType;
77
import org.hl7.fhir.r4.model.CodeableConcept;
88
import org.hl7.fhir.r4.model.Coding;
9+
import org.hl7.fhir.r4.model.Condition;
910
import org.hl7.fhir.r4.model.DomainResource;
1011
import org.hl7.fhir.r4.model.Identifier;
1112
import org.hl7.fhir.r4.model.Medication;
1213
import org.hl7.fhir.r4.model.Meta;
14+
import org.hl7.fhir.r4.model.Observation;
1315
import org.hl7.fhir.r4.model.Patient;
1416
import org.junit.Test;
1517
import org.junit.jupiter.api.Nested;
@@ -23,6 +25,7 @@
2325

2426
import static de.medizininformatikinitiative.torch.util.FhirUtil.createAbsentReasonExtension;
2527
import static org.assertj.core.api.Assertions.assertThat;
28+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
2629

2730
public class RedactionTest {
2831

@@ -45,11 +48,11 @@ public RedactionTest() throws IOException {
4548
@ParameterizedTest
4649
@ValueSource(strings = {"Observation_lab_Missing_Elements_Unknown_Slices.json"})
4750
void testObservationLab(String resource) throws IOException {
48-
DomainResource src = integrationTestSetup.readResource("src/test/resources/InputResources/Observation/" + resource);
49-
DomainResource expected = integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
51+
Observation src = (Observation) integrationTestSetup.readResource("src/test/resources/InputResources/Observation/" + resource);
52+
Observation expected = (Observation) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
5053

5154
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(OBSERVATION_LAB), Map.of("Observation.subject", Set.of("Patient/VHF-MIXED-TEST-CASE-0001-a"), "Observation.encounter", Set.of("Encounter/VHF-MIXED-TEST-CASE-0001-a-E-1")), Set.of());
52-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
55+
DomainResource tgt = (Observation) integrationTestSetup.redaction().redact(wrapper);
5356

5457
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
5558
}
@@ -59,11 +62,11 @@ void testObservationLab(String resource) throws IOException {
5962
"Observation-mii-exa-test-data-patient-1-vitalstatus-1.json"
6063
})
6164
void testValueSetBindingPassingThroughAsDiscriminator(String resource) throws IOException {
62-
DomainResource src = integrationTestSetup.readResource("src/test/resources/InputResources/Observation/" + resource);
63-
DomainResource expected = integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
65+
Observation src = (Observation) integrationTestSetup.readResource("src/test/resources/InputResources/Observation/" + resource);
66+
Observation expected = (Observation) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
6467

6568
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(VITALSTATUS), Map.of("Observation.subject", Set.of("Patient/VHF-MIXED-TEST-CASE-0001-a"), "Observation.encounter", Set.of("Encounter/VHF-MIXED-TEST-CASE-0001-a-E-1")), Set.of());
66-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
69+
DomainResource tgt = (Observation) integrationTestSetup.redaction().redact(wrapper);
6770

6871
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
6972
}
@@ -73,18 +76,50 @@ void testValueSetBindingPassingThroughAsDiscriminator(String resource) throws IO
7376
"Observation-mii-exa-test-data-patient-1-vitalstatus-1-identifier.json"
7477
})
7578
void testReferenceComplexType(String resource) throws IOException {
76-
DomainResource src = integrationTestSetup.readResource("src/test/resources/InputResources/Observation/" + resource);
77-
DomainResource expected = integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
79+
Observation src = (Observation) integrationTestSetup.readResource("src/test/resources/InputResources/Observation/" + resource);
80+
Observation expected = (Observation) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
7881

7982
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(VITALSTATUS), Map.of("Observation.subject", Set.of("Patient/VHF-MIXED-TEST-CASE-0001-a"), "Observation.encounter", Set.of("Encounter/VHF-MIXED-TEST-CASE-0001-a-E-1")), Set.of());
80-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
83+
DomainResource tgt = (Observation) integrationTestSetup.redaction().redact(wrapper);
8184

8285
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
8386
}
8487

88+
@Test
89+
public void mismatchProfileWithAssignedProfile() {
90+
org.hl7.fhir.r4.model.Condition src = new org.hl7.fhir.r4.model.Condition();
91+
Meta meta = new Meta();
92+
meta.setProfile(List.of(new CanonicalType(MEDICATION)));
93+
src.setMeta(meta);
94+
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of(), Set.of());
95+
96+
assertThatThrownBy(() -> integrationTestSetup.redaction().redact(wrapper)).isInstanceOf(RuntimeException.class)
97+
.hasMessage("Resource is missing required profiles: [" + DIAGNOSIS + "]");
98+
}
99+
100+
@Test
101+
public void unknownProfile() {
102+
org.hl7.fhir.r4.model.Condition src = new org.hl7.fhir.r4.model.Condition();
103+
Meta meta = new Meta();
104+
meta.setProfile(List.of(new CanonicalType("UnknownProfile")));
105+
src.setMeta(meta);
106+
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of("UnknownProfile"), Map.of(), Set.of());
107+
108+
assertThatThrownBy(() -> integrationTestSetup.redaction().redact(wrapper)).isInstanceOf(RuntimeException.class)
109+
.hasMessage("Trying to handle unknown profiles: [UnknownProfile]");
110+
}
111+
112+
@Test
113+
public void metaMissing() {
114+
org.hl7.fhir.r4.model.Condition src = new org.hl7.fhir.r4.model.Condition();
115+
116+
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of(), Set.of());
117+
assertThatThrownBy(() -> integrationTestSetup.redaction().redact(wrapper)).isInstanceOf(RuntimeException.class);
118+
}
119+
85120
@Test
86121
public void unknownSlice() throws IOException {
87-
DomainResource expected = integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + "unknownSlice.json");
122+
Condition expected = (Condition) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + "unknownSlice.json");
88123
org.hl7.fhir.r4.model.Condition src = new org.hl7.fhir.r4.model.Condition();
89124
Meta meta = new Meta();
90125
meta.setProfile(List.of(new CanonicalType(DIAGNOSIS)));
@@ -94,6 +129,35 @@ public void unknownSlice() throws IOException {
94129
concept.setCoding(List.of(code));
95130
src.setCode(concept);
96131

132+
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of(), Set.of());
133+
DomainResource tgt = (Condition) integrationTestSetup.redaction().redact(wrapper);
134+
135+
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
136+
}
137+
138+
@ParameterizedTest
139+
@ValueSource(strings = {"DiagnosisWithExtensionAtCodeWithUnknownField.json"})
140+
void notHandlingUnknownElementID(String resource) throws IOException {
141+
142+
Condition src = (Condition) integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
143+
Condition expected = (Condition) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
144+
145+
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of("Condition.subject", Set.of("Patient/12345", "Patient/123"), "Condition.encounter", Set.of("Encounter/12345")), Set.of());
146+
DomainResource tgt = (Condition) integrationTestSetup.redaction().redact(wrapper);
147+
148+
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
149+
150+
151+
}
152+
153+
@Test
154+
public void emptyValues() throws IOException {
155+
Condition expected = (Condition) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + "EmptyValues.json");
156+
org.hl7.fhir.r4.model.Condition src = new org.hl7.fhir.r4.model.Condition();
157+
Meta meta = new Meta();
158+
meta.setProfile(List.of(new CanonicalType(DIAGNOSIS)));
159+
src.setMeta(meta);
160+
97161
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of(), Set.of());
98162
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
99163

@@ -103,11 +167,11 @@ public void unknownSlice() throws IOException {
103167
@ParameterizedTest
104168
@ValueSource(strings = {"DiagnosisUnknownPrimitiveExtension.json", "DiagnosisWithExtensionAtCode.json", "DiagnosisUnknownComplexExtension.json"})
105169
void removeUnknownPrimitiveAndComplexExtension(String resource) throws IOException {
106-
DomainResource src = integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
107-
DomainResource expected = integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
170+
Condition src = (Condition) integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
171+
Condition expected = (Condition) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
108172

109173
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of("Condition.subject", Set.of("Patient/12345", "Patient/123"), "Condition.encounter", Set.of("Encounter/12345")), Set.of());
110-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
174+
DomainResource tgt = (Condition) integrationTestSetup.redaction().redact(wrapper);
111175

112176
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
113177
}
@@ -130,7 +194,7 @@ public void backboneElementHandling() {
130194

131195

132196
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(medication, Set.of(MEDICATION), Map.of(), Set.of());
133-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
197+
DomainResource tgt = (Medication) integrationTestSetup.redaction().redact(wrapper);
134198

135199
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expectedMedication));
136200
}
@@ -153,58 +217,58 @@ public void patient() {
153217
expectedPatient.setIdentifier(List.of(identifier));
154218

155219
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(patient, Set.of(PATIENT), Map.of(), Set.of());
156-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
220+
DomainResource tgt = (Patient) integrationTestSetup.redaction().redact(wrapper);
157221

158222
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expectedPatient));
159223
}
160224

161225
@Nested
162-
class Condition {
226+
class ConditionTest {
163227

164228
@ParameterizedTest
165229
@ValueSource(strings = {"Condition-mii-exa-diagnose-condition-minimal.json", "Condition-mii-exa-diagnose-mehrfachkodierung-primaercode.json", "Condition-mii-exa-diagnose-mehrfachkodierung-primaercode.json", "Condition-mii-exa-diagnose-multiple-kodierungen.json", "Condition-mii-exa-test-data-patient-1-diagnose-1.json", "Condition-mii-exa-test-data-patient-1-diagnose-2.json", "Condition-mii-exa-test-data-patient-3-diagnose-1.json", "Condition-mii-exa-test-data-patient-4-diagnose-1.json"})
166-
void diagnosisAllValid(String resource) throws IOException {
167-
DomainResource src = integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
168-
DomainResource expected = integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
230+
void diagnosisNoChange(String resource) throws IOException {
231+
Condition src = (Condition) integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
232+
Condition expected = (Condition) integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
169233

170234
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of("Condition.subject", Set.of("Patient/12345", "Patient/mii-exa-test-data-patient-1", "Patient/mii-exa-test-data-patient-3"), "Condition.encounter", Set.of("Encounter/12345")), Set.of());
171-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
235+
DomainResource tgt = (Condition) integrationTestSetup.redaction().redact(wrapper);
172236

173237
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
174238
}
175239

176240
@ParameterizedTest
177241
@ValueSource(strings = {"Condition-mii-exa-diagnose-condition-minimal.json", "Condition-mii-exa-diagnose-mehrfachkodierung-primaercode.json"})
178242
void invalidReferences(String resource) throws IOException {
179-
DomainResource src = integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
180-
DomainResource expected = integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
243+
Condition src = (Condition) integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
244+
Condition expected = (Condition) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
181245

182246
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of("Condition.subject", Set.of(), "Condition.encounter", Set.of("Encounter/12345")), Set.of());
183-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
247+
DomainResource tgt = (Condition) integrationTestSetup.redaction().redact(wrapper);
184248

185249
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
186250
}
187251

188252
@ParameterizedTest
189253
@ValueSource(strings = {"DiagnosisWithInvalidSliceCode.json"})
190254
void diagnosisInvalidElements(String resource) throws IOException {
191-
DomainResource src = integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
192-
DomainResource expected = integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
255+
Condition src = (Condition) integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
256+
Condition expected = (Condition) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
193257

194258
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of("Condition.subject", Set.of("Patient/12345"), "Condition.encounter", Set.of("Encounter/12345")), Set.of());
195-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
259+
DomainResource tgt = (Condition) integrationTestSetup.redaction().redact(wrapper);
196260

197261
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
198262
}
199263

200264
@ParameterizedTest
201265
@ValueSource(strings = {"Diagnosis1.json", "Diagnosis2.json"})
202266
void diagnosisMissingElements(String resource) throws IOException {
203-
DomainResource src = integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
204-
DomainResource expected = integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
267+
Condition src = (Condition) integrationTestSetup.readResource(INPUT_CONDITION_DIR + resource);
268+
Condition expected = (Condition) integrationTestSetup.readResource(EXPECTED_OUTPUT_DIR + resource);
205269

206270
ExtractionRedactionWrapper wrapper = new ExtractionRedactionWrapper(src, Set.of(DIAGNOSIS), Map.of("Condition.subject", Set.of("Patient/12345", "Patient/123"), "Condition.encounter", Set.of("Encounter/12345")), Set.of());
207-
DomainResource tgt = (DomainResource) integrationTestSetup.redaction().redact(wrapper);
271+
DomainResource tgt = (Condition) integrationTestSetup.redaction().redact(wrapper);
208272

209273
assertThat(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(tgt)).isEqualTo(fhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expected));
210274
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"resourceType": "Condition",
3+
"id": "mii-exa-diagnose-mehrfachkodierung-primaercode",
4+
"meta": {
5+
"profile": [
6+
"https://www.medizininformatik-initiative.de/fhir/core/modul-diagnose/StructureDefinition/Diagnose"
7+
]
8+
},
9+
"code": {
10+
"coding": [
11+
{
12+
"system": "http://fhir.de/CodeSystem/bfarm/icd-10-gm",
13+
"extension": [
14+
{
15+
"url": "http://fhir.de/StructureDefinition/seitenlokalisation",
16+
"valueCoding": {
17+
"code": "L",
18+
"system": "https://fhir.kbv.de/CodeSystem/KBV_CS_SFHIR_ICD_SEITENLOKALISATION",
19+
"display": "links"
20+
}
21+
},
22+
{
23+
"url": "http://fhir.de/StructureDefinition/icd-10-gm-mehrfachcodierungs-kennzeichen",
24+
"valueCoding": {
25+
"code": "",
26+
"system": "http://fhir.de/CodeSystem/icd-10-gm-mehrfachcodierungs-kennzeichen"
27+
}
28+
}
29+
],
30+
"code": "A54.4",
31+
"version": "2020",
32+
"display": "Gonokokkeninfektion des Muskel-Skelett-Systems"
33+
},
34+
{
35+
"system": "http://fhir.de/CodeSystem/bfarm/alpha-id",
36+
"code": "I97525",
37+
"version": "2020",
38+
"display": "Bursitis gonorrhoica"
39+
}
40+
]
41+
},
42+
"clinicalStatus": {
43+
"coding": [
44+
{
45+
"code": "active",
46+
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
47+
"extension": [
48+
{
49+
"url": "http://fhir.de/StructureDefinition/seitenlokalisation",
50+
"valueCoding": {
51+
"code": "L",
52+
"system": "https://fhir.kbv.de/CodeSystem/KBV_CS_SFHIR_ICD_SEITENLOKALISATION",
53+
"display": "links"
54+
}
55+
}
56+
]
57+
}
58+
]
59+
},
60+
"verificationStatus": {
61+
"coding": [
62+
{
63+
"code": "confirmed",
64+
"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status"
65+
}
66+
]
67+
},
68+
"subject": {
69+
"reference": "Patient/12345"
70+
},
71+
"encounter": {
72+
"reference": "Encounter/12345"
73+
},
74+
"onsetPeriod": {
75+
"start": "2019-09-26T12:45:00+01:00",
76+
"end": "2020-03-25T13:00:00+01:00"
77+
},
78+
"recordedDate": "2020-01-05T12:53:00+01:00"
79+
}

0 commit comments

Comments
 (0)