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.ArrayList;
26 import java.util.List;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
30 import org.collectionspace.services.client.CollectionSpaceClient;
31 import org.collectionspace.services.client.DimensionClient;
32 import org.collectionspace.services.dimension.DimensionsCommon;
33 import org.collectionspace.services.dimension.DimensionsCommonList;
34 import org.collectionspace.services.jaxb.AbstractCommonList;
36 import org.jboss.resteasy.client.ClientResponse;
38 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
39 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
40 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
41 import org.testng.Assert;
42 import org.testng.annotations.AfterClass;
43 import org.testng.annotations.Test;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
49 * DimensionServiceTest, carries out tests against a
50 * deployed and running Dimension Service.
52 * $LastChangedRevision: 917 $
53 * $LastChangedDate: 2009-11-06 12:20:28 -0800 (Fri, 06 Nov 2009) $
55 public class DimensionServiceTest extends AbstractServiceTestImpl {
57 private final Logger logger =
58 LoggerFactory.getLogger(DimensionServiceTest.class);
60 // Instance variables specific to this test.
61 final String SERVICE_PATH_COMPONENT = "dimensions";
62 private String knownResourceId = null;
63 private List<String> allResourceIdsCreated = new ArrayList<String>();
66 * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
69 protected CollectionSpaceClient getClientInstance() {
70 return new DimensionClient();
74 * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
77 protected AbstractCommonList getAbstractCommonList(
78 ClientResponse<AbstractCommonList> response) {
79 return response.getEntity(DimensionsCommonList.class);
82 // ---------------------------------------------------------------
83 // CRUD tests : CREATE tests
84 // ---------------------------------------------------------------
87 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class)
88 public void create(String testName) throws Exception {
90 // Perform setup, such as initializing the type of service request
91 // (e.g. CREATE, DELETE), its valid and expected status codes, and
92 // its associated HTTP method name (e.g. POST, DELETE).
93 setupCreate(testName);
95 // Submit the request to the service and store the response.
96 DimensionClient client = new DimensionClient();
97 String identifier = createIdentifier();
98 MultipartOutput multipart = createDimensionInstance(identifier);
99 ClientResponse<Response> res = client.create(multipart);
101 int statusCode = res.getStatus();
103 // Check the status code of the response: does it match
104 // the expected response(s)?
107 // Does it fall within the set of valid status codes?
108 // Does it exactly match the expected status code?
109 if(logger.isDebugEnabled()){
110 logger.debug(testName + ": status = " + statusCode);
112 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
113 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
114 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
116 // Store the ID returned from the first resource created
117 // for additional tests below.
118 if (knownResourceId == null){
119 knownResourceId = extractId(res);
120 if (logger.isDebugEnabled()) {
121 logger.debug(testName + ": knownResourceId=" + knownResourceId);
125 // Store the IDs from every resource created by tests,
126 // so they can be deleted after tests have been run.
127 allResourceIdsCreated.add(extractId(res));
131 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
132 dependsOnMethods = {"create"})
133 public void createList(String testName) throws Exception {
134 for(int i = 0; i < 3; i++){
140 // Placeholders until the three tests below can be uncommented.
141 // See Issue CSPACE-401.
143 public void createWithEmptyEntityBody(String testName) throws Exception {
147 public void createWithMalformedXml(String testName) throws Exception {
151 public void createWithWrongXmlSchema(String testName) throws Exception {
156 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
157 dependsOnMethods = {"create", "testSubmitRequest"})
158 public void createWithEmptyEntityBody(String testName) throws Exception {
161 setupCreateWithEmptyEntityBody(testName);
163 // Submit the request to the service and store the response.
164 String method = REQUEST_TYPE.httpMethodName();
165 String url = getServiceRootURL();
166 String mediaType = MediaType.APPLICATION_XML;
167 final String entity = "";
168 int statusCode = submitRequest(method, url, mediaType, entity);
170 // Check the status code of the response: does it match
171 // the expected response(s)?
172 if(logger.isDebugEnabled()){
173 logger.debug("createWithEmptyEntityBody url=" + url +
174 " status=" + statusCode);
176 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
177 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
178 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
182 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
183 dependsOnMethods = {"create", "testSubmitRequest"})
184 public void createWithMalformedXml(String testName) throws Exception {
187 setupCreateWithMalformedXml(testName);
189 // Submit the request to the service and store the response.
190 String method = REQUEST_TYPE.httpMethodName();
191 String url = getServiceRootURL();
192 String mediaType = MediaType.APPLICATION_XML;
193 final String entity = MALFORMED_XML_DATA; // Constant from base class.
194 int statusCode = submitRequest(method, url, mediaType, entity);
196 // Check the status code of the response: does it match
197 // the expected response(s)?
198 if(logger.isDebugEnabled()){
199 logger.debug(testName + ": url=" + url +
200 " status=" + statusCode);
202 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
203 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
204 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
208 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
209 dependsOnMethods = {"create", "testSubmitRequest"})
210 public void createWithWrongXmlSchema(String testName) throws Exception {
213 setupCreateWithWrongXmlSchema(testName);
215 // Submit the request to the service and store the response.
216 String method = REQUEST_TYPE.httpMethodName();
217 String url = getServiceRootURL();
218 String mediaType = MediaType.APPLICATION_XML;
219 final String entity = WRONG_XML_SCHEMA_DATA;
220 int statusCode = submitRequest(method, url, mediaType, entity);
222 // Check the status code of the response: does it match
223 // the expected response(s)?
224 if(logger.isDebugEnabled()){
225 logger.debug(testName + ": url=" + url +
226 " status=" + statusCode);
228 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
229 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
230 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
234 // ---------------------------------------------------------------
235 // CRUD tests : READ tests
236 // ---------------------------------------------------------------
239 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
240 dependsOnMethods = {"create"})
241 public void read(String testName) throws Exception {
246 // Submit the request to the service and store the response.
247 DimensionClient client = new DimensionClient();
248 ClientResponse<MultipartInput> res = client.read(knownResourceId);
249 int statusCode = res.getStatus();
251 // Check the status code of the response: does it match
252 // the expected response(s)?
253 if(logger.isDebugEnabled()){
254 logger.debug(testName + ": status = " + statusCode);
256 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
257 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
258 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
260 MultipartInput input = (MultipartInput) res.getEntity();
261 DimensionsCommon dimension = (DimensionsCommon) extractPart(input,
262 client.getCommonPartName(), DimensionsCommon.class);
263 Assert.assertNotNull(dimension);
268 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
269 dependsOnMethods = {"read"})
270 public void readNonExistent(String testName) throws Exception {
273 setupReadNonExistent(testName);
275 // Submit the request to the service and store the response.
276 DimensionClient client = new DimensionClient();
277 ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
278 int statusCode = res.getStatus();
280 // Check the status code of the response: does it match
281 // the expected response(s)?
282 if(logger.isDebugEnabled()){
283 logger.debug(testName + ": status = " + statusCode);
285 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
286 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
287 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
290 // ---------------------------------------------------------------
291 // CRUD tests : READ_LIST tests
292 // ---------------------------------------------------------------
295 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
296 dependsOnMethods = {"read"})
297 public void readList(String testName) throws Exception {
300 setupReadList(testName);
302 // Submit the request to the service and store the response.
303 DimensionClient client = new DimensionClient();
304 ClientResponse<DimensionsCommonList> res = client.readList();
305 DimensionsCommonList list = res.getEntity();
306 int statusCode = res.getStatus();
308 // Check the status code of the response: does it match
309 // the expected response(s)?
310 if(logger.isDebugEnabled()){
311 logger.debug(testName + ": status = " + statusCode);
313 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
314 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
315 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
317 // Optionally output additional data about list members for debugging.
318 boolean iterateThroughList = false;
319 if(iterateThroughList && logger.isDebugEnabled()){
320 List<DimensionsCommonList.DimensionListItem> items =
321 list.getDimensionListItem();
323 for(DimensionsCommonList.DimensionListItem item : items){
324 logger.debug(testName + ": list-item[" + i + "] csid=" +
326 logger.debug(testName + ": list-item[" + i + "] objectNumber=" +
327 item.getDimension());
328 logger.debug(testName + ": list-item[" + i + "] URI=" +
338 // ---------------------------------------------------------------
339 // CRUD tests : UPDATE tests
340 // ---------------------------------------------------------------
343 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
344 dependsOnMethods = {"read"})
345 public void update(String testName) throws Exception {
348 setupUpdate(testName);
350 // Retrieve the contents of a resource to update.
351 DimensionClient client = new DimensionClient();
352 ClientResponse<MultipartInput> res =
353 client.read(knownResourceId);
354 if(logger.isDebugEnabled()){
355 logger.debug(testName + ": read status = " + res.getStatus());
357 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
359 if(logger.isDebugEnabled()){
360 logger.debug("got object to update with ID: " + knownResourceId);
362 MultipartInput input = (MultipartInput) res.getEntity();
363 DimensionsCommon dimension = (DimensionsCommon) extractPart(input,
364 client.getCommonPartName(), DimensionsCommon.class);
365 Assert.assertNotNull(dimension);
367 // Update the content of this resource.
368 dimension.setValue("updated-" + dimension.getValue());
369 dimension.setValueDate("updated-" + dimension.getValueDate());
370 if(logger.isDebugEnabled()){
371 logger.debug("to be updated object");
372 logger.debug(objectAsXmlString(dimension, DimensionsCommon.class));
374 // Submit the request to the service and store the response.
375 MultipartOutput output = new MultipartOutput();
376 OutputPart commonPart = output.addPart(dimension, MediaType.APPLICATION_XML_TYPE);
377 commonPart.getHeaders().add("label", client.getCommonPartName());
379 res = client.update(knownResourceId, output);
380 int statusCode = res.getStatus();
381 // Check the status code of the response: does it match the expected response(s)?
382 if(logger.isDebugEnabled()){
383 logger.debug(testName + ": status = " + statusCode);
385 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
386 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
387 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
390 input = (MultipartInput) res.getEntity();
391 DimensionsCommon updatedDimension =
392 (DimensionsCommon) extractPart(input,
393 client.getCommonPartName(), DimensionsCommon.class);
394 Assert.assertNotNull(updatedDimension);
396 Assert.assertEquals(updatedDimension.getValueDate(),
397 dimension.getValueDate(),
398 "Data in updated object did not match submitted data.");
403 // Placeholders until the three tests below can be uncommented.
404 // See Issue CSPACE-401.
406 public void updateWithEmptyEntityBody(String testName) throws Exception{
409 public void updateWithMalformedXml(String testName) throws Exception {
412 public void updateWithWrongXmlSchema(String testName) throws Exception {
417 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
418 dependsOnMethods = {"create", "update", "testSubmitRequest"})
419 public void updateWithEmptyEntityBody(String testName) throws Exception {
422 setupUpdateWithEmptyEntityBody(testName);
424 // Submit the request to the service and store the response.
425 String method = REQUEST_TYPE.httpMethodName();
426 String url = getResourceURL(knownResourceId);
427 String mediaType = MediaType.APPLICATION_XML;
428 final String entity = "";
429 int statusCode = submitRequest(method, url, mediaType, entity);
431 // Check the status code of the response: does it match
432 // the expected response(s)?
433 if(logger.isDebugEnabled()){
434 logger.debug(testName + ": url=" + url +
435 " status=" + statusCode);
437 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
438 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
439 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
443 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
444 dependsOnMethods = {"create", "update", "testSubmitRequest"})
445 public void updateWithMalformedXml(String testName) throws Exception {
448 setupUpdateWithMalformedXml(testName);
450 // Submit the request to the service and store the response.
451 String method = REQUEST_TYPE.httpMethodName();
452 String url = getResourceURL(knownResourceId);
453 String mediaType = MediaType.APPLICATION_XML;
454 final String entity = MALFORMED_XML_DATA;
455 int statusCode = submitRequest(method, url, mediaType, entity);
457 // Check the status code of the response: does it match
458 // the expected response(s)?
459 if(logger.isDebugEnabled()){
460 logger.debug(testName + ": url=" + url +
461 " status=" + statusCode);
463 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
464 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
465 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
469 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
470 dependsOnMethods = {"create", "update", "testSubmitRequest"})
471 public void updateWithWrongXmlSchema(String testName) throws Exception {
474 setupUpdateWithWrongXmlSchema(testName);
476 // Submit the request to the service and store the response.
477 String method = REQUEST_TYPE.httpMethodName();
478 String url = getResourceURL(knownResourceId);
479 String mediaType = MediaType.APPLICATION_XML;
480 final String entity = WRONG_XML_SCHEMA_DATA;
481 int statusCode = submitRequest(method, url, mediaType, entity);
483 // Check the status code of the response: does it match
484 // the expected response(s)?
485 if(logger.isDebugEnabled()){
486 logger.debug(testName + ": url=" + url +
487 " status=" + statusCode);
489 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
490 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
491 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
496 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
497 dependsOnMethods = {"update", "testSubmitRequest"})
498 public void updateNonExistent(String testName) throws Exception {
501 setupUpdateNonExistent(testName);
503 // Submit the request to the service and store the response.
504 // Note: The ID used in this 'create' call may be arbitrary.
505 // The only relevant ID may be the one used in update(), below.
506 DimensionClient client = new DimensionClient();
507 MultipartOutput multipart = createDimensionInstance(NON_EXISTENT_ID);
508 ClientResponse<MultipartInput> res =
509 client.update(NON_EXISTENT_ID, multipart);
510 int statusCode = res.getStatus();
512 // Check the status code of the response: does it match
513 // the expected response(s)?
514 if(logger.isDebugEnabled()){
515 logger.debug(testName + ": status = " + statusCode);
517 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
518 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
519 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
522 // ---------------------------------------------------------------
523 // CRUD tests : DELETE tests
524 // ---------------------------------------------------------------
527 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
528 dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
529 public void delete(String testName) throws Exception {
532 setupDelete(testName);
534 // Submit the request to the service and store the response.
535 DimensionClient client = new DimensionClient();
536 ClientResponse<Response> res = client.delete(knownResourceId);
537 int statusCode = res.getStatus();
539 // Check the status code of the response: does it match
540 // the expected response(s)?
541 if(logger.isDebugEnabled()){
542 logger.debug(testName + ": status = " + statusCode);
544 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
545 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
546 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
551 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
552 dependsOnMethods = {"delete"})
553 public void deleteNonExistent(String testName) throws Exception {
556 setupDeleteNonExistent(testName);
558 // Submit the request to the service and store the response.
559 DimensionClient client = new DimensionClient();
560 ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
561 int statusCode = res.getStatus();
563 // Check the status code of the response: does it match
564 // the expected response(s)?
565 if(logger.isDebugEnabled()){
566 logger.debug(testName + ": status = " + statusCode);
568 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
569 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
570 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
573 // ---------------------------------------------------------------
574 // Utility tests : tests of code used in tests above
575 // ---------------------------------------------------------------
577 * Tests the code for manually submitting data that is used by several
578 * of the methods above.
580 @Test(dependsOnMethods = {"create", "read"})
581 public void testSubmitRequest() {
583 // Expected status code: 200 OK
584 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
586 // Submit the request to the service and store the response.
587 String method = ServiceRequestType.READ.httpMethodName();
588 String url = getResourceURL(knownResourceId);
589 int statusCode = submitRequest(method, url);
591 // Check the status code of the response: does it match
592 // the expected response(s)?
593 if(logger.isDebugEnabled()){
594 logger.debug("testSubmitRequest: url=" + url +
595 " status=" + statusCode);
597 Assert.assertEquals(statusCode, EXPECTED_STATUS);
601 // ---------------------------------------------------------------
602 // Cleanup of resources created during testing
603 // ---------------------------------------------------------------
606 * Deletes all resources created by tests, after all tests have been run.
608 * This cleanup method will always be run, even if one or more tests fail.
609 * For this reason, it attempts to remove all resources created
610 * at any point during testing, even if some of those resources
611 * may be expected to be deleted by certain tests.
613 @AfterClass(alwaysRun=true)
614 public void cleanUp() {
615 String noTest = System.getProperty("noTestCleanup");
616 if(Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
617 if (logger.isDebugEnabled()) {
618 logger.debug("Skipping Cleanup phase ...");
622 if (logger.isDebugEnabled()) {
623 logger.debug("Cleaning up temporary resources created for testing ...");
625 DimensionClient client = new DimensionClient();
626 for (String resourceId : allResourceIdsCreated) {
627 // Note: Any non-success responses are ignored and not reported.
628 ClientResponse<Response> res = client.delete(resourceId);
632 // ---------------------------------------------------------------
633 // Utility methods used by tests above
634 // ---------------------------------------------------------------
636 public String getServicePathComponent() {
637 return SERVICE_PATH_COMPONENT;
640 private MultipartOutput createDimensionInstance(String identifier) {
641 return createDimensionInstance(
642 "dimensionType-" + identifier,
643 "entryNumber-" + identifier,
644 "entryDate-" + identifier);
647 private MultipartOutput createDimensionInstance(String dimensionType, String entryNumber, String entryDate) {
648 DimensionsCommon dimension = new DimensionsCommon();
649 dimension.setDimension(dimensionType);
650 dimension.setValue(entryNumber);
651 dimension.setValueDate(entryDate);
652 MultipartOutput multipart = new MultipartOutput();
653 OutputPart commonPart =
654 multipart.addPart(dimension, MediaType.APPLICATION_XML_TYPE);
655 commonPart.getHeaders().add("label", new DimensionClient().getCommonPartName());
657 if(logger.isDebugEnabled()){
658 logger.debug("to be created, dimension common");
659 logger.debug(objectAsXmlString(dimension, DimensionsCommon.class));