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.collectionobject.CollectionObject;
37 import org.collectionspace.services.collectionobject.CollectionObjectList;
38 import org.collectionspace.services.client.CollectionObjectClient;
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: 200 OK
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 * Tests creation of two or more new CollectionObjects.
98 * Expected status code: 200 OK
100 * The newly-created CollectionObjects are also used by other test(s)
101 * (e.g. read multiple/list) which follow, below.
103 @Test(dependsOnMethods = {"createCollectionObject"})
104 public void createCollection() {
105 for(int i = 0; i < 3; i++){
106 this.createCollectionObject();
114 * Tests creation of a CollectionObject by sending a null to the client proxy.
116 * Expected status code: (none)
118 * Expected result: NullPointerException
119 * (Make sure this is a reported exception in the called class.)
122 @Test(dependsOnMethods = {"createCollectionObject"}, expectedExceptions = NullPointerException.class)
123 public void createNullCollectionObject() {
124 ClientResponse<Response> res = collectionObjectClient.createCollectionObject(null);
129 * Tests creation of a CollectionObject by sending data in the wrong format
130 * (i.e. any format that doesn't match the CollectionObject schema) in the
131 * entity body of the request.
133 * Expected status code: 400 Bad Request
136 @Test(dependsOnMethods = {"createCollectionObject"})
137 public void createCollectionObjectWithWrongDataFormat() {
138 // Currently only a stub
143 * Tests creation of a duplicate CollectionObject, whose unique resource identifier
144 * duplicates that of an existing CollectionObject.
146 * Expected status code: 409 Conflict
149 @Test(dependsOnMethods = {"createCollectionObject"})
150 public void createDuplicateCollectionObject() {
151 CollectionObject collectionObject = createCollectionObject(knownCollectionObjectId);
152 ClientResponse<Response> res =
153 collectionObjectClient.createCollectionObject(collectionObject);
154 verbose("createDuplicateCollectionObject: status = " + res.getStatus());
155 Assert.assertEquals(res.getStatus(), Response.Status.CONFLICT.getStatusCode());
159 // ---------------------------------------------------------------
160 // CRUD tests : READ tests
161 // ---------------------------------------------------------------
167 * Tests reading (i.e. retrieval) of a CollectionObject.
169 * Expected status code: 200 OK
172 @Test(dependsOnMethods = {"createCollectionObject"})
173 public void getCollectionObject() {
174 ClientResponse<CollectionObject> res =
175 collectionObjectClient.getCollectionObject(knownCollectionObjectId);
176 verbose("getCollectionObject: status = " + res.getStatus());
177 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
185 * Tests reading (i.e. retrieval) of a non-existent CollectionObject,
186 * whose resource identifier does not exist at the specified URL.
188 * Expected status code: 404 Not Found
191 @Test(dependsOnMethods = {"createCollectionObject"})
192 public void getNonExistentCollectionObject() {
193 ClientResponse<CollectionObject> res =
194 collectionObjectClient.getCollectionObject(NON_EXISTENT_ID);
195 verbose("getNonExistentCollectionObject: status = " + res.getStatus());
196 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
200 // ---------------------------------------------------------------
201 // CRUD tests : READ (list, or multiple) tests
202 // ---------------------------------------------------------------
208 * Tests reading (i.e. retrieval) of a list of multiple CollectionObjects.
210 * Expected status code: 200 OK
212 * Also expected: The entity body in the response contains
213 * a representation of the list of CollectionObjects.
215 @Test(dependsOnMethods = {"createCollection"})
216 public void getCollectionObjectList() {
217 // The resource method is expected to return at least an empty list
218 ClientResponse<CollectionObjectList> res = collectionObjectClient.getCollectionObjectList();
219 CollectionObjectList coList = res.getEntity();
220 verbose("getCollectionObjectList: status = " + res.getStatus());
221 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
223 List<CollectionObjectList.CollectionObjectListItem> coItemList =
224 coList.getCollectionObjectListItem();
226 for(CollectionObjectList.CollectionObjectListItem pli : coItemList){
227 verbose("getCollectionObjectList: list-item[" + i + "] csid=" + pli.getCsid());
228 verbose("getCollectionObjectList: list-item[" + i + "] objectNumber=" + pli.getObjectNumber());
229 verbose("getCollectionObjectList: list-item[" + i + "] URI=" + pli.getUri());
235 * Tests reading (i.e. retrieval) of a list of multiple CollectionObjects
236 * when the contents of the list are expected to be empty.
238 * Expected status code: 200 OK
239 * (Note: *not* 204 No Content)
241 * Also expected: The entity body in the response contains
242 * a representation of an empty list of CollectionObjects.
245 @Test(dependsOnMethods = {"createCollection"})
246 public void getCollectionObjectEmptyList() {
253 // None known at present.
256 // ---------------------------------------------------------------
257 // CRUD tests : UPDATE tests
258 // ---------------------------------------------------------------
264 * Tests updating the content of a CollectionObject.
266 * Expected status code: 200 OK
268 * Also expected: The entity body in the response contains
269 * a representation of the updated CollectionObject.
271 @Test(dependsOnMethods = {"createCollectionObject"})
272 public void updateCollectionObject() {
273 ClientResponse<CollectionObject> res =
274 collectionObjectClient.getCollectionObject(knownCollectionObjectId);
275 verbose("getCollectionObject: status = " + res.getStatus());
276 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
277 CollectionObject collectionObject = res.getEntity();
278 verbose("Got CollectionObject to update with ID: " + knownCollectionObjectId,
279 collectionObject, CollectionObject.class);
281 //collectionObject.setCsid("updated-" + knownCollectionObjectId);
282 collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
283 collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
285 // make call to update service
287 collectionObjectClient.updateCollectionObject(knownCollectionObjectId, collectionObject);
288 verbose("updateCollectionObject: status = " + res.getStatus());
289 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
291 // check the response
292 CollectionObject updatedCollectionObject = res.getEntity();
293 Assert.assertEquals(updatedCollectionObject.getObjectName(),
294 collectionObject.getObjectName());
295 verbose("updateCollectionObject: ", updatedCollectionObject, CollectionObject.class);
302 * Tests updating the content of a non-existent CollectionObject, whose
303 * resource identifier does not exist.
305 * Expected status code: 404 Not Found
307 @Test(dependsOnMethods = {"updateCollectionObject"})
308 public void updateNonExistentCollectionObject() {
309 // Note: The ID used in this call may not be relevant, only the ID used
310 // in updateCollectionObject(), below.
311 CollectionObject collectionObject = createCollectionObject(NON_EXISTENT_ID);
312 // make call to update service
313 ClientResponse<CollectionObject> res =
314 collectionObjectClient.updateCollectionObject(NON_EXISTENT_ID, collectionObject);
315 verbose("createCollectionObject: status = " + res.getStatus());
316 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
320 // ---------------------------------------------------------------
321 // CRUD tests : DELETE tests
322 // ---------------------------------------------------------------
328 * Tests deleting a CollectionObject.
330 * Expected status code: 200 OK
332 @Test(dependsOnMethods = {"createCollectionObject"})
333 public void deleteCollectionObject() {
334 verbose("Calling deleteCollectionObject:" + knownCollectionObjectId);
335 ClientResponse<Response> res = collectionObjectClient.deleteCollectionObject(knownCollectionObjectId);
336 verbose("deleteCollectionObject: status = " + res.getStatus());
337 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
344 * Tests deleting a non-existent CollectionObject, whose
345 * resource identifier does not exist at the specified URL.
347 * Expected status code: 404 Not Found
349 @Test(dependsOnMethods = {"deleteCollectionObject"})
350 public void deleteNonExistentCollectionObject() {
351 verbose("Calling deleteCollectionObject:" + NON_EXISTENT_ID);
352 ClientResponse<Response> res =
353 collectionObjectClient.deleteCollectionObject(NON_EXISTENT_ID);
354 verbose("deleteCollectionObject: status = " + res.getStatus());
355 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
359 // ---------------------------------------------------------------
360 // Utility methods used by tests above
361 // ---------------------------------------------------------------
363 private CollectionObject createCollectionObject(String identifier) {
364 CollectionObject collectionObject = createCollectionObject("objectNumber-" + identifier,
365 "objectName-" + identifier);
367 return collectionObject;
370 private CollectionObject createCollectionObject(String objectNumber, String objectName) {
371 CollectionObject collectionObject = new CollectionObject();
373 collectionObject.setObjectNumber(objectNumber);
374 collectionObject.setObjectName(objectName);
376 return collectionObject;
379 private String extractId(ClientResponse<Response> res) {
380 MultivaluedMap mvm = res.getMetadata();
381 String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
382 verbose("extractId:uri=" + uri);
383 String[] segments = uri.split("/");
384 String id = segments[segments.length - 1];
389 private void verbose(String msg) {
390 // if(logger.isInfoEnabled()){
391 // logger.debug(msg);
393 System.out.println(msg);
396 private void verbose(String msg, Object o, Class clazz) {
399 JAXBContext jc = JAXBContext.newInstance(clazz);
400 Marshaller m = jc.createMarshaller();
401 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
403 m.marshal(o, System.out);
409 private void verboseMap(MultivaluedMap map) {
410 for(Object entry : map.entrySet()){
411 MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry;
412 verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue());
416 private String createIdentifier() {
417 long identifier = System.currentTimeMillis();
418 return Long.toString(identifier);
421 private String createNonExistentIdentifier() {
422 return Long.toString(Long.MAX_VALUE);