2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright © 2009 Regents of the University of California
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
15 * https://source.collectionspace.org/collection-space/LICENSE.txt
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
24 package org.collectionspace.services.client.test;
26 import java.util.List;
27 import javax.ws.rs.core.Response;
28 import org.jboss.resteasy.client.ClientResponse;
29 import org.testng.Assert;
30 import org.testng.annotations.Test;
32 import org.collectionspace.services.client.CollectionObjectClient;
33 import org.collectionspace.services.client.test.ServiceRequestType;
34 import org.collectionspace.services.collectionobject.CollectionObject;
35 import org.collectionspace.services.collectionobject.CollectionObjectList;
37 import java.util.Arrays;
39 import javax.ws.rs.core.Response.Status;
40 // import org.jboss.resteasy.client.ClientRequest;
42 import org.apache.commons.httpclient.methods.GetMethod;
43 import org.apache.commons.httpclient.methods.PostMethod;
44 import org.apache.commons.httpclient.methods.PutMethod;
45 import org.apache.commons.httpclient.methods.RequestEntity;
46 import org.apache.commons.httpclient.methods.StringRequestEntity;
49 * CollectionObjectServiceTest, carries out tests against a
50 * deployed and running CollectionObject Service.
52 * $LastChangedRevision$
55 public class CollectionObjectServiceTest extends AbstractServiceTest {
57 // Instance variables specific to this test.
58 private CollectionObjectClient client = new CollectionObjectClient();
60 // Instance variables common to all entity service test classes.
61 private final String NON_EXISTENT_ID = createNonExistentIdentifier();
62 private String knownObjectId = null;
64 // ---------------------------------------------------------------
65 // CRUD tests : CREATE tests
66 // ---------------------------------------------------------------
72 public void create() {
74 // Perform setup, such as initializing the type of service request
75 // and its valid and expected status codes.
78 // Submit the request to the service and store the response.
79 String identifier = createIdentifier();
80 CollectionObject collectionObject = createCollectionObject(identifier);
81 ClientResponse<Response> res = client.createCollectionObject(collectionObject);
82 int statusCode = res.getStatus();
84 // Check the status code of the response: does it match the expected response(s)?
86 // Does it fall within the set of valid status codes?
87 // Does it match the expected status code?
88 verbose("create: status = " + statusCode);
89 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
90 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
91 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
93 // Store the ID returned from this create operation for additional tests below.
94 knownObjectId = extractId(res);
98 @Test(dependsOnMethods = {"create"})
99 public void createMultiple() {
100 for(int i = 0; i < 3; i++){
108 @Test(dependsOnMethods = {"create"}, expectedExceptions = IllegalArgumentException.class)
109 public void createNull() {
110 ClientResponse<Response> res = client.createCollectionObject(null);
114 @Test(dependsOnMethods = {"create", "testSubmitRequest"})
115 public void createWithMalformedXml() {
118 super.setupCreateWithMalformedXml();
120 // Submit the request to the service and store the response.
121 String url = getServiceRootURL();
122 PostMethod method = new PostMethod(url);
123 final String MALFORMED_XML_DATA =
124 "<malformed_xml>wrong schema contents</malformed_xml"; // Note: intentionally missing bracket.
125 StringRequestEntity entity = getXmlEntity(MALFORMED_XML_DATA);
126 int statusCode = submitRequest(method, entity);
128 // Check the status code of the response: does it match the expected response(s)?
129 verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
130 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
131 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
132 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
136 @Test(dependsOnMethods = {"create", "testSubmitRequest"}) //, "createWithMalformedXml"})
137 public void createWithWrongXmlSchema() {
140 super.setupCreateWithWrongXmlSchema();
142 // Submit the request to the service and store the response.
143 String url = getServiceRootURL();
144 PostMethod method = new PostMethod(url);
145 final String WRONG_SCHEMA_DATA = "<wrong_schema>wrong schema contents</wrong_schema>";
146 StringRequestEntity entity = getXmlEntity(WRONG_SCHEMA_DATA);
147 int statusCode = submitRequest(method, entity);
149 // Check the status code of the response: does it match the expected response(s)?
150 verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
151 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
152 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
153 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
156 // ---------------------------------------------------------------
157 // CRUD tests : READ tests
158 // ---------------------------------------------------------------
163 @Test(dependsOnMethods = {"create"})
169 // Submit the request to the service and store the response.
170 ClientResponse<CollectionObject> res =
171 client.getCollectionObject(knownObjectId);
172 int statusCode = res.getStatus();
174 // Check the status code of the response: does it match the expected response(s)?
175 verbose("read: status = " + statusCode);
176 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
177 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
178 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
182 @Test(dependsOnMethods = {"read"})
183 public void readNonExistent() {
186 super.setupReadNonExistent();
188 // Submit the request to the service and store the response.
189 ClientResponse<CollectionObject> res =
190 client.getCollectionObject(NON_EXISTENT_ID);
191 int statusCode = res.getStatus();
193 // Check the status code of the response: does it match the expected response(s)?
194 verbose("readNonExistent: status = " + res.getStatus());
195 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
196 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
197 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
201 // ---------------------------------------------------------------
202 // CRUD tests : READ (list, or multiple) tests
203 // ---------------------------------------------------------------
208 @Test(dependsOnMethods = {"createMultiple"})
209 public void readList() {
212 super.setupReadList();
214 // Submit the request to the service and store the response.
215 ClientResponse<CollectionObjectList> res = client.getCollectionObjectList();
216 CollectionObjectList coList = res.getEntity();
217 int statusCode = res.getStatus();
219 // Check the status code of the response: does it match the expected response(s)?
220 verbose("readList: status = " + res.getStatus());
221 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
222 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
223 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
225 // Optionally output additional data about list members for debugging.
226 boolean iterateThroughList = false;
227 if (iterateThroughList && logger.isDebugEnabled()) {
228 List<CollectionObjectList.CollectionObjectListItem> coItemList =
229 coList.getCollectionObjectListItem();
231 for(CollectionObjectList.CollectionObjectListItem pli : coItemList){
232 verbose("readList: list-item[" + i + "] csid=" + pli.getCsid());
233 verbose("readList: list-item[" + i + "] objectNumber=" + pli.getObjectNumber());
234 verbose("readList: list-item[" + i + "] URI=" + pli.getUri());
246 // ---------------------------------------------------------------
247 // CRUD tests : UPDATE tests
248 // ---------------------------------------------------------------
253 @Test(dependsOnMethods = {"create"})
254 public void update() {
259 // Retrieve an existing resource that we can update.
260 ClientResponse<CollectionObject> res =
261 client.getCollectionObject(knownObjectId);
262 verbose("read: status = " + res.getStatus());
263 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
264 CollectionObject collectionObject = res.getEntity();
265 verbose("Got object to update with ID: " + knownObjectId,
266 collectionObject, CollectionObject.class);
268 // Update the content of this resource.
269 //collectionObject.setCsid("updated-" + knownObjectId);
270 collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
271 collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
273 // Submit the request to the service and store the response.
274 res = client.updateCollectionObject(knownObjectId, collectionObject);
275 int statusCode = res.getStatus();
276 CollectionObject updatedCollectionObject = res.getEntity();
278 // Check the status code of the response: does it match the expected response(s)?
279 verbose("update: status = " + res.getStatus());
280 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
281 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
282 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
284 // Check the contents of the response: does it match what was submitted?
285 verbose("update: ", updatedCollectionObject, CollectionObject.class);
286 Assert.assertEquals(updatedCollectionObject.getObjectName(),
287 collectionObject.getObjectName(), "Data in updated object did not match submitted data.");
291 @Test(dependsOnMethods = {"create", "testSubmitRequest"})
292 public void updateWithMalformedXml() {
295 super.setupUpdateWithMalformedXml();
297 // Submit the request to the service and store the response.
298 String url = getResourceURL(knownObjectId);
299 PutMethod method = new PutMethod(url);
300 final String MALFORMED_XML_DATA =
301 "<malformed_xml>wrong schema contents</malformed_xml"; // Note: intentionally missing bracket.
302 StringRequestEntity entity = getXmlEntity(MALFORMED_XML_DATA);
303 int statusCode = submitRequest(method, entity);
305 // Check the status code of the response: does it match the expected response(s)?
306 verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
307 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
308 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
309 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
312 @Test(dependsOnMethods = {"create", "testSubmitRequest"}) // , "createWithMalformedXml"})
313 public void updateWithWrongXmlSchema() {
316 super.setupUpdateWithWrongXmlSchema();
318 // @TODO This test is currently commented out, because it returns a
319 // 500 Internal Server Error status code, rather than the expected status code.
321 // Submit the request to the service and store the response.
322 String url = getResourceURL(knownObjectId);
323 PutMethod method = new PutMethod(url);
324 final String WRONG_SCHEMA_DATA = "<wrong_schema>wrong schema contents</wrong_schema>";
325 StringRequestEntity entity = getXmlEntity(WRONG_SCHEMA_DATA);
326 int statusCode = submitRequest(method, entity);
328 // Check the status code of the response: does it match the expected response(s)?
329 verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
330 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
331 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
332 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
335 @Test(dependsOnMethods = {"update"})
336 public void updateNonExistent() {
339 super.setupUpdateNonExistent();
341 // Submit the request to the service and store the response.
342 // Note: The ID used in this 'create' call may be arbitrary.
343 // The only relevant ID may be the one used in updateCollectionObject(), below.
344 CollectionObject collectionObject = createCollectionObject(NON_EXISTENT_ID);
345 ClientResponse<CollectionObject> res =
346 client.updateCollectionObject(NON_EXISTENT_ID, collectionObject);
347 int statusCode = res.getStatus();
349 // Check the status code of the response: does it match the expected response(s)?
350 verbose("updateNonExistent: status = " + res.getStatus());
351 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
352 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
353 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
357 // ---------------------------------------------------------------
358 // CRUD tests : DELETE tests
359 // ---------------------------------------------------------------
363 @Test(dependsOnMethods =
364 {"create", "read", "testSubmitRequest", "update"})
365 public void delete() {
370 // Submit the request to the service and store the response.
371 ClientResponse<Response> res = client.deleteCollectionObject(knownObjectId);
372 int statusCode = res.getStatus();
374 // Check the status code of the response: does it match the expected response(s)?
375 verbose("delete: status = " + res.getStatus());
376 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
377 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
378 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
383 @Test(dependsOnMethods = {"delete"})
384 public void deleteNonExistent() {
387 super.setupDeleteNonExistent();
389 // Expected status code: 404 Not Found
390 final int EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
392 // Type of service request being tested
393 final ServiceRequestType REQUEST_TYPE = ServiceRequestType.DELETE;
395 // Submit the request to the service and store the response.
396 ClientResponse<Response> res =
397 client.deleteCollectionObject(NON_EXISTENT_ID);
398 int statusCode = res.getStatus();
400 // Check the status code of the response: does it match the expected response(s)?
401 verbose("deleteNonExistent: status = " + res.getStatus());
402 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
403 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
404 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
408 // ---------------------------------------------------------------
409 // Utility tests : tests of code used in tests above
410 // ---------------------------------------------------------------
413 * Tests the HttpClient-based code used to submit data, in various methods below.
415 @Test(dependsOnMethods = {"create", "read"})
416 public void testSubmitRequest() {
418 // Expected status code: 200 OK
419 final int EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
421 // Submit the request to the service and store the response.
422 String url = getResourceURL(knownObjectId);
423 GetMethod method = new GetMethod(url);
424 int statusCode = submitRequest(method);
426 // Check the status code of the response: does it match the expected response(s)?
427 verbose("testSubmitRequest: url=" + url + " status=" + statusCode);
428 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
433 // ---------------------------------------------------------------
434 // Utility methods used by tests above
435 // ---------------------------------------------------------------
437 private CollectionObject createCollectionObject(String identifier) {
438 CollectionObject collectionObject = createCollectionObject("objectNumber-" + identifier,
439 "objectName-" + identifier);
440 return collectionObject;
443 private CollectionObject createCollectionObject(String objectNumber, String objectName) {
444 CollectionObject collectionObject = new CollectionObject();
445 collectionObject.setObjectNumber(objectNumber);
446 collectionObject.setObjectName(objectName);
447 return collectionObject;
451 public String getServicePathComponent() {
452 // @TODO Determine if it is possible to obtain this value programmatically.
453 // We set this in an annotation in the CollectionObjectProxy interface, for instance.
454 // We also set service-specific constants in each service module.
455 final String SERVICE_PATH_COMPONENT = "collectionobjects";
456 return SERVICE_PATH_COMPONENT;