From: Ray Lee Date: Wed, 3 Aug 2016 01:43:39 +0000 (-0700) Subject: DRYD-23: Add integration tests. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=dcbcce9ecf746413cba67e0f6cf72debeeac17c6;p=tmp%2Fjakarta-migration.git DRYD-23: Add integration tests. --- diff --git a/services/IntegrationTests/pom.xml b/services/IntegrationTests/pom.xml index d588b3921..663545f36 100644 --- a/services/IntegrationTests/pom.xml +++ b/services/IntegrationTests/pom.xml @@ -101,10 +101,6 @@ org.jboss.resteasy resteasy-multipart-provider - - commons-httpclient - commons-httpclient - javax.security jaas @@ -134,6 +130,18 @@ 1.0 provided + + org.apache.httpcomponents + fluent-hc + 4.5.2 + test + + + org.apache.httpcomponents + httpclient + 4.5.2 + test + diff --git a/services/IntegrationTests/src/test/java/org/collectionspace/services/IntegrationTests/test/JsonIntegrationTest.java b/services/IntegrationTests/src/test/java/org/collectionspace/services/IntegrationTests/test/JsonIntegrationTest.java new file mode 100644 index 000000000..94a510289 --- /dev/null +++ b/services/IntegrationTests/src/test/java/org/collectionspace/services/IntegrationTests/test/JsonIntegrationTest.java @@ -0,0 +1,196 @@ +package org.collectionspace.services.IntegrationTests.test; + +import java.io.File; +import java.io.IOException; + +import static org.testng.Assert.*; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpResponseException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.fluent.Executor; +import org.apache.http.client.fluent.Request; +import org.apache.http.entity.ContentType; +import org.testng.annotations.Test; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Tests for sending and receiving JSON-formatted payloads. + */ +public class JsonIntegrationTest { + public static final String HOST = "localhost"; + public static final int PORT = 8180; + public static final String CLIENT_ID = "cspace-ui"; + public static final String CLIENT_SECRET = ""; + public static final String USERNAME = "admin@core.collectionspace.org"; + public static final String PASSWORD = "Administrator"; + public static final String BASE_URL = "http://" + HOST + ":" + PORT + "/cspace-services/"; + public static final String FILE_PATH = "test-data/json/"; + + private Executor restExecutor = Executor.newInstance() + .auth(new HttpHost(HOST, PORT), USERNAME, PASSWORD); + + private Executor authExecutor = Executor.newInstance() + .auth(new HttpHost(HOST, PORT), CLIENT_ID, CLIENT_SECRET); + + private ObjectMapper mapper = new ObjectMapper(); + private JsonFactory jsonFactory = mapper.getFactory(); + + @Test + public void testRecord() throws ClientProtocolException, IOException { + JsonNode jsonNode; + + String csid = postJson("collectionobjects", "collectionobject1"); + + jsonNode = getJson("collectionobjects/" + csid); + + assertEquals(jsonNode.at("/document/ns2:collectionspace_core/createdBy").asText(), USERNAME); + assertEquals(jsonNode.at("/document/ns2:collectionobjects_common/objectNumber").asText(), "TEST2000.4.5"); + assertEquals(jsonNode.at("/document/ns2:collectionobjects_common/objectNameList/objectNameGroup/objectName").asText(), "Test Object"); + assertEquals(jsonNode.at("/document/ns2:collectionobjects_common/comments/comment/0").asText(), "line 1\nline 2"); + assertEquals(jsonNode.at("/document/ns2:collectionobjects_common/comments/comment/1").asText(), "åéîøü"); + + jsonNode = putJson("collectionobjects/" + csid, "collectionobject2"); + + assertEquals(jsonNode.at("/document/ns2:collectionobjects_common/objectNumber").asText(), "TEST2000.4.5-updated"); + assertEquals(jsonNode.at("/document/ns2:collectionobjects_common/comments/comment").asText(), "™£•"); + assertTrue(jsonNode.at("/document/ns2:collectionobjects_common/comments/comment/0").isMissingNode()); + assertTrue(jsonNode.at("/document/ns2:collectionobjects_common/comments/comment/1").isMissingNode()); + + jsonNode = getJson("collectionobjects/" + csid); + + assertEquals(jsonNode.at("/document/ns2:collectionobjects_common/objectNumber").asText(), "TEST2000.4.5-updated"); + assertEquals(jsonNode.at("/document/ns2:collectionobjects_common/comments/comment").asText(), "™£•"); + assertTrue(jsonNode.at("/document/ns2:collectionobjects_common/comments/comment/0").isMissingNode()); + assertTrue(jsonNode.at("/document/ns2:collectionobjects_common/comments/comment/1").isMissingNode()); + + delete("collectionobjects/" + csid); + } + + @Test + public void testAuth() throws ClientProtocolException, IOException { + JsonNode jsonNode; + + jsonNode = postAuthForm("oauth/token", "grant_type=password&username=" + USERNAME + "&password=" + PASSWORD); + + assertEquals(jsonNode.at("/token_type").asText(), "bearer"); + assertTrue(StringUtils.isNotEmpty(jsonNode.at("/access_token").asText())); + } + + private String postJson(String path, String filename) throws ClientProtocolException, IOException { + return restExecutor.execute(Request.Post(getUrl(path)) + .addHeader("Accept", ContentType.APPLICATION_JSON.getMimeType()) + .addHeader("Content-type", ContentType.APPLICATION_JSON.getMimeType()) + .bodyFile(getFile(filename), ContentType.APPLICATION_JSON)) + .handleResponse(new CsidFromLocationResponseHandler()); + } + + private JsonNode getJson(String path) throws ClientProtocolException, IOException { + return restExecutor.execute(Request.Get(getUrl(path)) + .addHeader("Accept", ContentType.APPLICATION_JSON.getMimeType())) + .handleResponse(new JsonBodyResponseHandler()); + } + + private JsonNode putJson(String path, String filename) throws ClientProtocolException, IOException { + return restExecutor.execute(Request.Put(getUrl(path)) + .addHeader("Accept", ContentType.APPLICATION_JSON.getMimeType()) + .addHeader("Content-type", ContentType.APPLICATION_JSON.getMimeType()) + .bodyFile(getFile(filename), ContentType.APPLICATION_JSON)) + .handleResponse(new JsonBodyResponseHandler()); + } + + private void delete(String path) throws ClientProtocolException, IOException { + restExecutor.execute(Request.Delete(getUrl(path))) + .handleResponse(new CheckStatusResponseHandler()); + } + + private JsonNode postAuthForm(String path, String values) throws ClientProtocolException, IOException { + return authExecutor.execute(Request.Post(getUrl(path)) + .addHeader("Accept", ContentType.APPLICATION_JSON.getMimeType()) + .addHeader("Content-type", ContentType.APPLICATION_FORM_URLENCODED.getMimeType()) + .bodyString(values, ContentType.APPLICATION_FORM_URLENCODED)) + .handleResponse(new JsonBodyResponseHandler()); + } + + public class CsidFromLocationResponseHandler implements ResponseHandler { + + @Override + public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException { + StatusLine status = response.getStatusLine(); + int statusCode = status.getStatusCode(); + + if (statusCode< 200 || statusCode > 299) { + throw new HttpResponseException(statusCode, status.getReasonPhrase()); + } + + return csidFromLocation(response.getFirstHeader("Location").getValue()); + } + } + + public class JsonBodyResponseHandler implements ResponseHandler { + + @Override + public JsonNode handleResponse(HttpResponse response) throws ClientProtocolException, IOException { + StatusLine status = response.getStatusLine(); + int statusCode = status.getStatusCode(); + + if (statusCode< 200 || statusCode > 299) { + throw new HttpResponseException(statusCode, status.getReasonPhrase()); + } + + HttpEntity entity = response.getEntity(); + + if (entity == null) { + throw new ClientProtocolException("response contains no content"); + } + + ContentType contentType = ContentType.getOrDefault(entity); + String mimeType = contentType.getMimeType(); + + if (!mimeType.equals(ContentType.APPLICATION_JSON.getMimeType())) { + throw new ClientProtocolException("unexpected content type: " + contentType); + } + + return jsonFactory.createParser(entity.getContent()).readValueAsTree(); + } + } + + public class CheckStatusResponseHandler implements ResponseHandler { + + @Override + public Integer handleResponse(HttpResponse response) throws ClientProtocolException, IOException { + StatusLine status = response.getStatusLine(); + int statusCode = status.getStatusCode(); + + if (statusCode< 200 || statusCode > 299) { + throw new HttpResponseException(statusCode, status.getReasonPhrase()); + } + + return statusCode; + } + } + + private String csidFromLocation(String location) { + int index = location.lastIndexOf("/"); + + return location.substring(index + 1); + } + + private String getUrl(String path) { + return BASE_URL + path; + } + + private File getFile(String fileName) { + ClassLoader classLoader = getClass().getClassLoader(); + + return new File(classLoader.getResource(FILE_PATH + fileName + ".json").getFile()); + } +} diff --git a/services/IntegrationTests/src/test/resources/test-data/json/collectionobject1.json b/services/IntegrationTests/src/test/resources/test-data/json/collectionobject1.json new file mode 100644 index 000000000..f997d20e1 --- /dev/null +++ b/services/IntegrationTests/src/test/resources/test-data/json/collectionobject1.json @@ -0,0 +1,20 @@ +{ + "document": { + "@name": "collectionobjects", + "ns2:collectionobjects_common": { + "@xmlns:ns2": "http://collectionspace.org/services/collectionobject", + "objectNameList": { + "objectNameGroup": { + "objectName": "Test Object" + } + }, + "objectNumber": "TEST2000.4.5", + "comments": { + "comment": [ + "line 1\nline 2", + "åéîøü" + ] + } + } + } +} \ No newline at end of file diff --git a/services/IntegrationTests/src/test/resources/test-data/json/collectionobject2.json b/services/IntegrationTests/src/test/resources/test-data/json/collectionobject2.json new file mode 100644 index 000000000..99cd04fe3 --- /dev/null +++ b/services/IntegrationTests/src/test/resources/test-data/json/collectionobject2.json @@ -0,0 +1,14 @@ +{ + "document": { + "@name": "collectionobjects", + "ns2:collectionobjects_common": { + "@xmlns:ns2": "http://collectionspace.org/services/collectionobject", + "objectNumber": "TEST2000.4.5-updated", + "comments": { + "comment": [ + "™£•" + ] + } + } + } +} \ No newline at end of file diff --git a/services/common/src/main/java/org/collectionspace/services/common/xmljson/XmlToJsonFilter.java b/services/common/src/main/java/org/collectionspace/services/common/xmljson/XmlToJsonFilter.java index 843e29722..465e70445 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/xmljson/XmlToJsonFilter.java +++ b/services/common/src/main/java/org/collectionspace/services/common/xmljson/XmlToJsonFilter.java @@ -26,6 +26,7 @@ import javax.xml.stream.XMLStreamException; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.commons.lang3.StringUtils; /** *

A filter that translates XML responses to JSON.

@@ -65,7 +66,7 @@ public class XmlToJsonFilter implements Filter { chain.doFilter(requestWrapper, responseWrapper); - if (responseWrapper.getContentType().equals(MediaType.APPLICATION_XML)) { + if (StringUtils.equals(responseWrapper.getContentType(), MediaType.APPLICATION_XML)) { // Got an XML response. Translate it to JSON. response.setContentType(MediaType.APPLICATION_JSON); @@ -87,9 +88,11 @@ public class XmlToJsonFilter implements Filter { else { // Didn't get an XML response. Just pass it along. - InputStream inputStream = responseWrapper.getBuffer().toInputStream(); + if (responseWrapper.getBuffer() != null) { + InputStream inputStream = responseWrapper.getBuffer().toInputStream(); - IOUtils.copy(inputStream, response.getOutputStream()); + IOUtils.copy(inputStream, response.getOutputStream()); + } } } else { diff --git a/services/common/src/test/java/org/collectionspace/services/common/xmljson/test/JsonToXmlStreamConverterTest.java b/services/common/src/test/java/org/collectionspace/services/common/xmljson/test/JsonToXmlStreamConverterTest.java index 154b80216..fc5c4c378 100644 --- a/services/common/src/test/java/org/collectionspace/services/common/xmljson/test/JsonToXmlStreamConverterTest.java +++ b/services/common/src/test/java/org/collectionspace/services/common/xmljson/test/JsonToXmlStreamConverterTest.java @@ -30,6 +30,7 @@ public class JsonToXmlStreamConverterTest { testConvert("vocabulary-items"); testConvert("numeric-json"); testConvert("boolean-json"); + testConvert("single-list-item-json"); testConvertThrows("empty-json", XMLStreamException.class); } diff --git a/services/common/src/test/resources/test-data/xmljson/collectionobject.json b/services/common/src/test/resources/test-data/xmljson/collectionobject.json index c5824419c..4e68a6e58 100644 --- a/services/common/src/test/resources/test-data/xmljson/collectionobject.json +++ b/services/common/src/test/resources/test-data/xmljson/collectionobject.json @@ -56,7 +56,7 @@ "assocEventPersons": null, "assocPlaceGroupList": null, "comments": { - "comment": "new COMMENTS" + "comment": "new COMMENTS™ éå" }, "textualInscriptionGroupList": null, "briefDescriptions": null, diff --git a/services/common/src/test/resources/test-data/xmljson/collectionobject.xml b/services/common/src/test/resources/test-data/xmljson/collectionobject.xml index 56ffcd8ad..5e8e10c6e 100644 --- a/services/common/src/test/resources/test-data/xmljson/collectionobject.xml +++ b/services/common/src/test/resources/test-data/xmljson/collectionobject.xml @@ -50,7 +50,7 @@ - new COMMENTS + new COMMENTS™ éå diff --git a/services/common/src/test/resources/test-data/xmljson/single-list-item-json.json b/services/common/src/test/resources/test-data/xmljson/single-list-item-json.json new file mode 100644 index 000000000..0a88d23d4 --- /dev/null +++ b/services/common/src/test/resources/test-data/xmljson/single-list-item-json.json @@ -0,0 +1,13 @@ +{ + "document": { + "@name": "examples", + "ns:examples_common": { + "@xmlns:ns": "http://collectionspace.org/services/example", + "comments": { + "comment": [ + "some value" + ] + } + } + } +} \ No newline at end of file diff --git a/services/common/src/test/resources/test-data/xmljson/single-list-item-json.xml b/services/common/src/test/resources/test-data/xmljson/single-list-item-json.xml new file mode 100644 index 000000000..ab8890348 --- /dev/null +++ b/services/common/src/test/resources/test-data/xmljson/single-list-item-json.xml @@ -0,0 +1,7 @@ + + + + some value + + +