diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/ResponseHighlightingInterceptorTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/ResponseHighlightingInterceptorTest.java index d5d198902c6..3b2818641d3 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/ResponseHighlightingInterceptorTest.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/ResponseHighlightingInterceptorTest.java @@ -61,92 +61,230 @@ import ca.uhn.fhir.util.*; public class ResponseHighlightingInterceptorTest { + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResponseHighlightingInterceptorTest.class); private static ResponseHighlighterInterceptor ourInterceptor = new ResponseHighlighterInterceptor(); private static CloseableHttpClient ourClient; private static FhirContext ourCtx = FhirContext.forDstu2(); - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResponseHighlightingInterceptorTest.class); private static int ourPort; private static Server ourServer; private static RestfulServer ourServlet; - @AfterClass - public static void afterClassClearContext() { - TestUtil.clearAllStaticFieldsForUnitTest(); - } - @Before public void before() { ourInterceptor.setShowRequestHeaders(new ResponseHighlighterInterceptor().isShowRequestHeaders()); ourInterceptor.setShowResponseHeaders(new ResponseHighlighterInterceptor().isShowResponseHeaders()); } - /** - * For interactive testing only - */ @Test - public void waitForInput() throws IOException { - System.in.read(); + public void testBinaryReadAcceptBrowser() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary/foo"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + httpGet.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); + + HttpResponse status = ourClient.execute(httpGet); + byte[] responseContent = IOUtils.toByteArray(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("foo", status.getFirstHeader("content-type").getValue()); + assertEquals("Attachment;", status.getFirstHeader("Content-Disposition").getValue()); + assertArrayEquals(new byte[] { 1, 2, 3, 4 }, responseContent); } - /** - * See #464 - */ @Test - public void testPrettyPrintDefaultsToTrue() throws Exception { - ourServlet.setDefaultPrettyPrint(false); - - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1"); - httpGet.addHeader("Accept", "text/html"); + public void testBinaryReadAcceptFhirJson() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary/foo"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + httpGet.addHeader("Accept", Constants.CT_FHIR_JSON); HttpResponse status = ourClient.execute(httpGet); String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); IOUtils.closeQuietly(status.getEntity().getContent()); - ourLog.info(responseContent); assertEquals(200, status.getStatusLine().getStatusCode()); - assertThat(responseContent, (stringContainsInOrder("
", "", ""))); + assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertNull(status.getFirstHeader("Content-Disposition")); + assertEquals("{\"resourceType\":\"Binary\",\"id\":\"1\",\"contentType\":\"foo\",\"content\":\"AQIDBA==\"}", responseContent); + } - /** - * See #464 - */ @Test - public void testPrettyPrintDefaultsToTrueWithExplicitTrue() throws Exception { - ourServlet.setDefaultPrettyPrint(false); - - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_pretty=true"); - httpGet.addHeader("Accept", "text/html"); + public void testBinaryReadAcceptMissing() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary/foo"); + + HttpResponse status = ourClient.execute(httpGet); + byte[] responseContent = IOUtils.toByteArray(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("foo", status.getFirstHeader("content-type").getValue()); + assertEquals("Attachment;", status.getFirstHeader("Content-Disposition").getValue()); + assertArrayEquals(new byte[] { 1, 2, 3, 4 }, responseContent); + + } + + @Test + public void testDontHighlightWhenOriginHeaderPresent() throws Exception { + ResponseHighlighterInterceptor ic = ourInterceptor; + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getHeaders(Constants.HEADER_ACCEPT)).thenAnswer(new Answer>() { + @Override + public Enumeration answer(InvocationOnMock theInvocation) throws Throwable { + return new ArrayEnumeration ("text/html,application/xhtml+xml,application/xml;q=0.9"); + } + }); + when(req.getHeader(Constants.HEADER_ORIGIN)).thenAnswer(new Answer () { + @Override + public String answer(InvocationOnMock theInvocation) throws Throwable { + return "http://example.com"; + } + }); + + HttpServletResponse resp = mock(HttpServletResponse.class); + StringWriter sw = new StringWriter(); + when(resp.getWriter()).thenReturn(new PrintWriter(sw)); + + Patient resource = new Patient(); + resource.addName().addFamily("FAMILY"); + + ServletRequestDetails reqDetails = new TestServletRequestDetails(); + reqDetails.setRequestType(RequestTypeEnum.GET); + HashMap params = new HashMap (); + reqDetails.setParameters(params); + reqDetails.setServer(new RestfulServer(ourCtx)); + reqDetails.setServletRequest(req); + + // true means it decided to not handle the request.. + assertTrue(ic.outgoingResponse(reqDetails, resource, req, resp)); + + } + + @Test + public void testForceApplicationJson() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=application/json"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); HttpResponse status = ourClient.execute(httpGet); String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); IOUtils.closeQuietly(status.getEntity().getContent()); - ourLog.info(responseContent); assertEquals(200, status.getStatusLine().getStatusCode()); - assertThat(responseContent, (stringContainsInOrder("", " ", ""))); + assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, not(containsString("html"))); } - /** - * See #464 - */ @Test - public void testPrettyPrintDefaultsToTrueWithExplicitFalse() throws Exception { - ourServlet.setDefaultPrettyPrint(false); - - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_pretty=false"); - httpGet.addHeader("Accept", "text/html"); + public void testForceApplicationJsonFhir() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=application/json+fhir"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); HttpResponse status = ourClient.execute(httpGet); String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); IOUtils.closeQuietly(status.getEntity().getContent()); - ourLog.info(responseContent); assertEquals(200, status.getStatusLine().getStatusCode()); - assertThat(responseContent, not(stringContainsInOrder("", "", "\n", ""))); + assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, not(containsString("html"))); + } + + @Test + public void testForceApplicationJsonPlusFhir() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escape("application/json+fhir")); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, not(containsString("html"))); + } + + @Test + public void testForceApplicationXml() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=application/xml"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_XML + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, not(containsString("html"))); + } + + @Test + public void testForceApplicationXmlFhir() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=application/xml+fhir"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_XML + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, not(containsString("html"))); + } + + @Test + public void testForceApplicationXmlPlusFhir() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escape("application/xml+fhir")); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_XML + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, not(containsString("html"))); + } + + @Test + public void testForceHtmlJson() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, containsString("html")); + assertThat(responseContent, containsString(">{<")); + assertThat(responseContent, not(containsString("<"))); + + ourLog.info(responseContent); + } + + @Test + public void testForceHtmlXml() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/xml"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, containsString("html")); + assertThat(responseContent, not(containsString(">{<"))); + assertThat(responseContent, containsString("<")); + } + + @Test + public void testForceJson() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=json"); + httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, not(containsString("html"))); } @Test public void testForceResponseTime() throws Exception { HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); - + HttpResponse status = ourClient.execute(httpGet); String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); IOUtils.closeQuietly(status.getEntity().getContent()); @@ -154,74 +292,7 @@ public class ResponseHighlightingInterceptorTest { assertEquals(200, status.getStatusLine().getStatusCode()); assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); assertThat(responseContent.replace('\n', ' ').replace('\r', ' '), matchesPattern(".*Response generated in [0-9]+ms.*")); - - } - @Test - public void testShowNeither() throws Exception { - ourInterceptor.setShowRequestHeaders(false); - ourInterceptor.setShowResponseHeaders(false); - - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - ourLog.info(responseContent); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsStringIgnoringCase("Accept"))); - assertThat(responseContent, not(containsStringIgnoringCase("Content-Type"))); - } - - @Test - public void testShowResponse() throws Exception { - ourInterceptor.setShowResponseHeaders(true); - - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - ourLog.info(responseContent); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsStringIgnoringCase("Accept"))); - assertThat(responseContent, (containsStringIgnoringCase("Content-Type"))); - } - - @Test - public void testShowRequest() throws Exception { - ourInterceptor.setShowRequestHeaders(true); - ourInterceptor.setShowResponseHeaders(false); - - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - ourLog.info(responseContent); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, (containsStringIgnoringCase("Accept"))); - assertThat(responseContent, not(containsStringIgnoringCase("Content-Type"))); - } - - @Test - public void testShowRequestAndResponse() throws Exception { - ourInterceptor.setShowRequestHeaders(true); - ourInterceptor.setShowResponseHeaders(true); - - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - ourLog.info(responseContent); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, (containsStringIgnoringCase("Accept"))); - assertThat(responseContent, (containsStringIgnoringCase("Content-Type"))); } @Test @@ -238,7 +309,7 @@ public class ResponseHighlightingInterceptorTest { assertThat(responseContent, stringContainsInOrder("OperationOutcome", "Unknown resource type 'Foobar' - Server knows how to handle")); } - + @Test public void testGetInvalidResourceNoAcceptHeader() throws Exception { HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Foobar/123"); @@ -296,7 +367,7 @@ public class ResponseHighlightingInterceptorTest { // This can be null depending on the exception type // reqDetails.setParameters(null); - + ResourceNotFoundException exception = new ResourceNotFoundException("Not found"); exception.setOperationOutcome(new OperationOutcome().addIssue(new Issue().setDiagnostics("Hello"))); @@ -307,113 +378,6 @@ public class ResponseHighlightingInterceptorTest { assertThat(output, containsString("OperationOutcome")); } - - @Test - public void testHighlightNormalResponseForcePrettyPrint() throws Exception { - ResponseHighlighterInterceptor ic = ourInterceptor; - - HttpServletRequest req = mock(HttpServletRequest.class); - when(req.getHeaders(Constants.HEADER_ACCEPT)).thenAnswer(new Answer>() { - @Override - public Enumeration answer(InvocationOnMock theInvocation) throws Throwable { - return new ArrayEnumeration ("text/html,application/xhtml+xml,application/xml;q=0.9"); - } - }); - - HttpServletResponse resp = mock(HttpServletResponse.class); - StringWriter sw = new StringWriter(); - when(resp.getWriter()).thenReturn(new PrintWriter(sw)); - - Patient resource = new Patient(); - resource.addName().addFamily("FAMILY"); - - ServletRequestDetails reqDetails = new TestServletRequestDetails(); - reqDetails.setRequestType(RequestTypeEnum.GET); - HashMap params = new HashMap (); - params.put(Constants.PARAM_PRETTY, new String[] { Constants.PARAM_PRETTY_VALUE_TRUE }); - reqDetails.setParameters(params); - reqDetails.setServer(new RestfulServer(ourCtx)); - reqDetails.setServletRequest(req); - - assertFalse(ic.outgoingResponse(reqDetails, resource, req, resp)); - - String output = sw.getBuffer().toString(); - ourLog.info(output); - assertThat(output, containsString("Patient")); - assertThat(output, stringContainsInOrder("", " ", "")); - } - - @Test - public void testHighlightForceRaw() throws Exception { - ResponseHighlighterInterceptor ic = ourInterceptor; - - HttpServletRequest req = mock(HttpServletRequest.class); - when(req.getHeaders(Constants.HEADER_ACCEPT)).thenAnswer(new Answer>() { - @Override - public Enumeration answer(InvocationOnMock theInvocation) throws Throwable { - return new ArrayEnumeration ("text/html,application/xhtml+xml,application/xml;q=0.9"); - } - }); - - HttpServletResponse resp = mock(HttpServletResponse.class); - StringWriter sw = new StringWriter(); - when(resp.getWriter()).thenReturn(new PrintWriter(sw)); - - Patient resource = new Patient(); - resource.addName().addFamily("FAMILY"); - - ServletRequestDetails reqDetails = new TestServletRequestDetails(); - reqDetails.setRequestType(RequestTypeEnum.GET); - HashMap params = new HashMap (); - params.put(Constants.PARAM_PRETTY, new String[] { Constants.PARAM_PRETTY_VALUE_TRUE }); - params.put(Constants.PARAM_FORMAT, new String[] { Constants.CT_XML }); - params.put(ResponseHighlighterInterceptor.PARAM_RAW, new String[] { ResponseHighlighterInterceptor.PARAM_RAW_TRUE }); - reqDetails.setParameters(params); - reqDetails.setServer(new RestfulServer(ourCtx)); - reqDetails.setServletRequest(req); - - // true means it decided to not handle the request.. - assertTrue(ic.outgoingResponse(reqDetails, resource, req, resp)); - - } - - @Test - public void testDontHighlightWhenOriginHeaderPresent() throws Exception { - ResponseHighlighterInterceptor ic = ourInterceptor; - - HttpServletRequest req = mock(HttpServletRequest.class); - when(req.getHeaders(Constants.HEADER_ACCEPT)).thenAnswer(new Answer >() { - @Override - public Enumeration answer(InvocationOnMock theInvocation) throws Throwable { - return new ArrayEnumeration ("text/html,application/xhtml+xml,application/xml;q=0.9"); - } - }); - when(req.getHeader(Constants.HEADER_ORIGIN)).thenAnswer(new Answer () { - @Override - public String answer(InvocationOnMock theInvocation) throws Throwable { - return "http://example.com"; - } - }); - - HttpServletResponse resp = mock(HttpServletResponse.class); - StringWriter sw = new StringWriter(); - when(resp.getWriter()).thenReturn(new PrintWriter(sw)); - - Patient resource = new Patient(); - resource.addName().addFamily("FAMILY"); - - ServletRequestDetails reqDetails = new TestServletRequestDetails(); - reqDetails.setRequestType(RequestTypeEnum.GET); - HashMap params = new HashMap (); - reqDetails.setParameters(params); - reqDetails.setServer(new RestfulServer(ourCtx)); - reqDetails.setServletRequest(req); - - // true means it decided to not handle the request.. - assertTrue(ic.outgoingResponse(reqDetails, resource, req, resp)); - - } - /** * See #346 */ @@ -482,6 +446,40 @@ public class ResponseHighlightingInterceptorTest { assertFalse(ic.outgoingResponse(reqDetails, resource, req, resp)); } + @Test + public void testHighlightForceRaw() throws Exception { + ResponseHighlighterInterceptor ic = ourInterceptor; + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getHeaders(Constants.HEADER_ACCEPT)).thenAnswer(new Answer >() { + @Override + public Enumeration answer(InvocationOnMock theInvocation) throws Throwable { + return new ArrayEnumeration ("text/html,application/xhtml+xml,application/xml;q=0.9"); + } + }); + + HttpServletResponse resp = mock(HttpServletResponse.class); + StringWriter sw = new StringWriter(); + when(resp.getWriter()).thenReturn(new PrintWriter(sw)); + + Patient resource = new Patient(); + resource.addName().addFamily("FAMILY"); + + ServletRequestDetails reqDetails = new TestServletRequestDetails(); + reqDetails.setRequestType(RequestTypeEnum.GET); + HashMap params = new HashMap (); + params.put(Constants.PARAM_PRETTY, new String[] { Constants.PARAM_PRETTY_VALUE_TRUE }); + params.put(Constants.PARAM_FORMAT, new String[] { Constants.CT_XML }); + params.put(ResponseHighlighterInterceptor.PARAM_RAW, new String[] { ResponseHighlighterInterceptor.PARAM_RAW_TRUE }); + reqDetails.setParameters(params); + reqDetails.setServer(new RestfulServer(ourCtx)); + reqDetails.setServletRequest(req); + + // true means it decided to not handle the request.. + assertTrue(ic.outgoingResponse(reqDetails, resource, req, resp)); + + } + @Test public void testHighlightNormalResponse() throws Exception { ResponseHighlighterInterceptor ic = ourInterceptor; @@ -516,6 +514,41 @@ public class ResponseHighlightingInterceptorTest { assertThat(output, containsString("")); } + @Test + public void testHighlightNormalResponseForcePrettyPrint() throws Exception { + ResponseHighlighterInterceptor ic = ourInterceptor; + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getHeaders(Constants.HEADER_ACCEPT)).thenAnswer(new Answer >() { + @Override + public Enumeration answer(InvocationOnMock theInvocation) throws Throwable { + return new ArrayEnumeration ("text/html,application/xhtml+xml,application/xml;q=0.9"); + } + }); + + HttpServletResponse resp = mock(HttpServletResponse.class); + StringWriter sw = new StringWriter(); + when(resp.getWriter()).thenReturn(new PrintWriter(sw)); + + Patient resource = new Patient(); + resource.addName().addFamily("FAMILY"); + + ServletRequestDetails reqDetails = new TestServletRequestDetails(); + reqDetails.setRequestType(RequestTypeEnum.GET); + HashMap params = new HashMap (); + params.put(Constants.PARAM_PRETTY, new String[] { Constants.PARAM_PRETTY_VALUE_TRUE }); + reqDetails.setParameters(params); + reqDetails.setServer(new RestfulServer(ourCtx)); + reqDetails.setServletRequest(req); + + assertFalse(ic.outgoingResponse(reqDetails, resource, req, resp)); + + String output = sw.getBuffer().toString(); + ourLog.info(output); + assertThat(output, containsString("Patient")); + assertThat(output, stringContainsInOrder("", " ", "")); + } + /** * Browsers declare XML but not JSON in their accept header, we should still respond using JSON if that's the default */ @@ -553,9 +586,6 @@ public class ResponseHighlightingInterceptorTest { ourLog.info(output); assertThat(output, containsString("resourceType")); } - - - @Test public void testHighlightProducesDefaultJsonWithBrowserRequest2() throws Exception { @@ -589,6 +619,60 @@ public class ResponseHighlightingInterceptorTest { assertTrue(ic.outgoingResponse(reqDetails, resource, req, resp)); } + /** + * See #464 + */ + @Test + public void testPrettyPrintDefaultsToTrue() throws Exception { + ourServlet.setDefaultPrettyPrint(false); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1"); + httpGet.addHeader("Accept", "text/html"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, (stringContainsInOrder("", "", ""))); + } + + /** + * See #464 + */ + @Test + public void testPrettyPrintDefaultsToTrueWithExplicitFalse() throws Exception { + ourServlet.setDefaultPrettyPrint(false); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_pretty=false"); + httpGet.addHeader("Accept", "text/html"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, not(stringContainsInOrder("", "", "\n", ""))); + } + + /** + * See #464 + */ + @Test + public void testPrettyPrintDefaultsToTrueWithExplicitTrue() throws Exception { + ourServlet.setDefaultPrettyPrint(false); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_pretty=true"); + httpGet.addHeader("Accept", "text/html"); + + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, (stringContainsInOrder("", "", ""))); + } + @Test public void testSearchWithSummaryParam() throws Exception { HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchWithWildcardRetVal&_summary=count"); @@ -603,169 +687,75 @@ public class ResponseHighlightingInterceptorTest { } @Test - public void testBinaryReadAcceptMissing() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary/foo"); + public void testShowNeither() throws Exception { + ourInterceptor.setShowRequestHeaders(false); + ourInterceptor.setShowResponseHeaders(false); - HttpResponse status = ourClient.execute(httpGet); - byte[] responseContent = IOUtils.toByteArray(status.getEntity().getContent()); - IOUtils.closeQuietly(status.getEntity().getContent()); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals("foo", status.getFirstHeader("content-type").getValue()); - assertEquals("Attachment;", status.getFirstHeader("Content-Disposition").getValue()); - assertArrayEquals(new byte[] { 1, 2, 3, 4 }, responseContent); - - } - - @Test - public void testBinaryReadAcceptBrowser() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary/foo"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - httpGet.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); - - HttpResponse status = ourClient.execute(httpGet); - byte[] responseContent = IOUtils.toByteArray(status.getEntity().getContent()); - IOUtils.closeQuietly(status.getEntity().getContent()); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals("foo", status.getFirstHeader("content-type").getValue()); - assertEquals("Attachment;", status.getFirstHeader("Content-Disposition").getValue()); - assertArrayEquals(new byte[] { 1, 2, 3, 4 }, responseContent); - } - - @Test - public void testBinaryReadAcceptFhirJson() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary/foo"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - httpGet.addHeader("Accept", Constants.CT_FHIR_JSON); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertNull(status.getFirstHeader("Content-Disposition")); - assertEquals("{\"resourceType\":\"Binary\",\"id\":\"1\",\"contentType\":\"foo\",\"content\":\"AQIDBA==\"}", responseContent); - - } - @Test - public void testForceApplicationJson() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=application/json"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsString("html"))); - } - @Test - public void testForceApplicationJsonFhir() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=application/json+fhir"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsString("html"))); - } - - @Test - public void testForceApplicationJsonPlusFhir() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escape("application/json+fhir")); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsString("html"))); - } - - @Test - public void testForceJson() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=json"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); - IOUtils.closeQuietly(status.getEntity().getContent()); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsString("html"))); - } - - - - @Test - public void testForceHtmlJson() throws Exception { HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - + HttpResponse status = ourClient.execute(httpGet); String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); IOUtils.closeQuietly(status.getEntity().getContent()); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, containsString("html")); - assertThat(responseContent, containsString(">{<")); - assertThat(responseContent, not(containsString("<"))); - ourLog.info(responseContent); - } - - @Test - public void testForceHtmlXml() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/xml"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - - HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent()); - IOUtils.closeQuietly(status.getEntity().getContent()); assertEquals(200, status.getStatusLine().getStatusCode()); assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, containsString("html")); - assertThat(responseContent, not(containsString(">{<"))); - assertThat(responseContent, containsString("<")); + assertThat(responseContent, not(containsStringIgnoringCase("Accept"))); + assertThat(responseContent, not(containsStringIgnoringCase("Content-Type"))); } @Test - public void testForceApplicationXml() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=application/xml"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - + public void testShowRequest() throws Exception { + ourInterceptor.setShowRequestHeaders(true); + ourInterceptor.setShowResponseHeaders(false); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); + HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent()); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals(Constants.CT_FHIR_XML + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsString("html"))); + assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, (containsStringIgnoringCase("Accept"))); + assertThat(responseContent, not(containsStringIgnoringCase("Content-Type"))); } + @Test - public void testForceApplicationXmlFhir() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=application/xml+fhir"); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - + public void testShowRequestAndResponse() throws Exception { + ourInterceptor.setShowRequestHeaders(true); + ourInterceptor.setShowResponseHeaders(true); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); + HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent()); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals(Constants.CT_FHIR_XML + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsString("html"))); + assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, (containsStringIgnoringCase("Accept"))); + assertThat(responseContent, (containsStringIgnoringCase("Content-Type"))); } + @Test - public void testForceApplicationXmlPlusFhir() throws Exception { - HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escape("application/xml+fhir")); - httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); - + public void testShowResponse() throws Exception { + ourInterceptor.setShowResponseHeaders(true); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=html/json"); + HttpResponse status = ourClient.execute(httpGet); - String responseContent = IOUtils.toString(status.getEntity().getContent()); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); assertEquals(200, status.getStatusLine().getStatusCode()); - assertEquals(Constants.CT_FHIR_XML + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); - assertThat(responseContent, not(containsString("html"))); + assertEquals("text/html;charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); + assertThat(responseContent, not(containsStringIgnoringCase("Accept"))); + assertThat(responseContent, (containsStringIgnoringCase("Content-Type"))); + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); } @BeforeClass @@ -812,6 +802,13 @@ public class ResponseHighlightingInterceptorTest { } + class TestServletRequestDetails extends ServletRequestDetails { + @Override + public String getServerBaseForRequest() { + return "/baseDstu3"; + } + } + public static class DummyBinaryResourceProvider implements IResourceProvider { @Override @@ -839,7 +836,6 @@ public class ResponseHighlightingInterceptorTest { } - public static class DummyPatientResourceProvider implements IResourceProvider { private Patient createPatient1() { @@ -898,7 +894,7 @@ public class ResponseHighlightingInterceptorTest { /** * Retrieve the resource by its identifier - * + * * @param theId * The resource identity * @return The resource @@ -912,7 +908,7 @@ public class ResponseHighlightingInterceptorTest { /** * Retrieve the resource by its identifier - * + * * @param theId * The resource identity * @return The resource @@ -942,11 +938,4 @@ public class ResponseHighlightingInterceptorTest { } - class TestServletRequestDetails extends ServletRequestDetails { - @Override - public String getServerBaseForRequest() { - return "/baseDstu3"; - } - } - } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ExamineTestTrace.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ExamineTestTrace.java index 4a1e9a74555..6f36d5b953d 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ExamineTestTrace.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ExamineTestTrace.java @@ -14,12 +14,18 @@ public class ExamineTestTrace { private static final Logger ourLog = LoggerFactory.getLogger(ExamineTestTrace.class); public static void main(String[] aaa) { - String input = "Running ca.uhn.fhir.model.primitive.BaseResourceReferenceDtTest\n" + - "Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.896 sec - in ca.uhn.fhir.rest.server.OperationServerWithSearchParamTypesDstu2Test"; + String input = "[INFO] Running ca.uhn.fhir.rest.client.RestfulClientFactoryDstu2Test\n" + + "[INFO] Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.982 s - in ca.uhn.fhir.validation.ResourceValidatorDstu2Test"; Setstarted = new HashSet<>(); Set finished = new HashSet<>(); for (String next : input.split("\n")) { + if (next.startsWith("[INFO] ")) { + next = next.substring("[INFO] ".length()); + } + if (next.startsWith("[WARNING] ")) { + next = next.substring("[WARNING] ".length()); + } if (next.startsWith("Running ")) { started.add(next.substring("Running ".length())); } else if (next.startsWith("Tests run: ")) { @@ -27,7 +33,7 @@ public class ExamineTestTrace { } else if (isBlank(next)) { continue; } else { - throw new IllegalStateException(); + throw new IllegalStateException("Unknown line: " + next); } }