package ca.uhn.fhir.jpa.provider.dstu3; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Collection; import org.apache.commons.io.IOUtils; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemComponent; import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType; import org.hl7.fhir.dstu3.model.QuestionnaireResponse.QuestionnaireResponseStatus; import org.hl7.fhir.instance.model.api.IIdType; import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.validation.IValidatorModule; import ca.uhn.fhir.validation.ResultSeverityEnum; public class ResourceProviderQuestionnaireResponseDstu3Test extends BaseResourceProviderDstu3Test { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderQuestionnaireResponseDstu3Test.class); private static RequestValidatingInterceptor ourValidatingInterceptor; @AfterClass public static void afterClassClearContext() { ourRestServer.unregisterInterceptor(ourValidatingInterceptor); ourValidatingInterceptor = null; TestUtil.clearAllStaticFieldsForUnitTest(); } @Override @Before public void before() throws Exception { super.before(); if (ourValidatingInterceptor == null) { ourValidatingInterceptor = new RequestValidatingInterceptor(); ourValidatingInterceptor.setFailOnSeverity(ResultSeverityEnum.ERROR); Collection<IValidatorModule> validators = myAppCtx.getBeansOfType(IValidatorModule.class).values(); for (IValidatorModule next : validators) { ourValidatingInterceptor.addValidatorModule(next); } ourRestServer.registerInterceptor(ourValidatingInterceptor); } } @SuppressWarnings("unused") @Test public void testCreateWithLocalReference() { Patient pt1 = new Patient(); pt1.addName().setFamily("Everything").addGiven("Arthur"); IIdType ptId1 = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless(); Questionnaire q1 = new Questionnaire(); q1.addItem().setLinkId("link1").setType(QuestionnaireItemType.STRING); IIdType qId = myQuestionnaireDao.create(q1, mySrd).getId().toUnqualifiedVersionless(); QuestionnaireResponse qr1 = new QuestionnaireResponse(); qr1.getQuestionnaire().setReferenceElement(qId); qr1.setStatus(QuestionnaireResponseStatus.COMPLETED); qr1.addItem().setLinkId("link1").addAnswer().setValue(new DecimalType(123)); try { ourClient.create().resource(qr1).execute(); fail(); } catch (UnprocessableEntityException e) { assertThat(e.toString(), containsString("Answer value must be of type string")); } } @SuppressWarnings("unused") @Test public void testCreateWithAbsoluteReference() { Patient pt1 = new Patient(); pt1.addName().setFamily("Everything").addGiven("Arthur"); IIdType ptId1 = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless(); Questionnaire q1 = new Questionnaire(); q1.addItem().setLinkId("link1").setType(QuestionnaireItemType.STRING); IIdType qId = myQuestionnaireDao.create(q1, mySrd).getId().toUnqualifiedVersionless(); QuestionnaireResponse qr1 = new QuestionnaireResponse(); qr1.getQuestionnaire().setReferenceElement(qId.withServerBase("http://example.com", "Questionnaire")); qr1.setStatus(QuestionnaireResponseStatus.COMPLETED); qr1.addItem().setLinkId("link1").addAnswer().setValue(new DecimalType(123)); try { ourClient.create().resource(qr1).execute(); fail(); } catch (UnprocessableEntityException e) { assertThat(e.toString(), containsString("Answer value must be of type string")); } } @Test public void testSaveQuestionnaire() throws Exception { String input = "<QuestionnaireResponse xmlns=\"http://hl7.org/fhir\">\n" + " <status value=\"completed\"/>\n" + " <authored value=\"2016-05-03T13:05:20-04:00\"/>\n" + " <item>\n" + " <linkId value=\"breast-feeding-intention\"/>\n" + " <text value=\"Breast Feeding Intention:\"/>\n" + " <answer>\n" + " <valueCoding>\n" + " <system value=\"http://example.org/codesystem-breastfeeding-intention\"/>\n" + " <code value=\"true\"/>\n" + " <display value=\"Mother wants to provide formula exclusively\"/>\n" + " </valueCoding>\n" + " </answer>\n" + " </item>\n" + " <item>\n" + " <linkId value=\"breast-feeding-education\"/>\n" + " <text value=\"Answer if not exclusive BM:\"/>\n" + " <answer>\n" + " <valueCoding>\n" + " <system value=\"http://example.org/codesystem-breastfeeding-education\"/>\n" + " <code value=\"true\"/>\n" + " <display value=\"Mother not given comprehensive education per protocol\"/>\n" + " </valueCoding>\n" + " </answer>\n" + " </item>\n" + " <item>\n" + " <linkId value=\"breast-feeding-exclusion\"/>\n" + " <text value=\"Exclusion Criteria:\"/>\n" + " <answer>\n" + " <valueCoding>\n" + " <system value=\"http://example.org/codesystem-breastfeeding-exclusion\"/>\n" + " <code value=\"true\"/>\n" + " <display\n" + " value=\"Maternal use of drugs of abuse, antimetabolites, chemotherapeutic agents, or radioisotopes\"\n" + " />\n" + " </valueCoding>\n" + " </answer>\n" + " </item>\n" + "</QuestionnaireResponse>"; HttpPost post = new HttpPost(ourServerBase + "/QuestionnaireResponse"); post.setEntity(new StringEntity(input, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); CloseableHttpResponse response = ourHttpClient.execute(post); final IdType id2; try { String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info("Response: {}", responseString); assertEquals(201, response.getStatusLine().getStatusCode()); String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue(); assertThat(newIdString, startsWith(ourServerBase + "/QuestionnaireResponse/")); id2 = new IdType(newIdString); } finally { IOUtils.closeQuietly(response); } HttpGet get = new HttpGet(ourServerBase + "/QuestionnaireResponse/" + id2.getIdPart() + "?_format=xml&_pretty=true"); response = ourHttpClient.execute(get); try { String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info("Response: {}", responseString); assertThat(responseString, containsString("Exclusion Criteria")); } finally { IOUtils.closeQuietly(response); } } @Test public void testValidateOnNoId() throws Exception { HttpGet get = new HttpGet(ourServerBase + "/QuestionnaireResponse/$validate"); CloseableHttpResponse response = ourHttpClient.execute(get); try { String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info("Response: {}", responseString); assertThat(responseString, containsString("No resource supplied for $validate operation")); assertEquals(400, response.getStatusLine().getStatusCode()); } finally { IOUtils.closeQuietly(response); } } /** * From a Skype message from Brian Postlethwaite */ @Test public void testValidateQuestionnaireResponseWithNoIdForCreate() throws Exception { String input = "{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"mode\",\"valueString\":\"create\"},{\"name\":\"resource\",\"resource\":{\"resourceType\":\"QuestionnaireResponse\",\"questionnaire\":{\"reference\":\"http://fhirtest.uhn.ca/baseDstu2/Questionnaire/MedsCheckEligibility\"},\"text\":{\"status\":\"generated\",\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">!-- populated from the rendered HTML below --></div>\"},\"status\":\"completed\",\"authored\":\"2017-02-10T00:02:58.098Z\"}}]}"; HttpPost post = new HttpPost(ourServerBase + "/QuestionnaireResponse/$validate?_pretty=true"); post.setEntity(new StringEntity(input, ContentType.APPLICATION_JSON)); CloseableHttpResponse response = ourHttpClient.execute(post); try { String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info("Response: {}", responseString); assertEquals(200, response.getStatusLine().getStatusCode()); } finally { IOUtils.closeQuietly(response); } } /** * From a Skype message from Brian Postlethwaite */ @Test public void testValidateQuestionnaireResponseWithNoIdForUpdate() throws Exception { String input = "{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"mode\",\"valueString\":\"update\"},{\"name\":\"resource\",\"resource\":{\"resourceType\":\"QuestionnaireResponse\",\"questionnaire\":{\"reference\":\"http://fhirtest.uhn.ca/baseDstu2/Questionnaire/MedsCheckEligibility\"},\"text\":{\"status\":\"generated\",\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">!-- populated from the rendered HTML below --></div>\"},\"status\":\"completed\",\"authored\":\"2017-02-10T00:02:58.098Z\"}}]}"; HttpPost post = new HttpPost(ourServerBase + "/QuestionnaireResponse/$validate?_pretty=true"); post.setEntity(new StringEntity(input, ContentType.APPLICATION_JSON)); CloseableHttpResponse response = ourHttpClient.execute(post); try { String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info("Response: {}", responseString); assertThat(responseString, containsString("Resource has no ID")); assertEquals(422, response.getStatusLine().getStatusCode()); } finally { IOUtils.closeQuietly(response); } } }