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.
23 package org.collectionspace.services.client.test;
25 import java.util.List;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
29 import org.collectionspace.services.client.CollectionObjectClient;
30 import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
31 import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionObjectNaturalhistory;
32 import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
34 import org.jboss.resteasy.client.ClientResponse;
36 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
37 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
38 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
39 import org.testng.Assert;
40 import org.testng.annotations.Test;
43 * CollectionObjectServiceTest, carries out tests against a
44 * deployed and running CollectionObject Service.
46 * $LastChangedRevision$
49 public class CollectionObjectServiceTest extends AbstractServiceTest {
51 // Instance variables specific to this test.
52 private CollectionObjectClient client = new CollectionObjectClient();
53 private String knownResourceId = null;
56 * This method is called only by the parent class, AbstractServiceTest
59 public String getServicePathComponent() {
60 return client.getServicePathComponent();
63 // ---------------------------------------------------------------
64 // CRUD tests : CREATE tests
65 // ---------------------------------------------------------------
69 public void create() {
71 // Perform setup, such as initializing the type of service request
72 // (e.g. CREATE, DELETE), its valid and expected status codes, and
73 // its associated HTTP method name (e.g. POST, DELETE).
76 // Submit the request to the service and store the response.
77 String identifier = createIdentifier();
79 MultipartOutput multipart = createCollectionObjectInstance(client.getCommonPartName(), identifier);
80 ClientResponse<Response> res = client.create(multipart);
82 int statusCode = res.getStatus();
84 // Check the status code of the response: does it match
85 // the expected response(s)?
88 // Does it fall within the set of valid status codes?
89 // Does it exactly match the expected status code?
90 verbose("create: status = " + statusCode);
91 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
92 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
93 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
95 // Store the ID returned from this create operation
96 // for additional tests below.
97 knownResourceId = extractId(res);
98 verbose("create: knownResourceId=" + knownResourceId);
102 @Test(dependsOnMethods = {"create"})
103 public void createList() {
104 for(int i = 0; i < 3; i++){
110 // Placeholders until the three tests below can be uncommented.
111 // See Issue CSPACE-401.
112 public void createWithEmptyEntityBody() {}
113 public void createWithMalformedXml() {}
114 public void createWithWrongXmlSchema() {}
118 @Test(dependsOnMethods = {"create", "testSubmitRequest"})
119 public void createWithEmptyEntityBody() {
122 setupCreateWithEmptyEntityBody();
124 // Submit the request to the service and store the response.
125 String method = REQUEST_TYPE.httpMethodName();
126 String url = getServiceRootURL();
127 String mediaType = MediaType.APPLICATION_XML;
128 final String entity = "";
129 int statusCode = submitRequest(method, url, mediaType, entity);
131 // Check the status code of the response: does it match
132 // the expected response(s)?
133 verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
134 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
135 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
136 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
140 @Test(dependsOnMethods = {"create", "testSubmitRequest"})
141 public void createWithMalformedXml() {
144 setupCreateWithMalformedXml();
146 // Submit the request to the service and store the response.
147 String method = REQUEST_TYPE.httpMethodName();
148 String url = getServiceRootURL();
149 String mediaType = MediaType.APPLICATION_XML;
150 final String entity = MALFORMED_XML_DATA; // Constant from base class.
151 int statusCode = submitRequest(method, url, mediaType, entity);
153 // Check the status code of the response: does it match
154 // the expected response(s)?
155 verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
156 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
157 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
158 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
162 @Test(dependsOnMethods = {"create", "testSubmitRequest"})
163 public void createWithWrongXmlSchema() {
166 setupCreateWithWrongXmlSchema();
168 // Submit the request to the service and store the response.
169 String method = REQUEST_TYPE.httpMethodName();
170 String url = getServiceRootURL();
171 String mediaType = MediaType.APPLICATION_XML;
172 final String entity = WRONG_XML_SCHEMA_DATA;
173 int statusCode = submitRequest(method, url, mediaType, entity);
175 // Check the status code of the response: does it match
176 // the expected response(s)?
177 verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
178 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
179 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
180 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
184 // ---------------------------------------------------------------
185 // CRUD tests : READ tests
186 // ---------------------------------------------------------------
189 @Test(dependsOnMethods = {"create"})
195 // Submit the request to the service and store the response.
196 ClientResponse<MultipartInput> res = client.read(knownResourceId);
197 int statusCode = res.getStatus();
199 // Check the status code of the response: does it match
200 // the expected response(s)?
201 verbose("read: status = " + statusCode);
202 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
203 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
204 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
205 //FIXME: remove the following try catch once Aron fixes signatures
207 MultipartInput input = (MultipartInput) res.getEntity();
208 CollectionobjectsCommon collectionObject = (CollectionobjectsCommon) extractPart(input,
209 client.getCommonPartName(), CollectionobjectsCommon.class);
210 Assert.assertNotNull(collectionObject);
212 throw new RuntimeException(e);
219 @Test(dependsOnMethods = {"read"})
220 public void readNonExistent() {
223 setupReadNonExistent();
225 // Submit the request to the service and store the response.
226 ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
227 int statusCode = res.getStatus();
229 // Check the status code of the response: does it match
230 // the expected response(s)?
231 verbose("readNonExistent: status = " + res.getStatus());
232 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
233 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
234 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
237 // ---------------------------------------------------------------
238 // CRUD tests : READ_LIST tests
239 // ---------------------------------------------------------------
242 @Test(dependsOnMethods = {"createList", "read"})
243 public void readList() {
247 // Submit the request to the service and store the response.
248 ClientResponse<CollectionobjectsCommonList> res = client.readList();
249 CollectionobjectsCommonList list = res.getEntity();
251 int statusCode = res.getStatus();
253 // Check the status code of the response: does it match
254 // the expected response(s)?
255 verbose("readList: status = " + res.getStatus());
256 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
257 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
258 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
260 // Optionally output additional data about list members for debugging.
261 boolean iterateThroughList = false;
262 if (iterateThroughList && logger.isDebugEnabled()) {
263 List<CollectionobjectsCommonList.CollectionObjectListItem> items =
264 list.getCollectionObjectListItem();
267 for(CollectionobjectsCommonList.CollectionObjectListItem item : items){
268 verbose("readList: list-item[" + i + "] csid=" +
270 verbose("readList: list-item[" + i + "] objectNumber=" +
271 item.getObjectNumber());
272 verbose("readList: list-item[" + i + "] URI=" +
281 // ---------------------------------------------------------------
282 // CRUD tests : UPDATE tests
283 // ---------------------------------------------------------------
286 @Test(dependsOnMethods = {"read"})
287 public void update() {
291 try{ //ideally, just remove try-catch and let the exception bubble up
292 // Retrieve an existing resource that we can update.
293 ClientResponse<MultipartInput> res =
294 client.read(knownResourceId);
295 verbose("update: read status = " + res.getStatus());
296 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
298 verbose("got object to update with ID: " + knownResourceId);
299 MultipartInput input = (MultipartInput) res.getEntity();
300 CollectionobjectsCommon collectionObject = (CollectionobjectsCommon) extractPart(input,
301 client.getCommonPartName(), CollectionobjectsCommon.class);
302 Assert.assertNotNull(collectionObject);
304 // Update the content of this resource.
305 collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
306 collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
307 verbose("updated object", collectionObject, CollectionobjectsCommon.class);
308 // Submit the request to the service and store the response.
309 MultipartOutput output = new MultipartOutput();
310 OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
311 commonPart.getHeaders().add("label", client.getCommonPartName());
313 res = client.update(knownResourceId, output);
314 int statusCode = res.getStatus();
315 // Check the status code of the response: does it match the expected response(s)?
316 verbose("update: status = " + res.getStatus());
317 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
318 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
319 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
322 input = (MultipartInput) res.getEntity();
323 CollectionobjectsCommon updatedCollectionObject =
324 (CollectionobjectsCommon) extractPart(input,
325 client.getCommonPartName(), CollectionobjectsCommon.class);
326 Assert.assertNotNull(updatedCollectionObject);
328 Assert.assertEquals(updatedCollectionObject.getObjectName(),
329 collectionObject.getObjectName(),
330 "Data in updated object did not match submitted data.");
338 // Placeholders until the three tests below can be uncommented.
339 // See Issue CSPACE-401.
340 public void updateWithEmptyEntityBody() {}
341 public void updateWithMalformedXml() {}
342 public void updateWithWrongXmlSchema() {}
347 @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
348 public void updateWithEmptyEntityBody() {
351 setupUpdateWithEmptyEntityBody();
353 // Submit the request to the service and store the response.
354 String method = REQUEST_TYPE.httpMethodName();
355 String url = getResourceURL(knownResourceId);
356 String mediaType = MediaType.APPLICATION_XML;
357 final String entity = "";
358 int statusCode = submitRequest(method, url, mediaType, entity);
360 // Check the status code of the response: does it match
361 // the expected response(s)?
362 verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
363 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
364 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
365 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
369 @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
370 public void updateWithMalformedXml() {
373 setupUpdateWithMalformedXml();
375 // Submit the request to the service and store the response.
376 String method = REQUEST_TYPE.httpMethodName();
377 String url = getResourceURL(knownResourceId);
378 final String entity = MALFORMED_XML_DATA;
379 String mediaType = MediaType.APPLICATION_XML;
380 int statusCode = submitRequest(method, url, mediaType, entity);
382 // Check the status code of the response: does it match
383 // the expected response(s)?
384 verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
385 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
386 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
387 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
391 @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
392 public void updateWithWrongXmlSchema() {
395 setupUpdateWithWrongXmlSchema();
397 // Submit the request to the service and store the response.
398 String method = REQUEST_TYPE.httpMethodName();
399 String url = getResourceURL(knownResourceId);
400 String mediaType = MediaType.APPLICATION_XML;
401 final String entity = WRONG_XML_SCHEMA_DATA;
402 int statusCode = submitRequest(method, url, mediaType, entity);
404 // Check the status code of the response: does it match
405 // the expected response(s)?
406 verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
407 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
408 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
409 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
414 @Test(dependsOnMethods = {"update", "testSubmitRequest"})
415 public void updateNonExistent() {
418 setupUpdateNonExistent();
420 // Submit the request to the service and store the response.
421 // Note: The ID used in this 'create' call may be arbitrary.
423 // The only relevant ID may be the one used in updateCollectionObject(), below.
424 MultipartOutput multipart = createCollectionObjectInstance(client.getCommonPartName(), NON_EXISTENT_ID);
425 ClientResponse<MultipartInput> res =
426 client.update(NON_EXISTENT_ID, multipart);
428 int statusCode = res.getStatus();
430 // Check the status code of the response: does it match
431 // the expected response(s)?
432 verbose("updateNonExistent: status = " + res.getStatus());
433 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
434 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
435 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
438 // ---------------------------------------------------------------
439 // CRUD tests : DELETE tests
440 // ---------------------------------------------------------------
443 @Test(dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
444 public void delete() {
449 // Submit the request to the service and store the response.
450 ClientResponse<Response> res = client.delete(knownResourceId);
451 int statusCode = res.getStatus();
453 // Check the status code of the response: does it match
454 // the expected response(s)?
455 verbose("delete: status = " + res.getStatus());
456 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
457 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
458 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
463 @Test(dependsOnMethods = {"delete"})
464 public void deleteNonExistent() {
467 setupDeleteNonExistent();
469 // Submit the request to the service and store the response.
470 ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
471 int statusCode = res.getStatus();
473 // Check the status code of the response: does it match
474 // the expected response(s)?
475 verbose("deleteNonExistent: status = " + res.getStatus());
476 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
477 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
478 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
481 // ---------------------------------------------------------------
482 // Utility tests : tests of code used in tests above
483 // ---------------------------------------------------------------
485 * Tests the code for manually submitting data that is used by several
486 * of the methods above.
488 @Test(dependsOnMethods = {"create", "read"})
489 public void testSubmitRequest() {
491 // Expected status code: 200 OK
492 final int EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
494 // Submit the request to the service and store the response.
495 String method = ServiceRequestType.READ.httpMethodName();
496 String url = getResourceURL(knownResourceId);
497 int statusCode = submitRequest(method, url);
499 // Check the status code of the response: does it match
500 // the expected response(s)?
501 verbose("testSubmitRequest: url=" + url + " status=" + statusCode);
502 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
506 // ---------------------------------------------------------------
507 // Utility methods used by tests above
508 // ---------------------------------------------------------------
510 private MultipartOutput createCollectionObjectInstance(String commonPartName, String identifier) {
511 return createCollectionObjectInstance(commonPartName, "objectNumber-" + identifier,
512 "objectName-" + identifier);
515 private MultipartOutput createCollectionObjectInstance(String commonPartName, String objectNumber, String objectName) {
516 CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
518 collectionObject.setObjectNumber(objectNumber);
519 collectionObject.setObjectName(objectName);
520 MultipartOutput multipart = new MultipartOutput();
521 OutputPart commonPart = multipart.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
522 commonPart.getHeaders().add("label", commonPartName);
524 verbose("to be created, collectionobject common ", collectionObject, CollectionobjectsCommon.class);
526 CollectionObjectNaturalhistory conh = new CollectionObjectNaturalhistory();
527 conh.setNhString("test-string");
529 conh.setNhLong(9999);
530 OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
531 nhPart.getHeaders().add("label", getNHPartName());
533 verbose("to be created, collectionobject nhistory", conh, CollectionObjectNaturalhistory.class);
538 private String getNHPartName() {
539 return "collectionobjects-naturalhistory";