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.ArrayList;
27 import java.util.List;
28 import javax.ws.rs.core.MultivaluedMap;
29 import javax.ws.rs.core.Response;
30 import javax.xml.bind.JAXBContext;
31 import javax.xml.bind.Marshaller;
32 import org.jboss.resteasy.client.ClientResponse;
33 import org.testng.Assert;
34 import org.testng.annotations.Test;
36 import org.collectionspace.services.client.CollectionObjectClient;
37 import org.collectionspace.services.collectionobject.CollectionObject;
38 import org.collectionspace.services.collectionobject.CollectionObjectList;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * CollectionObjectServiceTest, carries out tests against a
44 * deployed and running CollectionObject Service.
46 * $LastChangedRevision$
49 public class CollectionObjectServiceTest {
51 private CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
52 private String knownCollectionObjectId = null;
53 private final String NON_EXISTENT_ID = createNonExistentIdentifier();
54 final Logger logger = LoggerFactory.getLogger(CollectionObjectServiceTest.class);
57 // ---------------------------------------------------------------
58 // Service Discovery tests
59 // ---------------------------------------------------------------
64 // ---------------------------------------------------------------
65 // CRUD tests : CREATE tests
66 // ---------------------------------------------------------------
72 * Tests creation of a new CollectionObject.
74 * Expected status code: 201 Created
76 * Also expected: The 'Location' header contains the URL for the newly created object.
77 * This is required by the extractId() utility method, below.
79 * The newly-created CollectionObject is also used by other test(s)
80 * (e.g. update, delete) which follow, below.
83 public void createCollectionObject() {
84 String identifier = this.createIdentifier();
86 CollectionObject collectionObject = createCollectionObject(identifier);
87 ClientResponse<Response> res = collectionObjectClient.createCollectionObject(collectionObject);
88 verbose("createCollectionObject: status = " + res.getStatus());
89 Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
91 // Store the ID returned from this create operation for additional tests below.
92 knownCollectionObjectId = extractId(res);
96 * Creates two or more new CollectionObjects.
98 * Repeatedly calls the createCollectionObject test, above, and relies on its
101 * Expected status code: 201 Created
103 * The newly-created CollectionObjects are also used by other test(s)
104 * (e.g. read multiple/list) which follow, below.
106 @Test(dependsOnMethods = {"createCollectionObject"})
107 public void createCollection() {
108 for(int i = 0; i < 3; i++){
109 this.createCollectionObject();
117 * Tests creation of a CollectionObject by sending a null to the client proxy.
119 * Expected status code: (none)
121 * Expected result: IllegalArgumentException
122 * (Make sure this is a reported exception in the called class.)
124 @Test(dependsOnMethods = {"createCollectionObject"}, expectedExceptions = IllegalArgumentException.class)
125 public void createNullCollectionObject() {
126 ClientResponse<Response> res = collectionObjectClient.createCollectionObject(null);
130 * Tests creation of a CollectionObject by sending bad data
131 * (e.g. in a format that doesn't match the CollectionObject schema)
132 * in the entity body of the request.
134 * Expected status code: 400 Bad Request
137 @Test(dependsOnMethods = {"createCollectionObject"})
138 public void createCollectionObjectWithBadData() {
140 // Currently only a stub
145 * Tests creation of a CollectionObject by a user who
146 * is not authorized to perform this action.
148 * Expected status code: 403 Forbidden
151 @Test(dependsOnMethods = {"createCollectionObject"})
152 public void createCollectionObjectWithUnauthorizedUser() {
153 // Currently only a stub
158 * Tests creation of a duplicate CollectionObject, whose unique resource identifier
159 * duplicates that of an existing CollectionObject.
161 * Expected status code: 409 Conflict
164 @Test(dependsOnMethods = {"createCollectionObject"})
165 public void createDuplicateCollectionObject() {
166 CollectionObject collectionObject = createCollectionObject(knownCollectionObjectId);
167 ClientResponse<Response> res =
168 collectionObjectClient.createCollectionObject(collectionObject);
169 verbose("createDuplicateCollectionObject: status = " + res.getStatus());
170 Assert.assertEquals(res.getStatus(), Response.Status.CONFLICT.getStatusCode());
174 // ---------------------------------------------------------------
175 // CRUD tests : READ tests
176 // ---------------------------------------------------------------
182 * Tests reading (i.e. retrieval) of a CollectionObject.
184 * Expected status code: 200 OK
186 @Test(dependsOnMethods = {"createCollectionObject"})
187 public void getCollectionObject() {
188 ClientResponse<CollectionObject> res =
189 collectionObjectClient.getCollectionObject(knownCollectionObjectId);
190 verbose("getCollectionObject: status = " + res.getStatus());
191 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
198 * Tests reading (i.e. retrieval) of a CollectionObject by a user who
199 * is not authorized to perform this action.
201 * Expected status code: 403 Forbidden
204 @Test(dependsOnMethods = {"getCollectionObject"})
205 public void getCollectionObjectWithUnauthorizedUser() {
206 // Currently only a stub
211 * Tests reading (i.e. retrieval) of a non-existent CollectionObject,
212 * whose resource identifier does not exist at the specified URL.
214 * Expected status code: 404 Not Found
216 @Test(dependsOnMethods = {"getCollectionObject"})
217 public void getNonExistentCollectionObject() {
218 ClientResponse<CollectionObject> res =
219 collectionObjectClient.getCollectionObject(NON_EXISTENT_ID);
220 verbose("getNonExistentCollectionObject: status = " + res.getStatus());
221 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
225 // ---------------------------------------------------------------
226 // CRUD tests : READ (list, or multiple) tests
227 // ---------------------------------------------------------------
233 * Tests reading (i.e. retrieval) of a list of multiple CollectionObjects.
235 * Expected status code: 200 OK
237 * Also expected: The entity body in the response contains
238 * a representation of the list of CollectionObjects.
240 @Test(dependsOnMethods = {"createCollection"})
241 public void getCollectionObjectList() {
242 // The resource method is expected to return at least an empty list
243 ClientResponse<CollectionObjectList> res = collectionObjectClient.getCollectionObjectList();
244 CollectionObjectList coList = res.getEntity();
245 verbose("getCollectionObjectList: status = " + res.getStatus());
246 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
248 List<CollectionObjectList.CollectionObjectListItem> coItemList =
249 coList.getCollectionObjectListItem();
251 for(CollectionObjectList.CollectionObjectListItem pli : coItemList){
252 verbose("getCollectionObjectList: list-item[" + i + "] csid=" + pli.getCsid());
253 verbose("getCollectionObjectList: list-item[" + i + "] objectNumber=" + pli.getObjectNumber());
254 verbose("getCollectionObjectList: list-item[" + i + "] URI=" + pli.getUri());
260 * Tests reading (i.e. retrieval) of a list of multiple CollectionObjects
261 * when the contents of the list are expected to be empty.
263 * Expected status code: 200 OK
264 * (Note: *not* 204 No Content)
266 * Also expected: The entity body in the response contains
267 * a representation of an empty list of CollectionObjects.
270 @Test(dependsOnMethods = {"getCollectionObjectList"})
271 public void getCollectionObjectEmptyList() {
272 // Currently only a stub.
280 * Tests reading (i.e. retrieval) of a list of CollectionObjects
281 * when sending unrecognized query parameters with the request.
283 * Expected status code: 400 Bad Request
286 @Test(dependsOnMethods = {"getCollectionObjectList"})
287 public void getCollectionObjectListWithBadParams() {
288 // Currently only a stub.
293 * Tests reading (i.e. retrieval) of a list of CollectionObjects by a user who
294 * is not authorized to perform this action.
296 * Expected status code: 403 Forbidden
299 @Test(dependsOnMethods = {"getCollectionObjectList"})
300 public void getCollectionObjectListWithUnauthorizedUser() {
301 // Currently only a stub.
307 // ---------------------------------------------------------------
308 // CRUD tests : UPDATE tests
309 // ---------------------------------------------------------------
315 * Tests updating the content of a CollectionObject.
317 * Expected status code: 200 OK
319 * Also expected: The entity body in the response contains
320 * a representation of the updated CollectionObject.
322 @Test(dependsOnMethods = {"createCollectionObject"})
323 public void updateCollectionObject() {
324 ClientResponse<CollectionObject> res =
325 collectionObjectClient.getCollectionObject(knownCollectionObjectId);
326 verbose("getCollectionObject: status = " + res.getStatus());
327 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
328 CollectionObject collectionObject = res.getEntity();
329 verbose("Got CollectionObject to update with ID: " + knownCollectionObjectId,
330 collectionObject, CollectionObject.class);
332 //collectionObject.setCsid("updated-" + knownCollectionObjectId);
333 collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
334 collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
336 // make call to update service
338 collectionObjectClient.updateCollectionObject(knownCollectionObjectId, collectionObject);
339 verbose("updateCollectionObject: status = " + res.getStatus());
340 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
342 // check the response
343 CollectionObject updatedCollectionObject = res.getEntity();
344 Assert.assertEquals(updatedCollectionObject.getObjectName(),
345 collectionObject.getObjectName());
346 verbose("updateCollectionObject: ", updatedCollectionObject, CollectionObject.class);
353 * Tests updating the content of a CollectionObject by sending bad data
354 * (e.g. in a format that doesn't match the CollectionObject schema)
355 * in the entity body of the request.
357 * Expected status code: 400 Bad Request
360 @Test(dependsOnMethods = {"updateCollectionObject"})
361 public void updateCollectionObjectWithBadData() {
362 // Currently only a stub.
367 * Tests updating the content of a CollectionObject by a user who
368 * is not authorized to perform this action.
370 * Expected status code: 403 Forbidden
373 @Test(dependsOnMethods = {"updateCollectionObject"})
374 public void updateCollectionObjectWithUnauthorizedUser() {
375 // Currently only a stub.
380 * Tests updating the content of a non-existent CollectionObject, whose
381 * resource identifier does not exist.
383 * Expected status code: 404 Not Found
385 @Test(dependsOnMethods = {"updateCollectionObject"})
386 public void updateNonExistentCollectionObject() {
387 // Note: The ID used in this 'create' call may be arbitrary.
388 // The only relevant ID may be the one used in updateCollectionObject(), below.
389 CollectionObject collectionObject = createCollectionObject(NON_EXISTENT_ID);
390 // make call to update service
391 ClientResponse<CollectionObject> res =
392 collectionObjectClient.updateCollectionObject(NON_EXISTENT_ID, collectionObject);
393 verbose("createCollectionObject: status = " + res.getStatus());
394 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
398 // ---------------------------------------------------------------
399 // CRUD tests : DELETE tests
400 // ---------------------------------------------------------------
406 * Tests deleting a CollectionObject.
408 * Expected status code: 200 OK
410 @Test(dependsOnMethods = {"createCollectionObject"})
411 public void deleteCollectionObject() {
412 verbose("Calling deleteCollectionObject:" + knownCollectionObjectId);
413 ClientResponse<Response> res = collectionObjectClient.deleteCollectionObject(knownCollectionObjectId);
414 verbose("deleteCollectionObject: status = " + res.getStatus());
415 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
422 * Tests deleting a CollectionObject by a user who
423 * is not authorized to perform this action.
425 * Expected status code: 403 Forbidden
428 @Test(dependsOnMethods = {"deleteCollectionObject"})
429 public void deleteCollectionObjectWithUnauthorizedUser() {
430 // Currently only a stub.
435 * Tests deleting a non-existent CollectionObject, whose
436 * resource identifier does not exist at the specified URL.
438 * Expected status code: 404 Not Found
440 @Test(dependsOnMethods = {"deleteCollectionObject"})
441 public void deleteNonExistentCollectionObject() {
442 verbose("Calling deleteCollectionObject:" + NON_EXISTENT_ID);
443 ClientResponse<Response> res =
444 collectionObjectClient.deleteCollectionObject(NON_EXISTENT_ID);
445 verbose("deleteCollectionObject: status = " + res.getStatus());
446 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
450 // ---------------------------------------------------------------
451 // Utility methods used by tests above
452 // ---------------------------------------------------------------
454 private CollectionObject createCollectionObject(String identifier) {
455 CollectionObject collectionObject = createCollectionObject("objectNumber-" + identifier,
456 "objectName-" + identifier);
458 return collectionObject;
461 private CollectionObject createCollectionObject(String objectNumber, String objectName) {
462 CollectionObject collectionObject = new CollectionObject();
464 collectionObject.setObjectNumber(objectNumber);
465 collectionObject.setObjectName(objectName);
467 return collectionObject;
470 private String extractId(ClientResponse<Response> res) {
471 MultivaluedMap mvm = res.getMetadata();
472 String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
473 verbose("extractId:uri=" + uri);
474 String[] segments = uri.split("/");
475 String id = segments[segments.length - 1];
480 private void verbose(String msg) {
481 // if(logger.isInfoEnabled()){
482 // logger.debug(msg);
484 System.out.println(msg);
487 private void verbose(String msg, Object o, Class clazz) {
490 JAXBContext jc = JAXBContext.newInstance(clazz);
491 Marshaller m = jc.createMarshaller();
492 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
494 m.marshal(o, System.out);
500 private void verboseMap(MultivaluedMap map) {
501 for(Object entry : map.entrySet()){
502 MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry;
503 verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue());
507 private String createIdentifier() {
508 long identifier = System.currentTimeMillis();
509 return Long.toString(identifier);
512 private String createNonExistentIdentifier() {
513 return Long.toString(Long.MAX_VALUE);