package ca.uhn.fhir.validation; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Locale; import org.apache.commons.io.IOUtils; import org.hamcrest.core.StringContains; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.dstu.resource.OperationOutcome; import ca.uhn.fhir.model.dstu.resource.Patient; import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum; import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.StrictErrorHandler; import ca.uhn.fhir.util.TestUtil; public class ResourceValidatorTest { private static FhirContext ourCtx = FhirContext.forDstu1(); private static Locale ourDefaultLocale; private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceValidatorTest.class); @Test public void testSchemaResourceValidator() throws IOException { String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml")); Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res); FhirValidator val = ourCtx.newValidator(); val.setValidateAgainstStandardSchema(true); val.setValidateAgainstStandardSchematron(false); val.validate(p); p.getAnimal().getBreed().setText("The Breed"); try { val.validate(p); fail(); } catch (ValidationFailureException e) { OperationOutcome outcome = (OperationOutcome) e.getOperationOutcome(); ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outcome)); assertEquals(1, outcome.getIssue().size()); assertThat(outcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type.2.4.a")); } } @BeforeClass public static void beforeClass() { /* * We cache the default locale, but temporarily set it to a random value during this test. This helps ensure that there are no * language specific dependencies in the test. */ ourDefaultLocale = Locale.getDefault(); Locale newLocale = Locale.GERMANY; Locale.setDefault(newLocale); ourLog.info("Tests are running in locale: " + newLocale.getDisplayName()); } public static void afterClass() { Locale.setDefault(ourDefaultLocale); } /** * See issue #50 */ @Test() public void testOutOfBoundsDate() { Patient p = new Patient(); p.setBirthDate(new DateTimeDt("2000-12-31")); // Put in an invalid date IParser parser = ourCtx.newXmlParser(); parser.setParserErrorHandler(new StrictErrorHandler()); String encoded = parser.setPrettyPrint(true).encodeResourceToString(p).replace("2000-12-31", "2000-15-31"); ourLog.info(encoded); assertThat(encoded, StringContains.containsString("2000-15-31")); FhirValidator validator = ourCtx.newValidator(); ValidationResult result = validator.validateWithResult(encoded); String resultString = parser.setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome()); ourLog.info(resultString); assertEquals(2, ((OperationOutcome)result.toOperationOutcome()).getIssue().size()); assertThat(resultString, StringContains.containsString("cvc-datatype-valid.1.2.3")); try { parser.parseResource(encoded); fail(); } catch (DataFormatException e) { assertEquals("DataFormatException at [[row,col {unknown-source}]: [2,4]]: Invalid attribute value \"2000-15-31\": Invalid date/time format: \"2000-15-31\"", e.getMessage()); } } @Test public void testSchemaBundleValidator() throws IOException { String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("atom-document-large.xml")); Bundle b = ourCtx.newXmlParser().parseBundle(res); FhirValidator val = createFhirValidator(); val.validate(b); Patient p = (Patient) b.getEntries().get(0).getResource(); p.getTelecomFirstRep().setValue("123-4567"); try { val.validate(b); fail(); } catch (ValidationFailureException e) { OperationOutcome outcome = (OperationOutcome) e.getOperationOutcome(); ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outcome)); assertEquals(1, outcome.getIssue().size()); assertThat(outcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("Inv-2:")); } } @Test public void testSchematronResourceValidator() throws IOException { String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml")); Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res); FhirValidator val = ourCtx.newValidator(); val.setValidateAgainstStandardSchema(false); val.setValidateAgainstStandardSchematron(true); ValidationResult validationResult = val.validateWithResult(p); assertTrue(validationResult.isSuccessful()); p.getTelecomFirstRep().setValue("123-4567"); validationResult = val.validateWithResult(p); assertFalse(validationResult.isSuccessful()); OperationOutcome operationOutcome = (OperationOutcome) validationResult.toOperationOutcome(); ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome)); assertEquals(1, operationOutcome.getIssue().size()); assertThat(operationOutcome.getIssueFirstRep().getDetails().getValue(), containsString("Inv-2:")); p.getTelecomFirstRep().setSystem(ContactSystemEnum.EMAIL); validationResult = val.validateWithResult(p); assertTrue(validationResult.isSuccessful()); } @Test public void testSchemaBundleValidatorIsSuccessful() throws IOException { String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("atom-document-large.xml")); Bundle b = ourCtx.newXmlParser().parseBundle(res); FhirValidator val = createFhirValidator(); ValidationResult result = val.validateWithResult(b); OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome(); ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome)); assertTrue(result.isSuccessful()); assertNotNull(operationOutcome); assertEquals(1, operationOutcome.getIssue().size()); } @Test public void testSchemaBundleValidatorFails() throws IOException { String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("atom-document-large.xml")); Bundle b = ourCtx.newXmlParser().parseBundle(res); FhirValidator val = createFhirValidator(); ValidationResult validationResult = val.validateWithResult(b); assertTrue(validationResult.isSuccessful()); Patient p = (Patient) b.getEntries().get(0).getResource(); p.getTelecomFirstRep().setValue("123-4567"); validationResult = val.validateWithResult(b); assertFalse(validationResult.isSuccessful()); OperationOutcome operationOutcome = (OperationOutcome) validationResult.toOperationOutcome(); ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome)); assertEquals(1, operationOutcome.getIssue().size()); assertThat(operationOutcome.getIssueFirstRep().getDetails().getValue(), containsString("Inv-2:")); } private FhirValidator createFhirValidator() { FhirValidator val = ourCtx.newValidator(); val.setValidateAgainstStandardSchema(true); val.setValidateAgainstStandardSchematron(true); return val; } @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); } }