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:
Martha Mitran 2024-01-29 13:18:40 -08:00 committed by GitHub
parent d3876c546f
commit c7fd015195
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 320 additions and 37 deletions

View File

@ -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."

View File

@ -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());

View File

@ -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) {

View File

@ -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());
} }

View File

@ -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();