diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyService.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyService.java index f3463103853..08819e31abf 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyService.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyService.java @@ -43,6 +43,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; +import static org.apache.commons.lang3.StringUtils.defaultIfBlank; import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -67,13 +68,13 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport { public static final String UCUM_CODESYSTEM_URL = "http://unitsofmeasure.org"; public static final String UCUM_VALUESET_URL = "http://hl7.org/fhir/ValueSet/ucum-units"; public static final String ALL_LANGUAGES_VALUESET_URL = "http://hl7.org/fhir/ValueSet/all-languages"; - private static final String USPS_CODESYSTEM_URL = "https://www.usps.com/"; - private static final String USPS_VALUESET_URL = "http://hl7.org/fhir/us/core/ValueSet/us-core-usps-state"; + public static final String USPS_CODESYSTEM_URL = "https://www.usps.com/"; + public static final String USPS_VALUESET_URL = "http://hl7.org/fhir/us/core/ValueSet/us-core-usps-state"; private static final Logger ourLog = LoggerFactory.getLogger(CommonCodeSystemsTerminologyService.class); private static final Map USPS_CODES = Collections.unmodifiableMap(buildUspsCodes()); private static final Map ISO_4217_CODES = Collections.unmodifiableMap(buildIso4217Codes()); private static final Map ISO_3166_CODES = Collections.unmodifiableMap(buildIso3166Codes()); - private static final Map MIMETYPE_CODES = Collections.unmodifiableMap(buildMimetypeCodes()); + private static final Map BCP_13_CODES = Collections.unmodifiableMap(buildBCP13Codes()); private final FhirContext myFhirContext; private final VersionCanonicalizer myVersionCanonicalizer; private volatile org.hl7.fhir.r5.model.ValueSet myLanguagesVs; @@ -149,7 +150,7 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport { case ALL_LANGUAGES_VALUESET_URL: return validateLanguageCode(theCode, valueSet); case MIMETYPES_VALUESET_URL: - return getValidateCodeResultOk(theCode, defaultString(MIMETYPE_CODES.get(theCode), theDisplay)); + return getValidateCodeResultOk(theCode, defaultIfBlank(BCP_13_CODES.get(theCode), theDisplay)); case UCUM_VALUESET_URL: { return validateLookupCode(theValidationSupportContext, theCode, system); } @@ -252,7 +253,7 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport { } else { // If we get here it means we know the CodeSystem but the code was bad retVal.setFound(false); - String invalidCodeMessage = getErrorMessage("invalidCodeInSystem", system, code); + String invalidCodeMessage = getErrorMessage("invalidCodeInSystem", code, system); retVal.setErrorMessage(invalidCodeMessage); } @@ -386,11 +387,11 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport { mimeRetVal.setSearchedForSystem(MIMETYPES_CODESYSTEM_URL); mimeRetVal.setFound(true); // Set the display when the code is a standard code - mimeRetVal.setCodeDisplay(MIMETYPE_CODES.get(theCode)); + mimeRetVal.setCodeDisplay(BCP_13_CODES.get(theCode)); return mimeRetVal; } - private static Map buildMimetypeCodes() { + private static Map buildBCP13Codes() { ourLog.info("Loading the IANA mimetypes from system " + MIMETYPES_CODESYSTEM_URL); final String configPath = "/org/hl7/fhir/common/hapi/validation/support/mimetype/"; @@ -449,24 +450,20 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport { @Nonnull private LookupCodeResult lookupUcumCode(String theCode) { - InputStream input = ClasspathUtil.loadResourceAsStream("/ucum-essence.xml"); - String outcome; LookupCodeResult retVal = new LookupCodeResult(); retVal.setSearchedForCode(theCode); retVal.setSearchedForSystem(UCUM_CODESYSTEM_URL); - try { + try (InputStream input = ClasspathUtil.loadResourceAsStream("/ucum-essence.xml")) { UcumEssenceService svc = new UcumEssenceService(input); - outcome = svc.analyse(theCode); + String outcome = svc.analyse(theCode); if (outcome != null) { retVal.setFound(true); retVal.setCodeDisplay(outcome); } - } catch (UcumException e) { + } catch (UcumException | IOException e) { ourLog.debug("Failed parse UCUM code: {}", theCode, e); retVal.setErrorMessage(e.getMessage()); - } finally { - ClasspathUtil.close(input); } return retVal; } @@ -486,7 +483,7 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport { map = USPS_CODES; break; case MIMETYPES_CODESYSTEM_URL: - map = MIMETYPE_CODES; + map = BCP_13_CODES; break; default: return null; diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyServiceTest.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyServiceTest.java index 16110010ebd..28b70a6a2cc 100644 --- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyServiceTest.java +++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/common/hapi/validation/support/CommonCodeSystemsTerminologyServiceTest.java @@ -3,6 +3,7 @@ package org.hl7.fhir.common.hapi.validation.support; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.support.ConceptValidationOptions; import ca.uhn.fhir.context.support.IValidationSupport.CodeValidationResult; +import ca.uhn.fhir.context.support.IValidationSupport.IssueSeverity; import ca.uhn.fhir.context.support.IValidationSupport.LookupCodeResult; import ca.uhn.fhir.context.support.LookupCodeRequest; import ca.uhn.fhir.context.support.ValidationSupportContext; @@ -16,12 +17,22 @@ import org.hl7.fhir.r4.model.ValueSet; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import java.util.Map; +import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.ALL_LANGUAGES_VALUESET_URL; +import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.CURRENCIES_CODESYSTEM_URL; +import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.CURRENCIES_VALUESET_URL; +import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.LANGUAGES_CODESYSTEM_URL; +import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.LANGUAGES_VALUESET_URL; 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.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.UCUM_CODESYSTEM_URL; +import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.UCUM_VALUESET_URL; +import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.USPS_CODESYSTEM_URL; +import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.USPS_VALUESET_URL; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -40,208 +51,323 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW mySvc = new CommonCodeSystemsTerminologyService(myCtx); } - @Test - public void testUcum_LookupCode_Good() { - LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://unitsofmeasure.org", "Cel")); - assert outcome != null; + @ParameterizedTest + @CsvSource({"Cel, (degree Celsius)", "kg/m2, (kilogram) / (meter ^ 2)"}) + public void testLookupCode_withUnitsOfMeasureWithKnownCode_returnsFound(final String theCode, final String theDisplay) { + LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest(UCUM_CODESYSTEM_URL, theCode)); + assertNotNull(outcome); assertTrue(outcome.isFound()); + assertEquals(theCode, outcome.getSearchedForCode()); + assertEquals(theDisplay, outcome.getCodeDisplay()); } @Test - public void testUcum_LookupCode_Good2() { - LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://unitsofmeasure.org", "kg/m2")); - assert outcome != null; - assertTrue(outcome.isFound()); - } - - @Test - public void testUcum_LookupCode_Bad() { - LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://unitsofmeasure.org", "AAAAA")); - assert outcome != null; + public void testLookupCode_withUnitsOfMeasureWithUnknownCode_returnsNotFound() { + final String code = "someCode"; + LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest(UCUM_CODESYSTEM_URL, code)); + assertNotNull(outcome); assertFalse(outcome.isFound()); + assertEquals(code, outcome.getSearchedForCode()); + assertEquals("Error processing unit '" + code +"': The unit '" + code + "' is unknown' at position 0", outcome.getErrorMessage()); } @Test - public void testUcum_LookupCode_UnknownSystem() { - LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://foo", "AAAAA")); + public void testLookupCode_withUnknownSystem_returnsNull() { + LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest("http://foo", "someCode")); assertNull(outcome); } - @Test - public void lookupCode_languageOnlyLookup_isCaseInsensitive() { - LookupCodeResult outcomeUpper = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "SGN", "Sign Languages", null)); - LookupCodeResult outcomeLower = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "sgn", "Sign Languages", null)); - assertNotNull(outcomeUpper); - assertNotNull(outcomeLower); - assertTrue(outcomeLower.isFound()); - assertTrue(outcomeUpper.isFound()); + @ParameterizedTest + @CsvSource({"SGN, Sign languages", "sgn, Sign languages", "EN-US, English United States", "en-us, English United States"}) + public void testLookupCode_withLanguageOnlyWithKnownCode_returnsFound(final String theCode, final String theDisplay) { + LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest(CommonCodeSystemsTerminologyService.LANGUAGES_CODESYSTEM_URL, theCode, null, null)); + assertNotNull(outcome); + assertTrue(outcome.isFound()); + assertEquals(theCode, outcome.getSearchedForCode()); + assertEquals(theDisplay, outcome.getCodeDisplay()); } @Test - public void lookupCode_languageAndRegionLookup_isCaseInsensitive() { - LookupCodeResult outcomeUpper = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "EN-US", "English", null)); - LookupCodeResult outcomeLower = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "en-us", "English", null)); - assertNotNull(outcomeUpper); - assertNotNull(outcomeLower); - assertTrue(outcomeLower.isFound()); - assertTrue(outcomeUpper.isFound()); - } - - @Test - public void testUcum_ValidateCode_Good() { - ValueSet vs = new ValueSet(); - vs.setUrl("http://hl7.org/fhir/ValueSet/ucum-units"); - CodeValidationResult outcome = mySvc.validateCodeInValueSet(newSupport(), newOptions(), "http://unitsofmeasure.org", "mg", null, vs); - assert outcome != null; + public void testValidateCode_withUnitsOfMeasureWithKnownCode_returnsValid() { + final String code = "mg"; + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), UCUM_CODESYSTEM_URL, code, null, UCUM_VALUESET_URL); + assertNotNull(outcome); assertTrue(outcome.isOk()); + assertEquals(code, outcome.getCode()); assertEquals("(milligram)", outcome.getDisplay()); } @Test - public void testUcum_ValidateCode_Good_SystemInferred() { - ValueSet vs = new ValueSet(); - vs.setUrl("http://hl7.org/fhir/ValueSet/ucum-units"); - CodeValidationResult outcome = mySvc.validateCodeInValueSet(newSupport(), newOptions().setInferSystem(true), null, "mg", null, vs); - assert outcome != null; + public void testValidateCodeInValueSet_withUnitsOfMeasureWithKnownCode_returnsValid() { + final ValueSet vs = new ValueSet().setUrl(UCUM_VALUESET_URL); + final String code = "mg"; + CodeValidationResult outcome = mySvc.validateCodeInValueSet(newSupport(), newOptions(), UCUM_CODESYSTEM_URL, code, null, vs); + assertNotNull(outcome); assertTrue(outcome.isOk()); + assertEquals(code, outcome.getCode()); assertEquals("(milligram)", outcome.getDisplay()); } @Test - public void testUcum_ValidateCode_Bad() { - ValueSet vs = new ValueSet(); - vs.setUrl("http://hl7.org/fhir/ValueSet/ucum-units"); - CodeValidationResult outcome = mySvc.validateCodeInValueSet(newSupport(), newOptions(), "http://unitsofmeasure.org", "aaaaa", null, vs); + public void testValidateCodeInValueSet_withUnitsOfMeasureWithInferSystem_returnsValid() { + final ValueSet vs = new ValueSet().setUrl(UCUM_VALUESET_URL); + final String code = "mg"; + CodeValidationResult outcome = mySvc.validateCodeInValueSet(newSupport(), newOptions().setInferSystem(true), null, code, null, vs); + assertNotNull(outcome); + assertTrue(outcome.isOk()); + assertEquals(code, outcome.getCode()); + assertEquals("(milligram)", outcome.getDisplay()); + } + + @Test + public void testValidateCodeInValueSet_withUnitsOfMeasureWithUnknownCode_returnsInvalid() { + final String code = "FOO"; + final ValueSet vs = new ValueSet().setUrl(UCUM_VALUESET_URL); + CodeValidationResult outcome = mySvc.validateCodeInValueSet(newSupport(), newOptions(), UCUM_CODESYSTEM_URL, code, null, vs); assertNotNull(outcome); assertFalse(outcome.isOk()); - assertEquals("Error processing unit 'aaaaa': The unit 'aaaaa' is unknown' at position 0", outcome.getMessage()); - assertEquals("error", outcome.getSeverityCode()); + assertEquals(IssueSeverity.ERROR, outcome.getSeverity()); + assertEquals("Error processing unit '" + code +"': The unit '" + code + "' is unknown' at position 0", outcome.getMessage()); } - @Test - public void testLanguagesLanguagesCs_GoodCode() { - CodeValidationResult outcome = mySvc.validateLookupCode(newSupport(), "en-CA", "urn:ietf:bcp:47"); - assert outcome != null; + @ParameterizedTest + @CsvSource({"en-CA, English Canada", "en-US, English United States"}) + public void testValidateLookupCode_withLanguagesWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + CodeValidationResult outcome = mySvc.validateLookupCode(newSupport(), theCode, LANGUAGES_CODESYSTEM_URL); + assertNotNull(outcome); assertTrue(outcome.isOk()); - assertEquals("English Canada", outcome.getDisplay()); + assertEquals(theCode, outcome.getCode()); + assertEquals(theDisplay, outcome.getDisplay()); } - @Test - public void testLanguagesLanguagesCs_BadCode() { - CodeValidationResult outcome = mySvc.validateLookupCode(newSupport(), "en-FOO", "urn:ietf:bcp:47"); - assertNull(outcome); - } - - @Test - public void testLanguages_CommonLanguagesVs_GoodCode() { - CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), "urn:ietf:bcp:47", "en-US", null, "http://hl7.org/fhir/ValueSet/languages"); - assert outcome != null; + @ParameterizedTest + @CsvSource({"en-CA, English (Canada)", "en-US, English (United States)"}) + public void testValidateCode_withLanguagesWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), LANGUAGES_CODESYSTEM_URL, theCode, null, LANGUAGES_VALUESET_URL); + assertNotNull(outcome); assertTrue(outcome.isOk()); - assertEquals("English (United States)", outcome.getDisplay()); + assertEquals(theCode, outcome.getCode()); + assertEquals(theDisplay, outcome.getDisplay()); } @Test - public void testLanguages_CommonLanguagesVs_OnlyLanguage_NoRegion() { - LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "nl")); + public void testValidateCode_withLanguagesWithUnknownCode_returnsInvalid() { + final String code = "FOO"; + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), LANGUAGES_CODESYSTEM_URL, code, null, LANGUAGES_VALUESET_URL); + assertNotNull(outcome); + assertFalse(outcome.isOk()); + assertEquals(IssueSeverity.ERROR, outcome.getSeverity()); + assertEquals("Code \""+ code +"\" is not in valueset: " + LANGUAGES_VALUESET_URL, outcome.getMessage()); + } + + @Test + public void testValidateCode_withLanguagesWithIncorrectSystem_returnsInvalid() { + final String system = "FOO"; + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), system, "en-US", null, LANGUAGES_VALUESET_URL); + assertNotNull(outcome); + assertFalse(outcome.isOk()); + assertEquals(IssueSeverity.ERROR, outcome.getSeverity()); + assertEquals("Inappropriate CodeSystem URL \"" + system + "\" for ValueSet: " + LANGUAGES_VALUESET_URL, outcome.getMessage()); + } + + @ParameterizedTest + @CsvSource({"en-CA, English Canada", "en-US, English United States"}) + public void testValidateCode_withAllLanguagesWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), LANGUAGES_CODESYSTEM_URL, theCode, null, ALL_LANGUAGES_VALUESET_URL); + assertNotNull(outcome); + assertTrue(outcome.isOk()); + assertEquals(theCode, outcome.getCode()); + assertEquals(theDisplay, outcome.getDisplay()); + } + + + @Test + public void testValidateCode_withAllLanguagesWithUnknownCode_returnsInvalid() { + final String code = "FOO"; + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), LANGUAGES_CODESYSTEM_URL, code, null, ALL_LANGUAGES_VALUESET_URL); + assertNotNull(outcome); + assertFalse(outcome.isOk()); + assertEquals(IssueSeverity.ERROR, outcome.getSeverity()); + assertEquals("Code \"" + code + "\" is not in valueset: " + ALL_LANGUAGES_VALUESET_URL, outcome.getMessage()); + } + + @Test + public void testValidateCode_withAllLanguagesWithIncorrectSystem_returnsInvalid() { + final String system = "FOO"; + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), system, "en-US", null, ALL_LANGUAGES_VALUESET_URL); + assertNotNull(outcome); + assertFalse(outcome.isOk()); + assertEquals(IssueSeverity.ERROR, outcome.getSeverity()); + assertEquals("Inappropriate CodeSystem URL \"" + system + "\" for ValueSet: " + ALL_LANGUAGES_VALUESET_URL, outcome.getMessage()); + } + + @ParameterizedTest + @CsvSource({"nl, Dutch", "nl-NL, Dutch Netherlands"}) + public void testLookupCode_withLanguagesWithKnownLanguageOnlyCode_returnsCode(final String theCode, final String theDisplay) { + LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest(LANGUAGES_CODESYSTEM_URL, theCode)); assertTrue(nl != null && nl.isFound()); - assertEquals("Dutch", nl.getCodeDisplay()); + assertEquals(theCode, nl.getSearchedForCode()); + assertEquals(theDisplay, nl.getCodeDisplay()); } @Test - public void testLanguages_CommonLanguagesVs_LanguageAndRegion() { - LookupCodeResult nl = mySvc.lookupCode(newSupport(), new LookupCodeRequest("urn:ietf:bcp:47", "nl-NL")); - assertTrue(nl != null && nl.isFound()); - assertEquals("Dutch Netherlands", nl.getCodeDisplay()); - } - - @Test - public void testLanguages_CommonLanguagesVs_BadCode() { - CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), "urn:ietf:bcp:47", "FOO", null, "http://hl7.org/fhir/ValueSet/languages"); - assert outcome != null; - assertFalse(outcome.isOk()); - assertEquals("Code \"FOO\" is not in valueset: http://hl7.org/fhir/ValueSet/languages", outcome.getMessage()); - } - - @Test - public void testLanguages_CommonLanguagesVs_BadSystem() { - CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), "FOO", "en-US", null, "http://hl7.org/fhir/ValueSet/languages"); - assert outcome != null; - assertFalse(outcome.isOk()); - assertEquals("Inappropriate CodeSystem URL \"FOO\" for ValueSet: http://hl7.org/fhir/ValueSet/languages", outcome.getMessage()); - } - - @Test - public void testLanguages_AllLanguagesVs_GoodCode() { - CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), "urn:ietf:bcp:47", "en-US", null, "http://hl7.org/fhir/ValueSet/all-languages"); - assert outcome != null; - assertTrue(outcome.isOk()); - assertEquals("English United States", outcome.getDisplay()); - } - - @Test - public void testLanguages_AllLanguagesVs_BadCode() { - CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), "urn:ietf:bcp:47", "FOO", null, "http://hl7.org/fhir/ValueSet/all-languages"); - assert outcome != null; - assertFalse(outcome.isOk()); - assertEquals("Code \"FOO\" is not in valueset: http://hl7.org/fhir/ValueSet/all-languages", outcome.getMessage()); - } - - @Test - public void testLanguages_AllLanguagesVs_BadSystem() { - CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), "FOO", "en-US", null, "http://hl7.org/fhir/ValueSet/all-languages"); - assert outcome != null; - assertFalse(outcome.isOk()); - assertEquals("Inappropriate CodeSystem URL \"FOO\" for ValueSet: http://hl7.org/fhir/ValueSet/all-languages", outcome.getMessage()); - } - - @Test - public void testFetchCodeSystemBuiltIn_Iso3166_R4() { - CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL); - assert cs != null; - assertEquals(498, cs.getConcept().size()); - } - - @Test - public void testFetchCodeSystemBuiltIn_Iso3166_DSTU3() { + public void testFetchCodeSystem_withCountriesForDSTU3_returnsOk() { CommonCodeSystemsTerminologyService svc = new CommonCodeSystemsTerminologyService(FhirContext.forDstu3Cached()); org.hl7.fhir.dstu3.model.CodeSystem cs = (org.hl7.fhir.dstu3.model.CodeSystem) svc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL); - assert cs != null; + assertNotNull(cs); assertEquals(498, cs.getConcept().size()); } @Test - public void testFetchCodeSystemBuiltIn_Iso3166_R5() { + public void testFetchCodeSystem_withCountriesForR4_returnsOk() { + CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL); + assertNotNull(cs); + assertEquals(498, cs.getConcept().size()); + } + + @Test + public void testFetchCodeSystem_withCountriesForR5_returnsOk() { CommonCodeSystemsTerminologyService svc = new CommonCodeSystemsTerminologyService(FhirContext.forR5Cached()); org.hl7.fhir.r5.model.CodeSystem cs = (org.hl7.fhir.r5.model.CodeSystem) svc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL); - assert cs != null; + assertNotNull(cs); assertEquals(498, cs.getConcept().size()); } @Test - public void testFetchCodeSystemBuiltIn_Iso3166_DSTU2() { + public void testFetchCodeSystem_withCountriesForDSTU2_returnsOk() { CommonCodeSystemsTerminologyService svc = new CommonCodeSystemsTerminologyService(FhirContext.forDstu2Cached()); IBaseResource cs = svc.fetchCodeSystem(CommonCodeSystemsTerminologyService.COUNTRIES_CODESYSTEM_URL); assertNull(cs); } + @ParameterizedTest + @CsvSource({"WA, Washington", "PR, Puerto Rico"}) + public void testValidateCode_withUSPostalWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), USPS_CODESYSTEM_URL, theCode, null, null); + assertNotNull(outcome); + assertTrue(outcome.isOk()); + assertEquals(theCode, outcome.getCode()); + assertEquals(theDisplay, outcome.getDisplay()); + } + + @ParameterizedTest + @CsvSource({"WA, Washington", "PR, Puerto Rico"}) + public void testValidateCode_withUSPostalValueSetWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), USPS_CODESYSTEM_URL, theCode, null, USPS_VALUESET_URL); + assertNotNull(outcome); + assertTrue(outcome.isOk()); + assertEquals(theCode, outcome.getCode()); + assertEquals(theDisplay, outcome.getDisplay()); + } + @Test - public void testFetchCodeSystemBuiltIn_Iso_R4() { - CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(CommonCodeSystemsTerminologyService.CURRENCIES_CODESYSTEM_URL); - assert cs != null; + public void testValidateCode_withUSPostalValueSetWithUnknownCode_returnsInvalid() { + final String system = USPS_CODESYSTEM_URL; + final String code = "FOO"; + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), system, code, null, USPS_VALUESET_URL); + assertNotNull(outcome); + assertFalse(outcome.isOk()); + assertEquals(IssueSeverity.ERROR, outcome.getSeverity()); + assertEquals("Unknown code \"" + system + "#" + code + "\"", outcome.getMessage()); + } + + @ParameterizedTest + @CsvSource({"WA, Washington", "PR, Puerto Rico"}) + public void testLookupCode_withUSPostalWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest(USPS_CODESYSTEM_URL, theCode)); + assertNotNull(outcome); + assertTrue(outcome.isFound()); + assertEquals(theCode, outcome.getSearchedForCode()); + assertEquals(theDisplay, outcome.getCodeDisplay()); + } + + @Test + public void testLookupCode_withUSPostalWithUnknownCode_returnsNotFound() { + final String system = USPS_CODESYSTEM_URL; + final String code = "FOO"; + LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest(system, code)); + assertNotNull(outcome); + assertFalse(outcome.isFound()); + assertEquals(code, outcome.getSearchedForCode()); + assertEquals("Code " + code + " is not valid for system: " + system, outcome.getErrorMessage()); + } + + @ParameterizedTest + @CsvSource({"USD, United States dollar", "CAD, Canadian dollar", "EUR, Euro"}) + public void testValidateCode_withCurrenciesWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), CURRENCIES_CODESYSTEM_URL, theCode, null, null); + assertNotNull(outcome); + assertTrue(outcome.isOk()); + assertEquals(theCode, outcome.getCode()); + assertEquals(theDisplay, outcome.getDisplay()); + } + + @ParameterizedTest + @CsvSource({"USD, United States dollar", "CAD, Canadian dollar", "EUR, Euro"}) + public void testValidateCode_withCurrenciesValueSetWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), CURRENCIES_CODESYSTEM_URL, theCode, null, CURRENCIES_VALUESET_URL); + assertNotNull(outcome); + assertTrue(outcome.isOk()); + assertEquals(theCode, outcome.getCode()); + assertEquals(theDisplay, outcome.getDisplay()); + } + + @Test + public void testValidateCode_withCurrenciesValueSetWithUnknownCode_returnsInvalid() { + final String system = CURRENCIES_CODESYSTEM_URL; + final String code = "FOO"; + CodeValidationResult outcome = mySvc.validateCode(newSupport(), newOptions(), system, code, null, CURRENCIES_VALUESET_URL); + assertNotNull(outcome); + assertFalse(outcome.isOk()); + assertEquals(IssueSeverity.ERROR, outcome.getSeverity()); + assertEquals("Unknown code \"" + system + "#" + code + "\"", outcome.getMessage()); + } + + @ParameterizedTest + @CsvSource({"USD, United States dollar", "CAD, Canadian dollar", "EUR, Euro"}) + public void testLookupCode_withCurrenciesWithKnownCode_returnsValid(final String theCode, final String theDisplay) { + LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest(CURRENCIES_CODESYSTEM_URL, theCode)); + assertNotNull(outcome); + assertTrue(outcome.isFound()); + assertEquals(theCode, outcome.getSearchedForCode()); + assertEquals(theDisplay, outcome.getCodeDisplay()); + } + + @Test + public void testLookupCode_withCurrenciesWithUnknownCode_returnsNotFound() { + final String system = CURRENCIES_CODESYSTEM_URL; + final String code = "FOO"; + LookupCodeResult outcome = mySvc.lookupCode(newSupport(), new LookupCodeRequest(system, code)); + assertNotNull(outcome); + assertFalse(outcome.isFound()); + assertEquals(code, outcome.getSearchedForCode()); + assertEquals("Code " + code + " is not valid for system: " + system, outcome.getErrorMessage()); + } + + @Test + public void testFetchCodeSystem_withUSPostalCodes_returnsOk() { + CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(USPS_CODESYSTEM_URL); + assertNotNull(cs); + assertEquals(60, cs.getConcept().size()); + } + + @Test + public void testFetchCodeSystem_withCurrencies_returnsOk() { + CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(CURRENCIES_CODESYSTEM_URL); + assertNotNull(cs); assertEquals(182, cs.getConcept().size()); } @Test - public void testFetchCodeSystemBuiltIn_Unknown() { + public void testFetchCodeSystem_withUnknownSystem_returnsNull() { CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem("http://foo"); assertNull(cs); } @Test - public void testFetchCodeSystemUrlDstu3() { + public void testGetCodeSystemUrl_forDSTU3_throwsException() { try { CommonCodeSystemsTerminologyService.getCodeSystemUrl(myCtx, new org.hl7.fhir.dstu3.model.CodeSystem()); - fail(); } catch (IllegalArgumentException e) { assertEquals(Msg.code(696) + "Can not handle version: DSTU3", e.getMessage()); @@ -249,7 +375,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW } @Test - public void testGetMimetypesFromFile_withValidFormat_returnsResult() { + public void testGetMimetypesFromFile_withValidFormat_returnsOk() { Map mimetypeMap = CommonCodeSystemsTerminologyService.getMimetypesFromFile("/org/hl7/fhir/common/hapi/validation/support/mimetype-test/test-valid.csv"); assertFalse(mimetypeMap.isEmpty()); assertEquals(3, mimetypeMap.size()); @@ -260,13 +386,13 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW "/org/hl7/fhir/common/hapi/validation/support/mimetype-test/test-invalid.json", "/org/hl7/fhir/common/hapi/validation/support/mimetype-test/test-invalid.csv" }) - public void testGetMimetypesFromFile_withInvalidFormat_resultsEmpty(String theConfigFile) { + public void testGetMimetypesFromFile_withInvalidFormat_returnsEmpty(String theConfigFile) { Map mimetypeMap = CommonCodeSystemsTerminologyService.getMimetypesFromFile(theConfigFile); assertTrue(mimetypeMap.isEmpty()); } @Test - public void testFetchCodeSystem_withMimeType_returnsResult() { + public void testFetchCodeSystem_withMimeType_returnsOk() { CodeSystem cs = (CodeSystem) mySvc.fetchCodeSystem(MIMETYPES_CODESYSTEM_URL); assertNotNull(cs); assertEquals(2086, cs.getConcept().size()); @@ -274,7 +400,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW @ParameterizedTest @ValueSource(strings = { EncodingEnum.JSON_PLAIN_STRING, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_JSON }) - public void testValidateCode_withValueSetWithMimetypeKnown_returnValidResult(String code) { + public void testValidateCode_withMimetypesValueSetWithStandardCode_returnsValid(String code) { // test CodeValidationResult result = mySvc.validateCode(newSupport(), newOptions(), MIMETYPES_CODESYSTEM_URL, code, null, MIMETYPES_VALUESET_URL); @@ -289,7 +415,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW @ParameterizedTest @ValueSource(strings = { EncodingEnum.JSON_PLAIN_STRING, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_JSON }) - public void testValidateCode_withInferSystem_returnValidResult(String code) { + public void testValidateCode_withMimetypesValueSetWithInferSystemWithStandardCode_returnsValid(String code) { // test CodeValidationResult result = mySvc.validateCode(newSupport(), newOptions().setInferSystem(true), null, code, null, MIMETYPES_VALUESET_URL); @@ -304,7 +430,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW @ParameterizedTest @ValueSource(strings = { EncodingEnum.JSON_PLAIN_STRING, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_JSON }) - public void testValidateCode_withoutValueSetWithMimetypeKnown_returnValidResult(String code) { + public void testValidateCode_withMimetypesWithStandardCode_returnsValid(String code) { // test CodeValidationResult result = mySvc.validateCode(newSupport(), newOptions(), MIMETYPES_CODESYSTEM_URL, code, null, null); @@ -318,7 +444,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW } @Test - public void testValidateCode_withValueSetWithMimetypeUnknown_returnValidResult() { + public void testValidateCode_withMimetypeValueSetWithArbitraryCode_returnsValid() { // setup final String code = "someCode"; final String display = "displayValue"; @@ -334,7 +460,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW } @Test - public void testValidateCode_withoutValueSetWithMimetypeUnknown_returnValidResult() { + public void testValidateCode_withMimetypesWithArbitraryCode_returnsValid() { // setup final String code = "someCode"; final String display = "displayValue"; @@ -351,7 +477,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW @ParameterizedTest @ValueSource(strings = { EncodingEnum.JSON_PLAIN_STRING, Constants.FORMAT_TURTLE, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_JSON }) - public void testLookupCode_withMimetype_returnFoundResult(String code) { + public void testLookupCode_withMimetypesWithStandardCode_returnFound(String code) { // setup final String system = MIMETYPES_CODESYSTEM_URL; @@ -367,7 +493,7 @@ public class CommonCodeSystemsTerminologyServiceTest extends BaseValidationTestW } @Test - public void testLookupCode_withMimetype_returnNotFoundResult() { + public void testLookupCode_withMimetypesWithArbitraryCode_returnsFound() { // setup final String system = MIMETYPES_CODESYSTEM_URL; final String code = "someCode";