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 = CollectionObjectClient.getInstance();
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 // ---------------------------------------------------------------
71 // NOTE The W3C HTTP spec suggests that the URL of the newly-created
72 // resource be returned in the Location header, as well as in the
73 // entity body of the response: <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>.
74 // If we follow this practice in our service, we might also test for the presence of
75 // these URLs in the response headers (e.g. via res.getMetadata().getFirst("Location"))
80 public void createCollectionObject() {
81 String identifier = this.createIdentifier();
83 CollectionObject collectionObject = createCollectionObject(identifier);
84 ClientResponse<Response> res = collectionObjectClient.createCollectionObject(collectionObject);
85 verbose("createCollectionObject: status = " + res.getStatus());
86 Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
88 // Store the ID returned from this create operation for additional tests below.
89 knownCollectionObjectId = extractId(res);
90 knownCollectionObjectId = extractId(res);
93 // Create multiple (used for Read multiple tests, below)
94 @Test(dependsOnMethods = {"createCollectionObject"})
95 public void createCollection() {
96 for(int i = 0; i < 3; i++){
97 this.createCollectionObject();
104 // Create : sending null payload
106 // Create : sending wrong schema in payload
108 // Create : sending random data in payload
110 // Invalid CollectionObject schema
111 // Question: How can we pass an empty entity body, a different (non-CollectionObject) schema,
112 // and/or 'junk' data to the service via the CollectionObjectClient?
114 // Create : with duplicate object ID
116 // Should fail with a 409 Conflict status code.
117 @Test(dependsOnMethods = {"createCollectionObject"})
118 public void createDuplicateCollectionObject() {
119 CollectionObject collectionObject = createCollectionObject(knownCollectionObjectId);
120 ClientResponse<Response> res =
121 collectionObjectClient.createCollectionObject(collectionObject);
122 verbose("createDuplicateCollectionObject: status = " + res.getStatus());
123 Assert.assertEquals(res.getStatus(), Response.Status.CONFLICT.getStatusCode());
127 // ---------------------------------------------------------------
128 // CRUD tests : READ tests
129 // ---------------------------------------------------------------
134 // These two test methods have not yet been tested:
138 @Test(dependsOnMethods = {"createCollectionObject"})
139 public void getCollectionObject() {
140 ClientResponse<CollectionObject> res =
141 collectionObjectClient.getCollectionObject(knownCollectionObjectId);
142 verbose("getCollectionObject: status = " + res.getStatus());
143 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
151 // Read : with non-existent object ID
153 // Should fail with a 404 Not Found status code.
154 @Test(dependsOnMethods = {"createCollectionObject"})
155 public void getNonExistentCollectionObject() {
156 ClientResponse<CollectionObject> res =
157 collectionObjectClient.getCollectionObject(NON_EXISTENT_ID);
158 verbose("getNonExistentCollectionObject: status = " + res.getStatus());
159 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
163 // ---------------------------------------------------------------
164 // CRUD tests : READ (list, or multiple) tests
165 // ---------------------------------------------------------------
171 @Test(dependsOnMethods = {"createCollection"})
172 public void getCollectionObjectList() {
173 // The resource method is expected to return at least an empty list
174 ClientResponse<CollectionObjectList> res = collectionObjectClient.getCollectionObjectList();
175 CollectionObjectList coList = res.getEntity();
176 verbose("getCollectionObjectList: status = " + res.getStatus());
177 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
179 List<CollectionObjectList.CollectionObjectListItem> coItemList =
180 coList.getCollectionObjectListItem();
182 for(CollectionObjectList.CollectionObjectListItem pli : coItemList){
183 verbose("getCollectionObjectList: list-item[" + i + "] csid=" + pli.getCsid());
184 verbose("getCollectionObjectList: list-item[" + i + "] objectNumber=" + pli.getObjectNumber());
185 verbose("getCollectionObjectList: list-item[" + i + "] URI=" + pli.getUri());
195 // ---------------------------------------------------------------
196 // CRUD tests : UPDATE tests
197 // ---------------------------------------------------------------
203 @Test(dependsOnMethods = {"createCollectionObject"})
204 public void updateCollectionObject() {
205 ClientResponse<CollectionObject> res =
206 collectionObjectClient.getCollectionObject(knownCollectionObjectId);
207 verbose("getCollectionObject: status = " + res.getStatus());
208 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
209 CollectionObject collectionObject = res.getEntity();
210 verbose("Got CollectionObject to update with ID: " + knownCollectionObjectId,
211 collectionObject, CollectionObject.class);
213 //collectionObject.setCsid("updated-" + knownCollectionObjectId);
214 collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
215 collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
217 // make call to update service
219 collectionObjectClient.updateCollectionObject(knownCollectionObjectId, collectionObject);
220 verbose("updateCollectionObject: status = " + res.getStatus());
221 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
223 // check the response
224 CollectionObject updatedCollectionObject = res.getEntity();
225 Assert.assertEquals(updatedCollectionObject.getObjectName(),
226 collectionObject.getObjectName());
227 verbose("updateCollectionObject: ", updatedCollectionObject, CollectionObject.class);
233 // Update : with non-existent object ID
235 // Should fail with a 404 Not Found status code.
236 @Test(dependsOnMethods = {"updateCollectionObject"})
237 public void updateNonExistentCollectionObject() {
238 CollectionObject collectionObject = createCollectionObject(NON_EXISTENT_ID);
239 // make call to update service
240 ClientResponse<CollectionObject> res =
241 collectionObjectClient.updateCollectionObject(NON_EXISTENT_ID, collectionObject);
242 verbose("createCollectionObject: status = " + res.getStatus());
243 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
247 // ---------------------------------------------------------------
248 // CRUD tests : DELETE tests
249 // ---------------------------------------------------------------
255 @Test(dependsOnMethods = {"createCollectionObject"})
256 public void deleteCollectionObject() {
257 verbose("Calling deleteCollectionObject:" + knownCollectionObjectId);
258 ClientResponse<Response> res = collectionObjectClient.deleteCollectionObject(knownCollectionObjectId);
259 verbose("deleteCollectionObject: status = " + res.getStatus());
260 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
266 // Delete : with non-existent object ID
268 // Should fail with a 404 Not Found status code.
269 @Test(dependsOnMethods = {"deleteCollectionObject"})
270 public void deleteNonExistentCollectionObject() {
271 verbose("Calling deleteCollectionObject:" + NON_EXISTENT_ID);
272 ClientResponse<Response> res =
273 collectionObjectClient.deleteCollectionObject(NON_EXISTENT_ID);
274 verbose("deleteCollectionObject: status = " + res.getStatus());
275 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
279 // ---------------------------------------------------------------
280 // Utility methods used by tests above
281 // ---------------------------------------------------------------
283 private CollectionObject createCollectionObject(String identifier) {
284 CollectionObject collectionObject = createCollectionObject("objectNumber-" + identifier,
285 "objectName-" + identifier);
287 return collectionObject;
290 private CollectionObject createCollectionObject(String objectNumber, String objectName) {
291 CollectionObject collectionObject = new CollectionObject();
293 collectionObject.setObjectNumber(objectNumber);
294 collectionObject.setObjectName(objectName);
296 return collectionObject;
299 private String extractId(ClientResponse<Response> res) {
300 MultivaluedMap mvm = res.getMetadata();
301 String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
302 String[] segments = uri.split("/");
303 String id = segments[segments.length - 1];
308 private void verbose(String msg) {
309 // if(logger.isInfoEnabled()){
310 // logger.debug(msg);
312 System.out.println(msg);
315 private void verbose(String msg, Object o, Class clazz) {
318 JAXBContext jc = JAXBContext.newInstance(clazz);
319 Marshaller m = jc.createMarshaller();
320 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
322 m.marshal(o, System.out);
328 private void verboseMap(MultivaluedMap map) {
329 for(Object entry : map.entrySet()){
330 MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry;
331 verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue());
335 private String createIdentifier() {
336 long identifier = System.currentTimeMillis();
337 return Long.toString(identifier);
340 private String createNonExistentIdentifier() {
341 return Long.toString(Long.MAX_VALUE);