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.AbstractServiceClientImpl;
30 import org.collectionspace.services.client.CollectionObjectClient;
31 import org.collectionspace.services.client.CollectionObjectFactory;
32 import org.collectionspace.services.client.CollectionSpaceClient;
33 import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
34 import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionobjectsNaturalhistory;
35 import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
36 import org.collectionspace.services.collectionobject.ResponsibleDepartmentList;
37 import org.collectionspace.services.collectionobject.OtherNumber;
38 import org.collectionspace.services.collectionobject.OtherNumberList;
40 import org.collectionspace.services.jaxb.AbstractCommonList;
42 import org.jboss.resteasy.client.ClientResponse;
43 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
44 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
45 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
46 import org.testng.Assert;
47 import org.testng.annotations.Test;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
53 * CollectionObjectServiceTest, carries out tests against a
54 * deployed and running CollectionObject Service.
56 * $LastChangedRevision$
59 public class CollectionObjectServiceTest extends AbstractServiceTestImpl {
62 private final String CLASS_NAME = CollectionObjectServiceTest.class.getName();
63 private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
65 // Instance variables specific to this test.
66 /** The known resource id. */
67 private String knownResourceId = null;
69 /** The multivalue. */
70 private boolean multivalue; //toggle
73 * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
76 protected String getServicePathComponent() {
77 return new CollectionObjectClient().getServicePathComponent();
81 * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
84 protected CollectionSpaceClient getClientInstance() {
85 return new CollectionObjectClient();
89 * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
92 protected AbstractCommonList getAbstractCommonList(
93 ClientResponse<AbstractCommonList> response) {
94 return response.getEntity(CollectionobjectsCommonList.class);
97 // ---------------------------------------------------------------
98 // CRUD tests : CREATE tests
99 // ---------------------------------------------------------------
102 * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String)
105 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
106 public void create(String testName) throws Exception {
108 if (logger.isDebugEnabled()) {
109 logger.debug(testBanner(testName, CLASS_NAME));
111 // Perform setup, such as initializing the type of service request
112 // (e.g. CREATE, DELETE), its valid and expected status codes, and
113 // its associated HTTP method name (e.g. POST, DELETE).
116 // Submit the request to the service and store the response.
117 CollectionObjectClient client = new CollectionObjectClient();
118 String identifier = createIdentifier();
119 MultipartOutput multipart =
120 createCollectionObjectInstance(client.getCommonPartName(), identifier);
121 ClientResponse<Response> res = client.create(multipart);
122 int statusCode = res.getStatus();
124 // Check the status code of the response: does it match
125 // the expected response(s)?
128 // Does it fall within the set of valid status codes?
129 // Does it exactly match the expected status code?
130 if (logger.isDebugEnabled()) {
131 logger.debug(testName + ": status = " + statusCode);
133 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
134 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
135 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
137 // Store the ID returned from the first resource created
138 // for additional tests below.
139 if (knownResourceId == null) {
140 knownResourceId = extractId(res);
141 if (logger.isDebugEnabled()) {
142 logger.debug(testName + ": knownResourceId=" + knownResourceId);
146 // Store the IDs from every resource created by tests,
147 // so they can be deleted after tests have been run.
148 allResourceIdsCreated.add(extractId(res));
153 * Tests to diagnose and verify the fixed status of CSPACE-1026,
154 * "Whitespace at certain points in payload cause failure"
157 * Creates the from xml cambridge.
159 * @param testName the test name
160 * @throws Exception the exception
162 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
163 dependsOnMethods = {"create", "testSubmitRequest"})
164 public void createFromXmlCambridge(String testName) throws Exception {
166 createFromXmlFile(testName, "./test-data/testCambridge.xml", true);
167 testSubmitRequest(newId);
171 * Creates the from xml rfw s1.
173 * @param testName the test name
174 * @throws Exception the exception
176 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
177 dependsOnMethods = {"create", "testSubmitRequest"})
178 public void createFromXmlRFWS1(String testName) throws Exception {
179 String testDataDir = System.getProperty("test-data.fileName");
181 //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp1.xml", false);
182 createFromXmlFile(testName, testDataDir + "/repfield_whitesp1.xml", false);
183 testSubmitRequest(newId);
187 * Creates the from xml rfw s2.
189 * @param testName the test name
190 * @throws Exception the exception
192 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
193 dependsOnMethods = {"create", "testSubmitRequest"})
194 public void createFromXmlRFWS2(String testName) throws Exception {
195 String testDataDir = System.getProperty("test-data.fileName");
197 //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp2.xml", false);
198 createFromXmlFile(testName, testDataDir + "/repfield_whitesp2.xml", false);
199 testSubmitRequest(newId);
203 * Creates the from xml rfw s3.
205 * @param testName the test name
206 * @throws Exception the exception
208 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
209 dependsOnMethods = {"create", "testSubmitRequest"})
210 public void createFromXmlRFWS3(String testName) throws Exception {
211 String testDataDir = System.getProperty("test-data.fileName");
213 //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp3.xml", false);
214 createFromXmlFile(testName, testDataDir + "/repfield_whitesp3.xml", false);
215 testSubmitRequest(newId);
219 * Creates the from xml rfw s4.
221 * @param testName the test name
222 * @throws Exception the exception
224 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
225 dependsOnMethods = {"create", "testSubmitRequest"})
226 public void createFromXmlRFWS4(String testName) throws Exception {
227 String testDataDir = System.getProperty("test-data.fileName");
229 createFromXmlFile(testName, testDataDir + "/repfield_whitesp4.xml", false);
230 testSubmitRequest(newId);
234 * Tests to diagnose and verify the fixed status of CSPACE-1248,
235 * "Wedged records created!" (i.e. records with child repeatable
236 * fields, which contain null values, can be successfully created
237 * but an error occurs on trying to retrieve those records).
240 * Creates the with null value repeatable field.
242 * @param testName the test name
243 * @throws Exception the exception
245 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
246 dependsOnMethods = {"create", "testSubmitRequest"})
247 public void createWithNullValueRepeatableField(String testName) throws Exception {
248 String testDataDir = System.getProperty("test-data.fileName");
250 createFromXmlFile(testName, testDataDir + "/repfield_null1.xml", false);
251 if (logger.isDebugEnabled()) {
252 logger.debug("Successfully created record with null value repeatable field.");
253 logger.debug("Attempting to retrieve just-created record ...");
255 testSubmitRequest(newId);
259 * @see org.collectionspace.services.client.test.ServiceTest#createList()
262 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
263 dependsOnMethods = {"create"})
264 public void createList(String testName) throws Exception {
265 this.createPaginatedList(testName, DEFAULT_LIST_SIZE);
269 // Placeholders until the three tests below can be uncommented.
270 // See Issue CSPACE-401.
272 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithEmptyEntityBody(java.lang.String)
275 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
276 public void createWithEmptyEntityBody(String testName) throws Exception {
277 //FIXME: Should this test really be empty?
281 * Test how the service handles XML that is not well formed,
282 * when sent in the payload of a Create request.
284 * @param testName The name of this test method. This name is supplied
285 * automatically, via reflection, by a TestNG 'data provider' in
289 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
290 public void createWithMalformedXml(String testName) throws Exception {
294 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithWrongXmlSchema(java.lang.String)
297 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
298 public void createWithWrongXmlSchema(String testName) throws Exception {
299 //FIXME: Should this test really be empty?
305 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
306 dependsOnMethods = {"create", "testSubmitRequest"})
307 public void createWithEmptyEntityBody(String testName) throwsException {
309 if (logger.isDebugEnabled()) {
310 logger.debug(testBanner(testName, CLASS_NAME));
313 setupCreateWithEmptyEntityBody();
315 // Submit the request to the service and store the response.
316 String method = REQUEST_TYPE.httpMethodName();
317 String url = getServiceRootURL();
318 String mediaType = MediaType.APPLICATION_XML;
319 final String entity = "";
320 int statusCode = submitRequest(method, url, mediaType, entity);
322 // Check the status code of the response: does it match
323 // the expected response(s)?
324 if(logger.isDebugEnabled()){
325 logger.debug(testName + ": url=" + url +
326 " status=" + statusCode);
328 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
329 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
330 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
334 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
335 dependsOnMethods = {"create", "testSubmitRequest"})
336 public void createWithMalformedXml(String testName) throws Exception {
338 if (logger.isDebugEnabled()) {
339 logger.debug(testBanner(testName, CLASS_NAME));
342 setupCreateWithMalformedXml();
344 // Submit the request to the service and store the response.
345 String method = REQUEST_TYPE.httpMethodName();
346 String url = getServiceRootURL();
347 String mediaType = MediaType.APPLICATION_XML;
348 final String entity = MALFORMED_XML_DATA; // Constant from base class.
349 int statusCode = submitRequest(method, url, mediaType, entity);
351 // Check the status code of the response: does it match
352 // the expected response(s)?
353 if(logger.isDebugEnabled()){
354 logger.debug(testName + ": url=" + url +
355 " status=" + statusCode);
357 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
358 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
359 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
363 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
364 dependsOnMethods = {"create", "testSubmitRequest"})
365 public void createWithWrongXmlSchema(String testName) throws Exception {
367 if (logger.isDebugEnabled()) {
368 logger.debug(testBanner(testName, CLASS_NAME));
371 setupCreateWithWrongXmlSchema();
373 // Submit the request to the service and store the response.
374 String method = REQUEST_TYPE.httpMethodName();
375 String url = getServiceRootURL();
376 String mediaType = MediaType.APPLICATION_XML;
377 final String entity = WRONG_XML_SCHEMA_DATA;
378 int statusCode = submitRequest(method, url, mediaType, entity);
380 // Check the status code of the response: does it match
381 // the expected response(s)?
382 if(logger.isDebugEnabled()){
383 logger.debug(testName + ": url=" + url +
384 " status=" + statusCode);
386 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
387 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
388 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
393 * Test how the service handles, in a Create request, payloads
394 * containing null values (or, in the case of String fields,
395 * empty String values) in one or more fields which must be
396 * present and are required to contain non-empty values.
398 * This is a test of code and/or configuration in the service's
399 * validation routine(s).
401 * @param testName The name of this test method. This name is supplied
402 * automatically, via reflection, by a TestNG 'data provider' in
406 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
407 public void createWithRequiredValuesNullOrEmpty(String testName) throws Exception {
408 if (logger.isDebugEnabled()) {
409 logger.debug(testBanner(testName, CLASS_NAME));
413 // Build a payload with invalid content, by omitting a
414 // field (objectNumber) which must be present, and in which
415 // a non-empty value is required, as enforced by the service's
416 // validation routine(s).
417 CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
418 collectionObject.setTitle("atitle");
419 collectionObject.setObjectName("some name");
421 // Submit the request to the service and store the response.
422 CollectionObjectClient client = new CollectionObjectClient();
423 MultipartOutput multipart =
424 createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
425 ClientResponse<Response> res = client.create(multipart);
426 int statusCode = res.getStatus();
428 // Read the response and verify that the create attempt failed.
429 if (logger.isDebugEnabled()) {
430 logger.debug(testName + ": status = " + statusCode);
432 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
433 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
434 Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
436 // FIXME: Consider splitting off the following into its own test method.
438 // Build a payload with invalid content, by setting a value to the
439 // empty String, in a field that requires a non-empty value,
440 // as enforced by the service's validation routine(s).
441 collectionObject = new CollectionobjectsCommon();
442 collectionObject.setTitle("atitle");
443 collectionObject.setObjectName("some name");
444 collectionObject.setObjectNumber("");
446 // Submit the request to the service and store the response.
448 createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
449 res = client.create(multipart);
450 statusCode = res.getStatus();
452 // Read the response and verify that the create attempt failed.
453 if (logger.isDebugEnabled()) {
454 logger.debug(testName + ": status = " + statusCode);
456 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
457 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
458 Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
463 // ---------------------------------------------------------------
464 // CRUD tests : READ tests
465 // ---------------------------------------------------------------
468 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String)
471 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
472 dependsOnMethods = {"create"})
473 public void read(String testName) throws Exception {
475 if (logger.isDebugEnabled()) {
476 logger.debug(testBanner(testName, CLASS_NAME));
481 // Submit the request to the service and store the response.
482 CollectionObjectClient client = new CollectionObjectClient();
483 ClientResponse<MultipartInput> res = client.read(knownResourceId);
484 int statusCode = res.getStatus();
486 // Check the status code of the response: does it match
487 // the expected response(s)?
488 if (logger.isDebugEnabled()) {
489 logger.debug(testName + ": status = " + statusCode);
491 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
492 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
493 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
495 MultipartInput input = (MultipartInput) res.getEntity();
497 if (logger.isDebugEnabled()) {
498 logger.debug(testName + ": Reading Common part ...");
500 CollectionobjectsCommon collectionObject =
501 (CollectionobjectsCommon) extractPart(input,
502 client.getCommonPartName(), CollectionobjectsCommon.class);
503 Assert.assertNotNull(collectionObject);
505 if (logger.isDebugEnabled()) {
506 logger.debug(testName + ": Reading Natural History part ...");
508 CollectionobjectsNaturalhistory conh =
509 (CollectionobjectsNaturalhistory) extractPart(input,
510 getNHPartName(), CollectionobjectsNaturalhistory.class);
511 Assert.assertNotNull(conh);
516 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readNonExistent(java.lang.String)
519 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
520 dependsOnMethods = {"read"})
521 public void readNonExistent(String testName) throws Exception {
523 if (logger.isDebugEnabled()) {
524 logger.debug(testBanner(testName, CLASS_NAME));
527 setupReadNonExistent();
529 // Submit the request to the service and store the response.
530 CollectionObjectClient client = new CollectionObjectClient();
531 ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
532 int statusCode = res.getStatus();
534 // Check the status code of the response: does it match
535 // the expected response(s)?
536 if (logger.isDebugEnabled()) {
537 logger.debug(testName + ": status = " + statusCode);
539 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
540 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
541 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
545 // ---------------------------------------------------------------
546 // CRUD tests : READ_LIST tests
547 // ---------------------------------------------------------------
550 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readList(java.lang.String)
553 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
554 dependsOnMethods = {"createList", "read"})
555 public void readList(String testName) throws Exception {
557 if (logger.isDebugEnabled()) {
558 logger.debug(testBanner(testName, CLASS_NAME));
563 // Submit the request to the service and store the response.
564 CollectionObjectClient client = new CollectionObjectClient();
565 ClientResponse<CollectionobjectsCommonList> res = client.readList();
566 CollectionobjectsCommonList list = res.getEntity();
567 int statusCode = res.getStatus();
569 // Check the status code of the response: does it match
570 // the expected response(s)?
571 if (logger.isDebugEnabled()) {
572 logger.debug(testName + ": status = " + statusCode);
574 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
575 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
576 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
578 // Optionally output additional data about list members for debugging.
579 boolean iterateThroughList = false;
580 if (iterateThroughList && logger.isDebugEnabled()) {
581 List<CollectionobjectsCommonList.CollectionObjectListItem> items =
582 list.getCollectionObjectListItem();
585 for (CollectionobjectsCommonList.CollectionObjectListItem item : items) {
586 logger.debug(testName + ": list-item[" + i + "] csid="
588 logger.debug(testName + ": list-item[" + i + "] objectNumber="
589 + item.getObjectNumber());
590 logger.debug(testName + ": list-item[" + i + "] URI="
600 // ---------------------------------------------------------------
601 // CRUD tests : UPDATE tests
602 // ---------------------------------------------------------------
605 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String)
608 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
609 dependsOnMethods = {"read"})
610 public void update(String testName) throws Exception {
612 if (logger.isDebugEnabled()) {
613 logger.debug(testBanner(testName, CLASS_NAME));
618 // Read an existing resource that will be updated.
619 ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
621 // Extract its common part.
622 CollectionObjectClient client = new CollectionObjectClient();
623 MultipartInput input = (MultipartInput) res.getEntity();
624 CollectionobjectsCommon collectionObject =
625 (CollectionobjectsCommon) extractPart(input,
626 client.getCommonPartName(), CollectionobjectsCommon.class);
627 Assert.assertNotNull(collectionObject);
629 // Change the content of one or more fields in the common part.
630 collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
631 collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
632 if (logger.isDebugEnabled()) {
633 logger.debug("sparse update that will be sent in update request:");
634 logger.debug(objectAsXmlString(collectionObject,
635 CollectionobjectsCommon.class));
638 // Send the changed resource to be updated.
639 res = updateSend(testName, knownResourceId, collectionObject);
640 int statusCode = res.getStatus();
641 // Check the status code of the response: does it match the expected response(s)?
642 if (logger.isDebugEnabled()) {
643 logger.debug(testName + ": status = " + statusCode);
645 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
646 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
647 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
649 // Read the response and verify that the resource was correctly updated.
650 input = (MultipartInput) res.getEntity();
651 CollectionobjectsCommon updatedCollectionObject =
652 (CollectionobjectsCommon) extractPart(input,
653 client.getCommonPartName(), CollectionobjectsCommon.class);
654 Assert.assertNotNull(updatedCollectionObject);
655 Assert.assertEquals(updatedCollectionObject.getObjectName(),
656 collectionObject.getObjectName(),
657 "Data in updated object did not match submitted data.");
664 * @param testName the test name
666 * @return the client response
668 private ClientResponse<MultipartInput> updateRetrieve(String testName, String id) {
669 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
670 CollectionObjectClient client = new CollectionObjectClient();
671 ClientResponse<MultipartInput> res = client.read(id);
672 if (logger.isDebugEnabled()) {
673 logger.debug("read in updateRetrieve for " + testName + " status = " + res.getStatus());
675 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS);
676 if (logger.isDebugEnabled()) {
677 logger.debug("got object to updateRetrieve for " + testName + " with ID: " + id);
685 * @param testName the test name
687 * @param collectionObject the collection object
688 * @return the client response
690 private ClientResponse<MultipartInput> updateSend(String testName, String id,
691 CollectionobjectsCommon collectionObject) {
692 MultipartOutput output = new MultipartOutput();
693 OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
694 CollectionObjectClient client = new CollectionObjectClient();
695 commonPart.getHeaders().add("label", client.getCommonPartName());
696 ClientResponse<MultipartInput> res = client.update(knownResourceId, output);
701 // Placeholders until the three tests below can be uncommented.
702 // See Issue CSPACE-401.
704 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithEmptyEntityBody(java.lang.String)
707 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
708 dependsOnMethods = {"read"})
709 public void updateWithEmptyEntityBody(String testName) throws Exception {
710 //FIXME: Should this test really be empty?
714 * Test how the service handles XML that is not well formed,
715 * when sent in the payload of an Update request.
717 * @param testName The name of this test method. This name is supplied
718 * automatically, via reflection, by a TestNG 'data provider' in
722 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
723 dependsOnMethods = {"read"})
724 public void updateWithMalformedXml(String testName) throws Exception {
725 //FIXME: Should this test really be empty?
729 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithWrongXmlSchema(java.lang.String)
732 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
733 dependsOnMethods = {"read"})
734 public void updateWithWrongXmlSchema(String testName) throws Exception {
735 //FIXME: Should this test really be empty?
740 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
741 dependsOnMethods = {"create", "update", "testSubmitRequest"})
742 public void updateWithEmptyEntityBody(String testName) throws Exception {
744 if (logger.isDebugEnabled()) {
745 logger.debug(testBanner(testName, CLASS_NAME));
748 setupUpdateWithEmptyEntityBody();
750 // Submit the request to the service and store the response.
751 String method = REQUEST_TYPE.httpMethodName();
752 String url = getResourceURL(knownResourceId);
753 String mediaType = MediaType.APPLICATION_XML;
754 final String entity = "";
755 int statusCode = submitRequest(method, url, mediaType, entity);
757 // Check the status code of the response: does it match
758 // the expected response(s)?
759 if(logger.isDebugEnabled()){
760 logger.debug(testName + ": url=" + url +
761 " status=" + statusCode);
763 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
764 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
765 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
769 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
770 dependsOnMethods = {"create", "update", "testSubmitRequest"})
771 public void updateWithMalformedXml() throws Exception {
773 if (logger.isDebugEnabled()) {
774 logger.debug(testBanner(testName, CLASS_NAME));
777 setupUpdateWithMalformedXml();
779 // Submit the request to the service and store the response.
780 String method = REQUEST_TYPE.httpMethodName();
781 String url = getResourceURL(knownResourceId);
782 final String entity = MALFORMED_XML_DATA;
783 String mediaType = MediaType.APPLICATION_XML;
784 int statusCode = submitRequest(method, url, mediaType, entity);
786 // Check the status code of the response: does it match
787 // the expected response(s)?
788 if(logger.isDebugEnabled()){
789 logger.debug(testName + ": url=" + url +
790 " status=" + statusCode);
792 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
793 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
794 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
798 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
799 dependsOnMethods = {"create", "update", "testSubmitRequest"})
800 public void updateWithWrongXmlSchema(String testName) throws Exception {
802 if (logger.isDebugEnabled()) {
803 logger.debug(testBanner(testName, CLASS_NAME));
806 setupUpdateWithWrongXmlSchema();
808 // Submit the request to the service and store the response.
809 String method = REQUEST_TYPE.httpMethodName();
810 String url = getResourceURL(knownResourceId);
811 String mediaType = MediaType.APPLICATION_XML;
812 final String entity = WRONG_XML_SCHEMA_DATA;
813 int statusCode = submitRequest(method, url, mediaType, entity);
815 // Check the status code of the response: does it match
816 // the expected response(s)?
817 if(logger.isDebugEnabled()){
818 logger.debug(testName + ": url=" + url +
819 " status=" + statusCode);
821 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
822 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
823 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
828 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateNonExistent(java.lang.String)
831 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
832 dependsOnMethods = {"update", "testSubmitRequest"})
833 public void updateNonExistent(String testName) throws Exception {
835 if (logger.isDebugEnabled()) {
836 logger.debug(testBanner(testName, CLASS_NAME));
839 setupUpdateNonExistent();
841 // Submit the request to the service and store the response.
843 // Note: The ID used in this 'create' call may be arbitrary.
844 // The only relevant ID may be the one used in updateCollectionObject(), below.
845 CollectionObjectClient client = new CollectionObjectClient();
846 MultipartOutput multipart =
847 createCollectionObjectInstance(client.getCommonPartName(),
849 ClientResponse<MultipartInput> res =
850 client.update(NON_EXISTENT_ID, multipart);
851 int statusCode = res.getStatus();
853 // Check the status code of the response: does it match
854 // the expected response(s)?
855 if (logger.isDebugEnabled()) {
856 logger.debug(testName + ": status = " + statusCode);
858 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
859 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
860 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
864 * Test how the service handles, in an Update request, payloads
865 * containing null values (or, in the case of String fields,
866 * empty String values) in one or more fields in which non-empty
867 * values are required.
869 * This is a test of code and/or configuration in the service's
870 * validation routine(s).
872 * @param testName The name of this test method. This name is supplied
873 * automatically, via reflection, by a TestNG 'data provider' in
877 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
878 dependsOnMethods = {"read"})
879 public void updateWithRequiredValuesNullOrEmpty(String testName) throws Exception {
881 if (logger.isDebugEnabled()) {
882 logger.debug(testBanner(testName, CLASS_NAME));
886 if (logger.isDebugEnabled()) {
887 logger.debug(testName + " got object to update with ID: " + knownResourceId);
890 // Read an existing record for updating.
891 ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
893 CollectionObjectClient client = new CollectionObjectClient();
894 MultipartInput input = (MultipartInput) res.getEntity();
895 CollectionobjectsCommon collectionObject =
896 (CollectionobjectsCommon) extractPart(input,
897 client.getCommonPartName(), CollectionobjectsCommon.class);
898 Assert.assertNotNull(collectionObject);
900 // Update with invalid content, by setting a value to the
901 // empty String, in a field that requires a non-empty value,
902 // as enforced by the service's validation routine(s).
903 collectionObject.setObjectNumber("");
905 if (logger.isDebugEnabled()) {
906 logger.debug(testName + " updated object");
907 logger.debug(objectAsXmlString(collectionObject,
908 CollectionobjectsCommon.class));
911 // Submit the request to the service and store the response.
912 res = updateSend(testName, knownResourceId, collectionObject);
913 int statusCode = res.getStatus();
915 // Read the response and verify that the update attempt failed.
916 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
917 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
918 Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
922 // ---------------------------------------------------------------
923 // CRUD tests : DELETE tests
924 // ---------------------------------------------------------------
927 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String)
930 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
931 dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
932 public void delete(String testName) throws Exception {
934 if (logger.isDebugEnabled()) {
935 logger.debug(testBanner(testName, CLASS_NAME));
940 // Submit the request to the service and store the response.
941 CollectionObjectClient client = new CollectionObjectClient();
942 ClientResponse<Response> res = client.delete(knownResourceId);
943 int statusCode = res.getStatus();
945 // Check the status code of the response: does it match
946 // the expected response(s)?
947 if (logger.isDebugEnabled()) {
948 logger.debug(testName + ": status = " + statusCode);
950 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
951 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
952 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
957 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String)
960 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
961 dependsOnMethods = {"delete"})
962 public void deleteNonExistent(String testName) throws Exception {
964 if (logger.isDebugEnabled()) {
965 logger.debug(testBanner(testName, CLASS_NAME));
968 setupDeleteNonExistent();
970 // Submit the request to the service and store the response.
971 CollectionObjectClient client = new CollectionObjectClient();
972 ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
973 int statusCode = res.getStatus();
975 // Check the status code of the response: does it match
976 // the expected response(s)?
977 if (logger.isDebugEnabled()) {
978 logger.debug(testName + ": status = " + statusCode);
980 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
981 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
982 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
985 // ---------------------------------------------------------------
986 // Utility tests : tests of code used in tests above
987 // ---------------------------------------------------------------
989 * Tests the code for manually submitting data that is used by several
990 * of the methods above.
994 @Test(dependsOnMethods = {"create", "read"})
995 public void testSubmitRequest() throws Exception {
996 testSubmitRequest(knownResourceId);
1000 * Test submit request.
1002 * @param resourceId the resource id
1003 * @throws Exception the exception
1005 private void testSubmitRequest(String resourceId) throws Exception {
1007 // Expected status code: 200 OK
1008 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
1010 // Submit the request to the service and store the response.
1011 String method = ServiceRequestType.READ.httpMethodName();
1012 String url = getResourceURL(resourceId);
1013 int statusCode = submitRequest(method, url);
1015 // Check the status code of the response: does it match
1016 // the expected response(s)?
1017 if (logger.isDebugEnabled()) {
1018 logger.debug("testSubmitRequest: url=" + url
1019 + " status=" + statusCode);
1021 Assert.assertEquals(statusCode, EXPECTED_STATUS);
1025 // ---------------------------------------------------------------
1026 // Utility methods used by tests above
1027 // ---------------------------------------------------------------
1029 * Creates the collection object instance.
1031 * @param commonPartName the common part name
1032 * @param identifier the identifier
1033 * @return the multipart output
1035 private MultipartOutput createCollectionObjectInstance(String commonPartName,
1036 String identifier) {
1037 return createCollectionObjectInstance(commonPartName,
1038 "objectNumber-" + identifier,
1039 "objectName-" + identifier);
1043 * Creates the collection object instance.
1045 * @param commonPartName the common part name
1046 * @param objectNumber the object number
1047 * @param objectName the object name
1048 * @return the multipart output
1050 private MultipartOutput createCollectionObjectInstance(String commonPartName,
1051 String objectNumber, String objectName) {
1052 CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
1054 ResponsibleDepartmentList deptList = new ResponsibleDepartmentList();
1055 List<String> depts = deptList.getResponsibleDepartment();
1056 // @TODO Use properly formatted refNames for representative departments
1057 // in this example test record. The following are mere placeholders.
1058 depts.add("urn:org.collectionspace.services.department:Registrar");
1059 if (multivalue == true) {
1060 depts.add("urn:org.walkerart.department:Fine Art");
1063 // FIXME: REM - Can someone please document why we are toggling this
1066 multivalue = !multivalue;
1068 OtherNumberList otherNumList = new OtherNumberList();
1069 List<OtherNumber> otherNumbers = otherNumList.getOtherNumber();
1071 OtherNumber otherNumber1 = new OtherNumber();
1072 otherNumber1.setNumberValue("101." + objectName);
1073 otherNumber1.setNumberType("integer");
1074 otherNumbers.add(otherNumber1);
1076 OtherNumber otherNumber2 = new OtherNumber();
1077 otherNumber2.setNumberValue("101.502.23.456." + objectName);
1078 otherNumber2.setNumberType("ipaddress");
1079 otherNumbers.add(otherNumber2);
1081 //FIXME: Title does not need to be set.
1082 collectionObject.setTitle("atitle");
1083 collectionObject.setResponsibleDepartments(deptList);
1084 collectionObject.setObjectNumber(objectNumber);
1086 collectionObject.setOtherNumberList(otherNumList);
1087 collectionObject.setOtherNumber("urn:org.walkerart.id:123");
1089 collectionObject.setObjectName(objectName);
1090 collectionObject.setAge(""); //test for null string
1091 collectionObject.setBriefDescription("Papier mache bird cow mask with horns, "
1092 + "painted red with black and yellow spots. "
1093 + "Puerto Rico. ca. 8" high, 6" wide, projects 10" (with horns).");
1095 CollectionobjectsNaturalhistory conh = new CollectionobjectsNaturalhistory();
1096 conh.setNhString("test-string");
1098 conh.setNhLong(9999);
1101 MultipartOutput multipart = createCollectionObjectInstance(commonPartName, collectionObject, conh);
1106 * Creates the collection object instance.
1108 * @param commonPartName the common part name
1109 * @param collectionObject the collection object
1110 * @param conh the conh
1111 * @return the multipart output
1113 private MultipartOutput createCollectionObjectInstance(String commonPartName,
1114 CollectionobjectsCommon collectionObject, CollectionobjectsNaturalhistory conh) {
1116 MultipartOutput multipart = CollectionObjectFactory.createCollectionObjectInstance(
1117 commonPartName, collectionObject, getNHPartName(), conh);
1118 if (logger.isDebugEnabled()) {
1119 logger.debug("to be created, collectionobject common");
1120 logger.debug(objectAsXmlString(collectionObject,
1121 CollectionobjectsCommon.class));
1125 if (logger.isDebugEnabled()) {
1126 logger.debug("to be created, collectionobject nhistory");
1127 logger.debug(objectAsXmlString(conh,
1128 CollectionobjectsNaturalhistory.class));
1136 * createCollectionObjectInstanceFromXml uses JAXB unmarshaller to retrieve
1137 * collectionobject from given file
1138 * @param commonPartName
1139 * @param commonPartFileName
1143 private MultipartOutput createCollectionObjectInstanceFromXml(String testName, String commonPartName,
1144 String commonPartFileName) throws Exception {
1146 CollectionobjectsCommon collectionObject =
1147 (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class,
1148 commonPartFileName);
1149 MultipartOutput multipart = new MultipartOutput();
1150 OutputPart commonPart = multipart.addPart(collectionObject,
1151 MediaType.APPLICATION_XML_TYPE);
1152 commonPart.getHeaders().add("label", commonPartName);
1154 if (logger.isDebugEnabled()) {
1155 logger.debug(testName + " to be created, collectionobject common");
1156 logger.debug(objectAsXmlString(collectionObject,
1157 CollectionobjectsCommon.class));
1164 * createCollectionObjectInstanceFromRawXml uses stringified collectionobject
1165 * retrieve from given file
1166 * @param commonPartName
1167 * @param commonPartFileName
1171 private MultipartOutput createCollectionObjectInstanceFromRawXml(String testName, String commonPartName,
1172 String commonPartFileName) throws Exception {
1174 MultipartOutput multipart = new MultipartOutput();
1175 String stringObject = getXmlDocumentAsString(commonPartFileName);
1176 if (logger.isDebugEnabled()) {
1177 logger.debug(testName + " to be created, collectionobject common " + "\n" + stringObject);
1179 OutputPart commonPart = multipart.addPart(stringObject,
1180 MediaType.APPLICATION_XML_TYPE);
1181 commonPart.getHeaders().add("label", commonPartName);
1188 * Gets the nH part name.
1190 * @return the nH part name
1192 private String getNHPartName() {
1193 return "collectionobjects_naturalhistory";
1197 * Creates the from xml file.
1199 * @param testName the test name
1200 * @param fileName the file name
1201 * @param useJaxb the use jaxb
1202 * @return the string
1203 * @throws Exception the exception
1205 private String createFromXmlFile(String testName, String fileName, boolean useJaxb) throws Exception {
1210 MultipartOutput multipart = null;
1212 CollectionObjectClient client = new CollectionObjectClient();
1214 multipart = createCollectionObjectInstanceFromXml(testName,
1215 client.getCommonPartName(), fileName);
1217 multipart = createCollectionObjectInstanceFromRawXml(testName,
1218 client.getCommonPartName(), fileName);
1220 ClientResponse<Response> res = client.create(multipart);
1221 int statusCode = res.getStatus();
1223 if (logger.isDebugEnabled()) {
1224 logger.debug(testName + ": status = " + statusCode);
1226 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1227 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1228 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1229 String newId = extractId(res);
1230 allResourceIdsCreated.add(newId);