Fix expansion for `ValueSet` with no concepts based on CodeSystem `urn:ietf:bcp:13` (#5638)
* When fetching the mimetype code system, return empty CodeSystem with NOTSUPPORTED content. Update expansion logic to handle this case. Add some test cases. * Minor change to fix test * Rename changelog file * Remove TODOs as they're replaced by reported issue * Revert accidental change added with TODO removal
This commit is contained in:
parent
d3876c546f
commit
c7fd015195
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 5634
|
||||||
|
title: "Previously, expanding a 'ValueSet' with no concepts based on system `urn:ietf:bcp:13` would fail with
|
||||||
|
`ExpansionCouldNotBeCompletedInternallyException`. This has been fixed."
|
|
@ -29,6 +29,7 @@ import org.hl7.fhir.convertors.factory.VersionConvertorFactory_43_50;
|
||||||
import org.hl7.fhir.dstu2.model.ValueSet;
|
import org.hl7.fhir.dstu2.model.ValueSet;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
|
import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -428,21 +429,27 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBaseResource fetchCodeSystem(String theSystem) {
|
public IBaseResource fetchCodeSystem(String theSystem) {
|
||||||
|
final CodeSystemContentMode content;
|
||||||
Map<String, String> map;
|
Map<String, String> map;
|
||||||
switch (defaultString(theSystem)) {
|
switch (defaultString(theSystem)) {
|
||||||
case COUNTRIES_CODESYSTEM_URL:
|
case COUNTRIES_CODESYSTEM_URL:
|
||||||
map = ISO_3166_CODES;
|
map = ISO_3166_CODES;
|
||||||
|
content = CodeSystemContentMode.COMPLETE;
|
||||||
break;
|
break;
|
||||||
case CURRENCIES_CODESYSTEM_URL:
|
case CURRENCIES_CODESYSTEM_URL:
|
||||||
map = ISO_4217_CODES;
|
map = ISO_4217_CODES;
|
||||||
|
content = CodeSystemContentMode.COMPLETE;
|
||||||
|
break;
|
||||||
|
case MIMETYPES_CODESYSTEM_URL:
|
||||||
|
map = Collections.emptyMap();
|
||||||
|
content = CodeSystemContentMode.NOTPRESENT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeSystem retVal = new CodeSystem();
|
CodeSystem retVal = new CodeSystem();
|
||||||
retVal.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
|
retVal.setContent(content);
|
||||||
retVal.setUrl(theSystem);
|
retVal.setUrl(theSystem);
|
||||||
for (Map.Entry<String, String> nextEntry : map.entrySet()) {
|
for (Map.Entry<String, String> nextEntry : map.entrySet()) {
|
||||||
retVal.addConcept().setCode(nextEntry.getKey()).setDisplay(nextEntry.getValue());
|
retVal.addConcept().setCode(nextEntry.getKey()).setDisplay(nextEntry.getValue());
|
||||||
|
|
|
@ -745,13 +745,6 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
|
||||||
return expandValueSetR5(theValidationSupportContext, input, theWantSystemUrlAndVersion, theWantCode);
|
return expandValueSetR5(theValidationSupportContext, input, theWantSystemUrlAndVersion, theWantCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private org.hl7.fhir.r5.model.ValueSet expandValueSetR5(
|
|
||||||
ValidationSupportContext theValidationSupportContext, org.hl7.fhir.r5.model.ValueSet theInput)
|
|
||||||
throws ExpansionCouldNotBeCompletedInternallyException {
|
|
||||||
return expandValueSetR5(theValidationSupportContext, theInput, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private org.hl7.fhir.r5.model.ValueSet expandValueSetR5(
|
private org.hl7.fhir.r5.model.ValueSet expandValueSetR5(
|
||||||
ValidationSupportContext theValidationSupportContext,
|
ValidationSupportContext theValidationSupportContext,
|
||||||
|
@ -909,20 +902,25 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
|
||||||
|
|
||||||
includeOrExcludeSystemResource = codeSystemLoader.apply(loadedCodeSystemUrl);
|
includeOrExcludeSystemResource = codeSystemLoader.apply(loadedCodeSystemUrl);
|
||||||
|
|
||||||
Set<String> wantCodes;
|
boolean isIncludeWithDeclaredConcepts = !theInclude.getConcept().isEmpty();
|
||||||
if (theInclude.getConcept().isEmpty()) {
|
|
||||||
wantCodes = null;
|
final Set<String> wantCodes;
|
||||||
|
if (isIncludeWithDeclaredConcepts) {
|
||||||
|
wantCodes = theInclude.getConcept().stream()
|
||||||
|
.map(org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent::getCode)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
} else {
|
} else {
|
||||||
wantCodes =
|
wantCodes = null;
|
||||||
theInclude.getConcept().stream().map(t -> t.getCode()).collect(Collectors.toSet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean ableToHandleCode = false;
|
boolean ableToHandleCode = false;
|
||||||
String failureMessage = null;
|
String failureMessage = null;
|
||||||
FailureType failureType = FailureType.OTHER;
|
FailureType failureType = FailureType.OTHER;
|
||||||
|
|
||||||
if (includeOrExcludeSystemResource == null
|
boolean isIncludeCodeSystemIgnored = includeOrExcludeSystemResource != null
|
||||||
|| includeOrExcludeSystemResource.getContent() == Enumerations.CodeSystemContentMode.NOTPRESENT) {
|
&& includeOrExcludeSystemResource.getContent() == Enumerations.CodeSystemContentMode.NOTPRESENT;
|
||||||
|
|
||||||
|
if (includeOrExcludeSystemResource == null || isIncludeCodeSystemIgnored) {
|
||||||
|
|
||||||
if (theWantCode != null) {
|
if (theWantCode != null) {
|
||||||
if (theValidationSupportContext
|
if (theValidationSupportContext
|
||||||
|
@ -971,7 +969,7 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
|
||||||
// If the ValueSet.compose.include has no individual concepts in it, and
|
// If the ValueSet.compose.include has no individual concepts in it, and
|
||||||
// we can't find the actual referenced CodeSystem, we have no choice
|
// we can't find the actual referenced CodeSystem, we have no choice
|
||||||
// but to fail
|
// but to fail
|
||||||
if (!theInclude.getConcept().isEmpty()) {
|
if (isIncludeWithDeclaredConcepts) {
|
||||||
ableToHandleCode = true;
|
ableToHandleCode = true;
|
||||||
} else {
|
} else {
|
||||||
failureMessage = getFailureMessageForMissingOrUnusableCodeSystem(
|
failureMessage = getFailureMessageForMissingOrUnusableCodeSystem(
|
||||||
|
@ -998,15 +996,22 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isNotBlank(theInclude.getSystem())
|
boolean isIncludeFromSystem = isNotBlank(theInclude.getSystem())
|
||||||
&& !theInclude.getConcept().isEmpty()
|
&& theInclude.getValueSet().isEmpty();
|
||||||
&& theInclude.getFilter().isEmpty()
|
boolean isIncludeWithFilter = !theInclude.getFilter().isEmpty();
|
||||||
&& theInclude.getValueSet().isEmpty()) {
|
if (isIncludeFromSystem && !isIncludeWithFilter) {
|
||||||
|
if (isIncludeWithDeclaredConcepts) {
|
||||||
theInclude.getConcept().stream()
|
theInclude.getConcept().stream()
|
||||||
.map(t -> new FhirVersionIndependentConcept(
|
.map(t -> new FhirVersionIndependentConcept(
|
||||||
theInclude.getSystem(), t.getCode(), t.getDisplay(), theInclude.getVersion()))
|
theInclude.getSystem(),
|
||||||
.forEach(t -> nextCodeList.add(t));
|
t.getCode(),
|
||||||
|
t.getDisplay(),
|
||||||
|
theInclude.getVersion()))
|
||||||
|
.forEach(nextCodeList::add);
|
||||||
ableToHandleCode = true;
|
ableToHandleCode = true;
|
||||||
|
} else if (isIncludeCodeSystemIgnored) {
|
||||||
|
ableToHandleCode = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ableToHandleCode) {
|
if (!ableToHandleCode) {
|
||||||
|
|
|
@ -3,16 +3,24 @@ package org.hl7.fhir.common.hapi.validation.support;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.support.ConceptValidationOptions;
|
import ca.uhn.fhir.context.support.ConceptValidationOptions;
|
||||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||||
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
|
||||||
import ca.uhn.fhir.context.support.LookupCodeRequest;
|
import ca.uhn.fhir.context.support.LookupCodeRequest;
|
||||||
|
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
||||||
import ca.uhn.fhir.fhirpath.BaseValidationTestWithInlineMocks;
|
import ca.uhn.fhir.fhirpath.BaseValidationTestWithInlineMocks;
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
|
import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
import org.hl7.fhir.r5.model.Enumerations;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
|
import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.MIMETYPES_CODESYSTEM_URL;
|
||||||
|
import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.MIMETYPES_VALUESET_URL;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
@ -134,6 +142,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW
|
||||||
@Test
|
@Test
|
||||||
public void testLanguages_CommonLanguagesVs_OnlyLanguage_NoRegion() {
|
public void testLanguages_CommonLanguagesVs_OnlyLanguage_NoRegion() {
|
||||||
IValidationSupport.LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "nl"));
|
IValidationSupport.LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "nl"));
|
||||||
|
assertNotNull(nl);
|
||||||
assertTrue(nl.isFound());
|
assertTrue(nl.isFound());
|
||||||
assertEquals("Dutch", nl.getCodeDisplay());
|
assertEquals("Dutch", nl.getCodeDisplay());
|
||||||
}
|
}
|
||||||
|
@ -141,6 +150,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW
|
||||||
@Test
|
@Test
|
||||||
public void testLanguages_CommonLanguagesVs_LanguageAndRegion() {
|
public void testLanguages_CommonLanguagesVs_LanguageAndRegion() {
|
||||||
IValidationSupport.LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "nl-NL"));
|
IValidationSupport.LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "nl-NL"));
|
||||||
|
assertNotNull(nl);
|
||||||
assertTrue(nl.isFound());
|
assertTrue(nl.isFound());
|
||||||
assertEquals("Dutch Netherlands", nl.getCodeDisplay());
|
assertEquals("Dutch Netherlands", nl.getCodeDisplay());
|
||||||
}
|
}
|
||||||
|
@ -190,6 +200,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW
|
||||||
CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL);
|
CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL);
|
||||||
assert cs != null;
|
assert cs != null;
|
||||||
assertEquals(498, cs.getConcept().size());
|
assertEquals(498, cs.getConcept().size());
|
||||||
|
assertEquals(CodeSystemContentMode.COMPLETE, cs.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -198,6 +209,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW
|
||||||
org.hl7.fhir.dstu3.model.CodeSystem cs = (org.hl7.fhir.dstu3.model.CodeSystem) svc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL);
|
org.hl7.fhir.dstu3.model.CodeSystem cs = (org.hl7.fhir.dstu3.model.CodeSystem) svc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL);
|
||||||
assert cs != null;
|
assert cs != null;
|
||||||
assertEquals(498, cs.getConcept().size());
|
assertEquals(498, cs.getConcept().size());
|
||||||
|
assertEquals(org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode.COMPLETE, cs.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -206,6 +218,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW
|
||||||
org.hl7.fhir.r5.model.CodeSystem cs = (org.hl7.fhir.r5.model.CodeSystem) svc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL);
|
org.hl7.fhir.r5.model.CodeSystem cs = (org.hl7.fhir.r5.model.CodeSystem) svc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL);
|
||||||
assert cs != null;
|
assert cs != null;
|
||||||
assertEquals(498, cs.getConcept().size());
|
assertEquals(498, cs.getConcept().size());
|
||||||
|
assertEquals(Enumerations.CodeSystemContentMode.COMPLETE, cs.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -216,10 +229,11 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFetchCodeSystemBuiltIn_Iso_R4() {
|
public void testFetchCodeSystemBuiltIn_Iso4217_R4() {
|
||||||
CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(CommonCodeSystemsTerminologyService.CURRENCIES_CODESYSTEM_URL);
|
CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(CommonCodeSystemsTerminologyService.CURRENCIES_CODESYSTEM_URL);
|
||||||
assert cs != null;
|
assert cs != null;
|
||||||
assertEquals(182, cs.getConcept().size());
|
assertEquals(182, cs.getConcept().size());
|
||||||
|
assertEquals(CodeSystemContentMode.COMPLETE, cs.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -239,6 +253,120 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFetchCodeSystem_withMimeType_returnsOk() {
|
||||||
|
CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(MIMETYPES_CODESYSTEM_URL);
|
||||||
|
assertNotNull(cs);
|
||||||
|
assertTrue(cs.getConcept().isEmpty());
|
||||||
|
assertEquals(CodeSystemContentMode.NOTPRESENT, cs.getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = { EncodingEnum.JSON_PLAIN_STRING, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_JSON })
|
||||||
|
public void testValidateCode_withMimetypesValueSetWithStandardCode_returnsValid(String code) {
|
||||||
|
// test
|
||||||
|
IValidationSupport.CodeValidationResult result = mySvc.validateCode(newSupport(), newOptions(), MIMETYPES_CODESYSTEM_URL, code, null, MIMETYPES_VALUESET_URL);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(code, result.getCode());
|
||||||
|
assertTrue(result.isOk());
|
||||||
|
assertNull(result.getSeverity());
|
||||||
|
assertNull(result.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = { EncodingEnum.JSON_PLAIN_STRING, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_JSON })
|
||||||
|
public void testValidateCode_withMimetypesValueSetWithInferSystemWithStandardCode_returnsValid(String code) {
|
||||||
|
// test
|
||||||
|
IValidationSupport.CodeValidationResult result = mySvc.validateCode(newSupport(), newOptions().setInferSystem(true), null, code, null, MIMETYPES_VALUESET_URL);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(code, result.getCode());
|
||||||
|
assertTrue(result.isOk());
|
||||||
|
assertNull(result.getSeverity());
|
||||||
|
assertNull(result.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = { EncodingEnum.JSON_PLAIN_STRING, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_JSON })
|
||||||
|
public void testValidateCode_withMimetypesWithStandardCode_returnsValid(String code) {
|
||||||
|
// test
|
||||||
|
IValidationSupport.CodeValidationResult result = mySvc.validateCode(newSupport(), newOptions(), MIMETYPES_CODESYSTEM_URL, code, null, null);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(code, result.getCode());
|
||||||
|
assertTrue(result.isOk());
|
||||||
|
assertNull(result.getSeverity());
|
||||||
|
assertNull(result.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateCode_withMimetypeValueSetWithArbitraryCode_returnsValid() {
|
||||||
|
// setup
|
||||||
|
final String code = "someCode";
|
||||||
|
final String display = "displayValue";
|
||||||
|
|
||||||
|
// test
|
||||||
|
IValidationSupport.CodeValidationResult result = mySvc.validateCode(newSupport(), newOptions(), MIMETYPES_CODESYSTEM_URL, code, display, MIMETYPES_VALUESET_URL);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(code, result.getCode());
|
||||||
|
assertTrue(result.isOk());
|
||||||
|
assertEquals(display, result.getDisplay());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateCode_withMimetypesWithArbitraryCode_returnsValid() {
|
||||||
|
// setup
|
||||||
|
final String code = "someCode";
|
||||||
|
final String display = "displayValue";
|
||||||
|
|
||||||
|
// test
|
||||||
|
IValidationSupport.CodeValidationResult result = mySvc.validateCode(newSupport(), newOptions(), MIMETYPES_CODESYSTEM_URL, code, display, null);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(code, result.getCode());
|
||||||
|
assertTrue(result.isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = { EncodingEnum.JSON_PLAIN_STRING, Constants.FORMAT_TURTLE, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_JSON })
|
||||||
|
public void testLookupCode_withMimetypesWithStandardCode_returnFound(String code) {
|
||||||
|
// setup
|
||||||
|
final String system = MIMETYPES_CODESYSTEM_URL;
|
||||||
|
|
||||||
|
// test
|
||||||
|
IValidationSupport.LookupCodeResult result = mySvc.lookupCode(newSupport(), new LookupCodeRequest(system, code));
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(system, result.getSearchedForSystem());
|
||||||
|
assertEquals(code, result.getSearchedForCode());
|
||||||
|
assertTrue(result.isFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLookupCode_withMimetypesWithArbitraryCode_returnsFound() {
|
||||||
|
// setup
|
||||||
|
final String system = MIMETYPES_CODESYSTEM_URL;
|
||||||
|
final String code = "someCode";
|
||||||
|
|
||||||
|
// test
|
||||||
|
IValidationSupport.LookupCodeResult result = mySvc.lookupCode(newSupport(), new LookupCodeRequest(system, code));
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(system, result.getSearchedForSystem());
|
||||||
|
assertEquals(code, result.getSearchedForCode());
|
||||||
|
assertTrue(result.isFound());
|
||||||
|
assertNull(result.getCodeDisplay());
|
||||||
|
}
|
||||||
|
|
||||||
private ValidationSupportContext newSupport() {
|
private ValidationSupportContext newSupport() {
|
||||||
return new ValidationSupportContext(myCtx.getValidationSupport());
|
return new ValidationSupportContext(myCtx.getValidationSupport());
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -33,10 +31,8 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class InMemoryTerminologyServerValidationSupportTest extends BaseValidationTestWithInlineMocks {
|
public class InMemoryTerminologyServerValidationSupportTest extends BaseValidationTestWithInlineMocks {
|
||||||
|
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(InMemoryTerminologyServerValidationSupportTest.class);
|
|
||||||
private InMemoryTerminologyServerValidationSupport mySvc;
|
private InMemoryTerminologyServerValidationSupport mySvc;
|
||||||
private FhirContext myCtx = FhirContext.forR4();
|
private final FhirContext myCtx = FhirContext.forR4();
|
||||||
private DefaultProfileValidationSupport myDefaultSupport;
|
private DefaultProfileValidationSupport myDefaultSupport;
|
||||||
private ValidationSupportChain myChain;
|
private ValidationSupportChain myChain;
|
||||||
private PrePopulatedValidationSupport myPrePopulated;
|
private PrePopulatedValidationSupport myPrePopulated;
|
||||||
|
@ -54,8 +50,153 @@ public class InMemoryTerminologyServerValidationSupportTest extends BaseValidati
|
||||||
myDefaultSupport.fetchCodeSystem("http://foo");
|
myDefaultSupport.fetchCodeSystem("http://foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {
|
||||||
|
CommonCodeSystemsTerminologyService.MIMETYPES_VALUESET_URL,
|
||||||
|
CommonCodeSystemsTerminologyService.CURRENCIES_VALUESET_URL,
|
||||||
|
CommonCodeSystemsTerminologyService.LANGUAGES_VALUESET_URL
|
||||||
|
})
|
||||||
|
public void testExpandValueSet_commonVS_expandOk(String theValueSet) {
|
||||||
|
ValueSet vs = (ValueSet) myChain.fetchValueSet(theValueSet);
|
||||||
|
assertNotNull(vs);
|
||||||
|
|
||||||
|
ValidationSupportContext valCtx = new ValidationSupportContext(myChain);
|
||||||
|
|
||||||
|
IValidationSupport.ValueSetExpansionOutcome expansion = mySvc.expandValueSet(valCtx, new ValueSetExpansionOptions(), vs);
|
||||||
|
assertNotNull(expansion);
|
||||||
|
assertNull(expansion.getError());
|
||||||
|
ValueSet valueSet = (ValueSet) expansion.getValueSet();
|
||||||
|
assertNotNull(valueSet);
|
||||||
|
assertNotNull(valueSet.getExpansion());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {
|
||||||
|
CommonCodeSystemsTerminologyService.MIMETYPES_CODESYSTEM_URL,
|
||||||
|
CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL,
|
||||||
|
CommonCodeSystemsTerminologyService.CURRENCIES_CODESYSTEM_URL
|
||||||
|
})
|
||||||
|
public void testExpandValueSet_customVSBasedOnCommonCS_expandOk(String theCodeSystem) {
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
vs.setId("mimetype");
|
||||||
|
vs.setUrl("http://example.com/mimetype");
|
||||||
|
vs.setVersion("1.0");
|
||||||
|
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||||
|
ValueSet.ConceptSetComponent vsInclude = vs.getCompose().addInclude();
|
||||||
|
vsInclude.setSystem(theCodeSystem);
|
||||||
|
myPrePopulated.addValueSet(vs);
|
||||||
|
|
||||||
|
vs = (ValueSet) myChain.fetchValueSet(vs.getUrl());
|
||||||
|
assertNotNull(vs);
|
||||||
|
|
||||||
|
ValidationSupportContext valCtx = new ValidationSupportContext(myChain);
|
||||||
|
|
||||||
|
IValidationSupport.ValueSetExpansionOutcome expansion = mySvc.expandValueSet(valCtx, new ValueSetExpansionOptions(), vs);
|
||||||
|
assertNotNull(expansion);
|
||||||
|
assertNull(expansion.getError());
|
||||||
|
ValueSet valueSet = (ValueSet) expansion.getValueSet();
|
||||||
|
assertNotNull(valueSet);
|
||||||
|
assertNotNull(valueSet.getExpansion());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateCodeWithInferredSystem_CommonCodeSystemsCs_BuiltInVs() {
|
public void testValidateCode_mimetypeVSRandomCode_returnsOk() {
|
||||||
|
final String codeSystem = CommonCodeSystemsTerminologyService.MIMETYPES_CODESYSTEM_URL;
|
||||||
|
final String valueSetUrl = CommonCodeSystemsTerminologyService.MIMETYPES_VALUESET_URL;
|
||||||
|
|
||||||
|
final String code = "someRandomCode";
|
||||||
|
|
||||||
|
ValidationSupportContext valCtx = new ValidationSupportContext(myChain);
|
||||||
|
ConceptValidationOptions options = new ConceptValidationOptions();
|
||||||
|
|
||||||
|
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(valCtx, options, codeSystem, code, null, valueSetUrl);
|
||||||
|
assertNotNull(outcome);
|
||||||
|
assertTrue(outcome.isOk());
|
||||||
|
assertEquals(code, outcome.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateCode_customMimetypeVSRandomCode_returnsOk() {
|
||||||
|
final String codeSystem = CommonCodeSystemsTerminologyService.MIMETYPES_CODESYSTEM_URL;
|
||||||
|
final String code = "someRandomCode";
|
||||||
|
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
vs.setId("mimetype");
|
||||||
|
vs.setUrl("http://example.com/mimetype");
|
||||||
|
vs.setVersion("1.0");
|
||||||
|
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||||
|
ValueSet.ConceptSetComponent vsInclude = vs.getCompose().addInclude();
|
||||||
|
vsInclude.setSystem(codeSystem);
|
||||||
|
myPrePopulated.addValueSet(vs);
|
||||||
|
|
||||||
|
ValidationSupportContext valCtx = new ValidationSupportContext(myChain);
|
||||||
|
ConceptValidationOptions options = new ConceptValidationOptions();
|
||||||
|
|
||||||
|
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(valCtx, options, codeSystem, code, null, vs.getUrl());
|
||||||
|
assertNotNull(outcome);
|
||||||
|
assertTrue(outcome.isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateCode_customMimetypeVSCodeInVS_returnsOk() {
|
||||||
|
String codeSystem = CommonCodeSystemsTerminologyService.MIMETYPES_CODESYSTEM_URL;
|
||||||
|
|
||||||
|
final String code = "someRandomCode";
|
||||||
|
final String display = "Display " + code;
|
||||||
|
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
vs.setId("example-vs");
|
||||||
|
vs.setUrl("http://example.com/example-vs");
|
||||||
|
vs.setVersion("1.0");
|
||||||
|
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||||
|
ValueSet.ConceptSetComponent vsInclude = vs.getCompose().addInclude();
|
||||||
|
vsInclude.setSystem(codeSystem);
|
||||||
|
vsInclude.addConcept().setCode(code).setDisplay(display);
|
||||||
|
myPrePopulated.addValueSet(vs);
|
||||||
|
|
||||||
|
ValidationSupportContext valCtx = new ValidationSupportContext(myChain);
|
||||||
|
ConceptValidationOptions options = new ConceptValidationOptions();
|
||||||
|
|
||||||
|
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(valCtx, options, codeSystem, code, null, vs.getUrl());
|
||||||
|
assertNotNull(outcome);
|
||||||
|
assertTrue(outcome.isOk());
|
||||||
|
assertEquals(code, outcome.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {
|
||||||
|
CommonCodeSystemsTerminologyService.MIMETYPES_CODESYSTEM_URL,
|
||||||
|
CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL,
|
||||||
|
CommonCodeSystemsTerminologyService.CURRENCIES_VALUESET_URL,
|
||||||
|
CommonCodeSystemsTerminologyService.LANGUAGES_CODESYSTEM_URL,
|
||||||
|
CommonCodeSystemsTerminologyService.UCUM_CODESYSTEM_URL
|
||||||
|
})
|
||||||
|
public void testValidateCode_customMimetypeVSCodeNotInVS_returnsError(String theCodeSystem) {
|
||||||
|
final String code = "someRandomCode";
|
||||||
|
final String codeToValidate = "otherCode";
|
||||||
|
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
vs.setId("mimetype");
|
||||||
|
vs.setUrl("http://example.com/mimetype");
|
||||||
|
vs.setVersion("1.0");
|
||||||
|
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||||
|
ValueSet.ConceptSetComponent vsInclude = vs.getCompose().addInclude();
|
||||||
|
vsInclude.setSystem(theCodeSystem);
|
||||||
|
vsInclude.addConcept().setCode(code).setDisplay("Display " + code);
|
||||||
|
myPrePopulated.addValueSet(vs);
|
||||||
|
|
||||||
|
ValidationSupportContext valCtx = new ValidationSupportContext(myChain);
|
||||||
|
ConceptValidationOptions options = new ConceptValidationOptions();
|
||||||
|
|
||||||
|
IValidationSupport.CodeValidationResult outcome = mySvc.validateCode(valCtx, options, theCodeSystem, codeToValidate, null, vs.getUrl());
|
||||||
|
assertNotNull(outcome);
|
||||||
|
assertFalse(outcome.isOk());
|
||||||
|
assertEquals("Unknown code '" + theCodeSystem + "#" + codeToValidate + "' for in-memory expansion of ValueSet '" + vs.getUrl() + "'", outcome.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateCodeWithInferredSystem_CommonCs_BuiltInVs() {
|
||||||
|
|
||||||
ValidationSupportContext valCtx = new ValidationSupportContext(myChain);
|
ValidationSupportContext valCtx = new ValidationSupportContext(myChain);
|
||||||
ConceptValidationOptions options = new ConceptValidationOptions().setInferSystem(true);
|
ConceptValidationOptions options = new ConceptValidationOptions().setInferSystem(true);
|
||||||
|
@ -279,9 +420,6 @@ public class InMemoryTerminologyServerValidationSupportTest extends BaseValidati
|
||||||
assertEquals(null, outcome.getCodeSystemVersion());
|
assertEquals(null, outcome.getCodeSystemVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExpandValueSet_VsUsesVersionedSystem_CsIsFragmentWithoutCode() {
|
public void testExpandValueSet_VsUsesVersionedSystem_CsIsFragmentWithoutCode() {
|
||||||
CodeSystem cs = new CodeSystem();
|
CodeSystem cs = new CodeSystem();
|
||||||
|
|
Loading…
Reference in New Issue