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.jaxb.AbstractCommonList;
39 import org.jboss.resteasy.client.ClientResponse;
40 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
41 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
42 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
43 import org.testng.Assert;
44 import org.testng.annotations.Test;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
50 * CollectionObjectServiceTest, carries out tests against a
51 * deployed and running CollectionObject Service.
53 * $LastChangedRevision$
56 public class CollectionObjectServiceTest extends AbstractServiceTestImpl {
59 private final Logger logger =
60 LoggerFactory.getLogger(CollectionObjectServiceTest.class);
61 // Instance variables specific to this test.
62 /** The known resource id. */
63 private String knownResourceId = null;
65 /** The multivalue. */
66 private boolean multivalue; //toggle
69 * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
72 protected String getServicePathComponent() {
73 return new CollectionObjectClient().getServicePathComponent();
77 * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
80 protected CollectionSpaceClient getClientInstance() {
81 return new CollectionObjectClient();
85 * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
88 protected AbstractCommonList getAbstractCommonList(
89 ClientResponse<AbstractCommonList> response) {
90 return response.getEntity(CollectionobjectsCommonList.class);
93 // ---------------------------------------------------------------
94 // CRUD tests : CREATE tests
95 // ---------------------------------------------------------------
98 * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String)
101 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
102 public void create(String testName) throws Exception {
104 // Perform setup, such as initializing the type of service request
105 // (e.g. CREATE, DELETE), its valid and expected status codes, and
106 // its associated HTTP method name (e.g. POST, DELETE).
107 setupCreate(testName);
109 // Submit the request to the service and store the response.
110 CollectionObjectClient client = new CollectionObjectClient();
111 String identifier = createIdentifier();
112 MultipartOutput multipart =
113 createCollectionObjectInstance(client.getCommonPartName(), identifier);
114 ClientResponse<Response> res = client.create(multipart);
115 int statusCode = res.getStatus();
117 // Check the status code of the response: does it match
118 // the expected response(s)?
121 // Does it fall within the set of valid status codes?
122 // Does it exactly match the expected status code?
123 if (logger.isDebugEnabled()) {
124 logger.debug(testName + ": status = " + statusCode);
126 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
127 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
128 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
130 // Store the ID returned from the first resource created
131 // for additional tests below.
132 if (knownResourceId == null) {
133 knownResourceId = extractId(res);
134 if (logger.isDebugEnabled()) {
135 logger.debug(testName + ": knownResourceId=" + knownResourceId);
139 // Store the IDs from every resource created by tests,
140 // so they can be deleted after tests have been run.
141 allResourceIdsCreated.add(extractId(res));
146 * Tests to diagnose and verify the fixed status of CSPACE-1026,
147 * "Whitespace at certain points in payload cause failure"
150 * Creates the from xml cambridge.
152 * @param testName the test name
153 * @throws Exception the exception
155 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
156 dependsOnMethods = {"create", "testSubmitRequest"})
157 public void createFromXmlCambridge(String testName) throws Exception {
159 createFromXmlFile(testName, "./test-data/testCambridge.xml", true);
160 testSubmitRequest(newId);
164 * Creates the from xml rfw s1.
166 * @param testName the test name
167 * @throws Exception the exception
169 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
170 dependsOnMethods = {"create", "testSubmitRequest"})
171 public void createFromXmlRFWS1(String testName) throws Exception {
172 String testDataDir = System.getProperty("test-data.fileName");
174 //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp1.xml", false);
175 createFromXmlFile(testName, testDataDir + "/repfield_whitesp1.xml", false);
176 testSubmitRequest(newId);
180 * Creates the from xml rfw s2.
182 * @param testName the test name
183 * @throws Exception the exception
185 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
186 dependsOnMethods = {"create", "testSubmitRequest"})
187 public void createFromXmlRFWS2(String testName) throws Exception {
188 String testDataDir = System.getProperty("test-data.fileName");
190 //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp2.xml", false);
191 createFromXmlFile(testName, testDataDir + "/repfield_whitesp2.xml", false);
192 testSubmitRequest(newId);
196 * Creates the from xml rfw s3.
198 * @param testName the test name
199 * @throws Exception the exception
201 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
202 dependsOnMethods = {"create", "testSubmitRequest"})
203 public void createFromXmlRFWS3(String testName) throws Exception {
204 String testDataDir = System.getProperty("test-data.fileName");
206 //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp3.xml", false);
207 createFromXmlFile(testName, testDataDir + "/repfield_whitesp3.xml", false);
208 testSubmitRequest(newId);
212 * Creates the from xml rfw s4.
214 * @param testName the test name
215 * @throws Exception the exception
217 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
218 dependsOnMethods = {"create", "testSubmitRequest"})
219 public void createFromXmlRFWS4(String testName) throws Exception {
220 String testDataDir = System.getProperty("test-data.fileName");
222 createFromXmlFile(testName, testDataDir + "/repfield_whitesp4.xml", false);
223 testSubmitRequest(newId);
227 * Tests to diagnose and verify the fixed status of CSPACE-1248,
228 * "Wedged records created!" (i.e. records with child repeatable
229 * fields, which contain null values, can be successfully created
230 * but an error occurs on trying to retrieve those records).
233 * Creates the with null value repeatable field.
235 * @param testName the test name
236 * @throws Exception the exception
238 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
239 dependsOnMethods = {"create", "testSubmitRequest"})
240 public void createWithNullValueRepeatableField(String testName) throws Exception {
241 String testDataDir = System.getProperty("test-data.fileName");
243 createFromXmlFile(testName, testDataDir + "/repfield_null1.xml", false);
244 if (logger.isDebugEnabled()) {
245 logger.debug("Successfully created record with null value repeatable field.");
246 logger.debug("Attempting to retrieve just-created record ...");
248 testSubmitRequest(newId);
252 * @see org.collectionspace.services.client.test.ServiceTest#createList()
255 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
256 dependsOnMethods = {"create"})
257 public void createList(String testName) throws Exception {
258 this.createPaginatedList(testName, DEFAULT_LIST_SIZE);
262 // Placeholders until the three tests below can be uncommented.
263 // See Issue CSPACE-401.
265 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithEmptyEntityBody(java.lang.String)
268 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
269 public void createWithEmptyEntityBody(String testName) throws Exception {
270 //FIXME: Should this test really be empty?
274 * Test how the service handles XML that is not well formed,
275 * when sent in the payload of a Create request.
277 * @param testName The name of this test method. This name is supplied
278 * automatically, via reflection, by a TestNG 'data provider' in
282 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
283 public void createWithMalformedXml(String testName) throws Exception {
284 setupCreate(testName);
288 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithWrongXmlSchema(java.lang.String)
291 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
292 public void createWithWrongXmlSchema(String testName) throws Exception {
293 //FIXME: Should this test really be empty?
299 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
300 dependsOnMethods = {"create", "testSubmitRequest"})
301 public void createWithEmptyEntityBody(String testName) throwsException {
304 setupCreateWithEmptyEntityBody(testName);
306 // Submit the request to the service and store the response.
307 String method = REQUEST_TYPE.httpMethodName();
308 String url = getServiceRootURL();
309 String mediaType = MediaType.APPLICATION_XML;
310 final String entity = "";
311 int statusCode = submitRequest(method, url, mediaType, entity);
313 // Check the status code of the response: does it match
314 // the expected response(s)?
315 if(logger.isDebugEnabled()){
316 logger.debug(testName + ": url=" + url +
317 " status=" + statusCode);
319 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
320 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
321 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
325 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
326 dependsOnMethods = {"create", "testSubmitRequest"})
327 public void createWithMalformedXml(String testName) throws Exception {
330 setupCreateWithMalformedXml(testName);
332 // Submit the request to the service and store the response.
333 String method = REQUEST_TYPE.httpMethodName();
334 String url = getServiceRootURL();
335 String mediaType = MediaType.APPLICATION_XML;
336 final String entity = MALFORMED_XML_DATA; // Constant from base class.
337 int statusCode = submitRequest(method, url, mediaType, entity);
339 // Check the status code of the response: does it match
340 // the expected response(s)?
341 if(logger.isDebugEnabled()){
342 logger.debug(testName + ": url=" + url +
343 " status=" + statusCode);
345 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
346 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
347 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
351 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
352 dependsOnMethods = {"create", "testSubmitRequest"})
353 public void createWithWrongXmlSchema(String testName) throws Exception {
356 setupCreateWithWrongXmlSchema(testName);
358 // Submit the request to the service and store the response.
359 String method = REQUEST_TYPE.httpMethodName();
360 String url = getServiceRootURL();
361 String mediaType = MediaType.APPLICATION_XML;
362 final String entity = WRONG_XML_SCHEMA_DATA;
363 int statusCode = submitRequest(method, url, mediaType, entity);
365 // Check the status code of the response: does it match
366 // the expected response(s)?
367 if(logger.isDebugEnabled()){
368 logger.debug(testName + ": url=" + url +
369 " status=" + statusCode);
371 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
372 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
373 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
378 * Test how the service handles, in a Create request, payloads
379 * containing null values (or, in the case of String fields,
380 * empty String values) in one or more fields which must be
381 * present and are required to contain non-empty values.
383 * This is a test of code and/or configuration in the service's
384 * validation routine(s).
386 * @param testName The name of this test method. This name is supplied
387 * automatically, via reflection, by a TestNG 'data provider' in
391 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
392 public void createWithRequiredValuesNullOrEmpty(String testName) throws Exception {
393 setupCreate(testName);
395 // Build a payload with invalid content, by omitting a
396 // field (objectNumber) which must be present, and in which
397 // a non-empty value is required, as enforced by the service's
398 // validation routine(s).
399 CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
400 collectionObject.setTitle("atitle");
401 collectionObject.setObjectName("some name");
403 // Submit the request to the service and store the response.
404 CollectionObjectClient client = new CollectionObjectClient();
405 MultipartOutput multipart =
406 createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
407 ClientResponse<Response> res = client.create(multipart);
408 int statusCode = res.getStatus();
410 // Read the response and verify that the create attempt failed.
411 if (logger.isDebugEnabled()) {
412 logger.debug(testName + ": status = " + statusCode);
414 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
415 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
416 Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
418 // FIXME: Consider splitting off the following into its own test method.
420 // Build a payload with invalid content, by setting a value to the
421 // empty String, in a field that requires a non-empty value,
422 // as enforced by the service's validation routine(s).
423 collectionObject = new CollectionobjectsCommon();
424 collectionObject.setTitle("atitle");
425 collectionObject.setObjectName("some name");
426 collectionObject.setObjectNumber("");
428 // Submit the request to the service and store the response.
430 createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
431 res = client.create(multipart);
432 statusCode = res.getStatus();
434 // Read the response and verify that the create attempt failed.
435 if (logger.isDebugEnabled()) {
436 logger.debug(testName + ": status = " + statusCode);
438 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
439 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
440 Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
445 // ---------------------------------------------------------------
446 // CRUD tests : READ tests
447 // ---------------------------------------------------------------
450 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String)
453 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
454 dependsOnMethods = {"create"})
455 public void read(String testName) throws Exception {
460 // Submit the request to the service and store the response.
461 CollectionObjectClient client = new CollectionObjectClient();
462 ClientResponse<MultipartInput> res = client.read(knownResourceId);
463 int statusCode = res.getStatus();
465 // Check the status code of the response: does it match
466 // the expected response(s)?
467 if (logger.isDebugEnabled()) {
468 logger.debug(testName + ": status = " + statusCode);
470 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
471 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
472 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
474 MultipartInput input = (MultipartInput) res.getEntity();
476 if (logger.isDebugEnabled()) {
477 logger.debug(testName + ": Reading Common part ...");
479 CollectionobjectsCommon collectionObject =
480 (CollectionobjectsCommon) extractPart(input,
481 client.getCommonPartName(), CollectionobjectsCommon.class);
482 Assert.assertNotNull(collectionObject);
484 if (logger.isDebugEnabled()) {
485 logger.debug(testName + ": Reading Natural History part ...");
487 CollectionobjectsNaturalhistory conh =
488 (CollectionobjectsNaturalhistory) extractPart(input,
489 getNHPartName(), CollectionobjectsNaturalhistory.class);
490 Assert.assertNotNull(conh);
495 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readNonExistent(java.lang.String)
498 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
499 dependsOnMethods = {"read"})
500 public void readNonExistent(String testName) throws Exception {
503 setupReadNonExistent(testName);
505 // Submit the request to the service and store the response.
506 CollectionObjectClient client = new CollectionObjectClient();
507 ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
508 int statusCode = res.getStatus();
510 // Check the status code of the response: does it match
511 // the expected response(s)?
512 if (logger.isDebugEnabled()) {
513 logger.debug(testName + ": status = " + statusCode);
515 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
516 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
517 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
521 // ---------------------------------------------------------------
522 // CRUD tests : READ_LIST tests
523 // ---------------------------------------------------------------
526 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readList(java.lang.String)
529 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
530 dependsOnMethods = {"createList", "read"})
531 public void readList(String testName) throws Exception {
534 setupReadList(testName);
536 // Submit the request to the service and store the response.
537 CollectionObjectClient client = new CollectionObjectClient();
538 ClientResponse<CollectionobjectsCommonList> res = client.readList();
539 CollectionobjectsCommonList list = res.getEntity();
540 int statusCode = res.getStatus();
542 // Check the status code of the response: does it match
543 // the expected response(s)?
544 if (logger.isDebugEnabled()) {
545 logger.debug(testName + ": status = " + statusCode);
547 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
548 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
549 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
551 // Optionally output additional data about list members for debugging.
552 boolean iterateThroughList = false;
553 if (iterateThroughList && logger.isDebugEnabled()) {
554 List<CollectionobjectsCommonList.CollectionObjectListItem> items =
555 list.getCollectionObjectListItem();
558 for (CollectionobjectsCommonList.CollectionObjectListItem item : items) {
559 logger.debug(testName + ": list-item[" + i + "] csid="
561 logger.debug(testName + ": list-item[" + i + "] objectNumber="
562 + item.getObjectNumber());
563 logger.debug(testName + ": list-item[" + i + "] URI="
573 // ---------------------------------------------------------------
574 // CRUD tests : UPDATE tests
575 // ---------------------------------------------------------------
578 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String)
581 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
582 dependsOnMethods = {"read"})
583 public void update(String testName) throws Exception {
586 setupUpdate(testName);
588 // Read an existing resource that will be updated.
589 ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
591 // Extract its common part.
592 CollectionObjectClient client = new CollectionObjectClient();
593 MultipartInput input = (MultipartInput) res.getEntity();
594 CollectionobjectsCommon collectionObject =
595 (CollectionobjectsCommon) extractPart(input,
596 client.getCommonPartName(), CollectionobjectsCommon.class);
597 Assert.assertNotNull(collectionObject);
599 // Change the content of one or more fields in the common part.
600 collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
601 collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
602 if (logger.isDebugEnabled()) {
603 logger.debug("sparse update that will be sent in update request:");
604 logger.debug(objectAsXmlString(collectionObject,
605 CollectionobjectsCommon.class));
608 // Send the changed resource to be updated.
609 res = updateSend(testName, knownResourceId, collectionObject);
610 int statusCode = res.getStatus();
611 // Check the status code of the response: does it match the expected response(s)?
612 if (logger.isDebugEnabled()) {
613 logger.debug(testName + ": status = " + statusCode);
615 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
616 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
617 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
619 // Read the response and verify that the resource was correctly updated.
620 input = (MultipartInput) res.getEntity();
621 CollectionobjectsCommon updatedCollectionObject =
622 (CollectionobjectsCommon) extractPart(input,
623 client.getCommonPartName(), CollectionobjectsCommon.class);
624 Assert.assertNotNull(updatedCollectionObject);
625 Assert.assertEquals(updatedCollectionObject.getObjectName(),
626 collectionObject.getObjectName(),
627 "Data in updated object did not match submitted data.");
634 * @param testName the test name
636 * @return the client response
638 private ClientResponse<MultipartInput> updateRetrieve(String testName, String id) {
639 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
640 CollectionObjectClient client = new CollectionObjectClient();
641 ClientResponse<MultipartInput> res = client.read(id);
642 if (logger.isDebugEnabled()) {
643 logger.debug("read in updateRetrieve for " + testName + " status = " + res.getStatus());
645 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS);
646 if (logger.isDebugEnabled()) {
647 logger.debug("got object to updateRetrieve for " + testName + " with ID: " + id);
655 * @param testName the test name
657 * @param collectionObject the collection object
658 * @return the client response
660 private ClientResponse<MultipartInput> updateSend(String testName, String id,
661 CollectionobjectsCommon collectionObject) {
662 MultipartOutput output = new MultipartOutput();
663 OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
664 CollectionObjectClient client = new CollectionObjectClient();
665 commonPart.getHeaders().add("label", client.getCommonPartName());
666 ClientResponse<MultipartInput> res = client.update(knownResourceId, output);
671 // Placeholders until the three tests below can be uncommented.
672 // See Issue CSPACE-401.
674 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithEmptyEntityBody(java.lang.String)
677 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
678 dependsOnMethods = {"read"})
679 public void updateWithEmptyEntityBody(String testName) throws Exception {
680 //FIXME: Should this test really be empty?
684 * Test how the service handles XML that is not well formed,
685 * when sent in the payload of an Update request.
687 * @param testName The name of this test method. This name is supplied
688 * automatically, via reflection, by a TestNG 'data provider' in
692 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
693 dependsOnMethods = {"read"})
694 public void updateWithMalformedXml(String testName) throws Exception {
695 //FIXME: Should this test really be empty?
699 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithWrongXmlSchema(java.lang.String)
702 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
703 dependsOnMethods = {"read"})
704 public void updateWithWrongXmlSchema(String testName) throws Exception {
705 //FIXME: Should this test really be empty?
710 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
711 dependsOnMethods = {"create", "update", "testSubmitRequest"})
712 public void updateWithEmptyEntityBody(String testName) throws Exception {
715 setupUpdateWithEmptyEntityBody(testName);
717 // Submit the request to the service and store the response.
718 String method = REQUEST_TYPE.httpMethodName();
719 String url = getResourceURL(knownResourceId);
720 String mediaType = MediaType.APPLICATION_XML;
721 final String entity = "";
722 int statusCode = submitRequest(method, url, mediaType, entity);
724 // Check the status code of the response: does it match
725 // the expected response(s)?
726 if(logger.isDebugEnabled()){
727 logger.debug(testName + ": url=" + url +
728 " status=" + statusCode);
730 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
731 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
732 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
736 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
737 dependsOnMethods = {"create", "update", "testSubmitRequest"})
738 public void updateWithMalformedXml() throws Exception {
741 setupUpdateWithMalformedXml(testName);
743 // Submit the request to the service and store the response.
744 String method = REQUEST_TYPE.httpMethodName();
745 String url = getResourceURL(knownResourceId);
746 final String entity = MALFORMED_XML_DATA;
747 String mediaType = MediaType.APPLICATION_XML;
748 int statusCode = submitRequest(method, url, mediaType, entity);
750 // Check the status code of the response: does it match
751 // the expected response(s)?
752 if(logger.isDebugEnabled()){
753 logger.debug(testName + ": url=" + url +
754 " status=" + statusCode);
756 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
757 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
758 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
762 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
763 dependsOnMethods = {"create", "update", "testSubmitRequest"})
764 public void updateWithWrongXmlSchema(String testName) throws Exception {
767 setupUpdateWithWrongXmlSchema(String testName);
769 // Submit the request to the service and store the response.
770 String method = REQUEST_TYPE.httpMethodName();
771 String url = getResourceURL(knownResourceId);
772 String mediaType = MediaType.APPLICATION_XML;
773 final String entity = WRONG_XML_SCHEMA_DATA;
774 int statusCode = submitRequest(method, url, mediaType, entity);
776 // Check the status code of the response: does it match
777 // the expected response(s)?
778 if(logger.isDebugEnabled()){
779 logger.debug(testName + ": url=" + url +
780 " status=" + statusCode);
782 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
783 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
784 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
789 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateNonExistent(java.lang.String)
792 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
793 dependsOnMethods = {"update", "testSubmitRequest"})
794 public void updateNonExistent(String testName) throws Exception {
797 setupUpdateNonExistent(testName);
799 // Submit the request to the service and store the response.
801 // Note: The ID used in this 'create' call may be arbitrary.
802 // The only relevant ID may be the one used in updateCollectionObject(), below.
803 CollectionObjectClient client = new CollectionObjectClient();
804 MultipartOutput multipart =
805 createCollectionObjectInstance(client.getCommonPartName(),
807 ClientResponse<MultipartInput> res =
808 client.update(NON_EXISTENT_ID, multipart);
809 int statusCode = res.getStatus();
811 // Check the status code of the response: does it match
812 // the expected response(s)?
813 if (logger.isDebugEnabled()) {
814 logger.debug(testName + ": status = " + statusCode);
816 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
817 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
818 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
822 * Test how the service handles, in an Update request, payloads
823 * containing null values (or, in the case of String fields,
824 * empty String values) in one or more fields in which non-empty
825 * values are required.
827 * This is a test of code and/or configuration in the service's
828 * validation routine(s).
830 * @param testName The name of this test method. This name is supplied
831 * automatically, via reflection, by a TestNG 'data provider' in
835 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
836 dependsOnMethods = {"read"})
837 public void updateWithRequiredValuesNullOrEmpty(String testName) throws Exception {
839 setupUpdate(testName);
840 if (logger.isDebugEnabled()) {
841 logger.debug(testName + " got object to update with ID: " + knownResourceId);
844 // Read an existing record for updating.
845 ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
847 CollectionObjectClient client = new CollectionObjectClient();
848 MultipartInput input = (MultipartInput) res.getEntity();
849 CollectionobjectsCommon collectionObject =
850 (CollectionobjectsCommon) extractPart(input,
851 client.getCommonPartName(), CollectionobjectsCommon.class);
852 Assert.assertNotNull(collectionObject);
854 // Update with invalid content, by setting a value to the
855 // empty String, in a field that requires a non-empty value,
856 // as enforced by the service's validation routine(s).
857 collectionObject.setObjectNumber("");
859 if (logger.isDebugEnabled()) {
860 logger.debug(testName + " updated object");
861 logger.debug(objectAsXmlString(collectionObject,
862 CollectionobjectsCommon.class));
865 // Submit the request to the service and store the response.
866 res = updateSend(testName, knownResourceId, collectionObject);
867 int statusCode = res.getStatus();
869 // Read the response and verify that the update attempt failed.
870 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
871 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
872 Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
876 // ---------------------------------------------------------------
877 // CRUD tests : DELETE tests
878 // ---------------------------------------------------------------
881 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String)
884 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
885 dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
886 public void delete(String testName) throws Exception {
889 setupDelete(testName);
891 // Submit the request to the service and store the response.
892 CollectionObjectClient client = new CollectionObjectClient();
893 ClientResponse<Response> res = client.delete(knownResourceId);
894 int statusCode = res.getStatus();
896 // Check the status code of the response: does it match
897 // the expected response(s)?
898 if (logger.isDebugEnabled()) {
899 logger.debug(testName + ": status = " + statusCode);
901 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
902 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
903 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
908 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String)
911 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
912 dependsOnMethods = {"delete"})
913 public void deleteNonExistent(String testName) throws Exception {
916 setupDeleteNonExistent(testName);
918 // Submit the request to the service and store the response.
919 CollectionObjectClient client = new CollectionObjectClient();
920 ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
921 int statusCode = res.getStatus();
923 // Check the status code of the response: does it match
924 // the expected response(s)?
925 if (logger.isDebugEnabled()) {
926 logger.debug(testName + ": status = " + statusCode);
928 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
929 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
930 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
933 // ---------------------------------------------------------------
934 // Utility tests : tests of code used in tests above
935 // ---------------------------------------------------------------
937 * Tests the code for manually submitting data that is used by several
938 * of the methods above.
942 @Test(dependsOnMethods = {"create", "read"})
943 public void testSubmitRequest() throws Exception {
944 testSubmitRequest(knownResourceId);
948 * Test submit request.
950 * @param resourceId the resource id
951 * @throws Exception the exception
953 private void testSubmitRequest(String resourceId) throws Exception {
955 // Expected status code: 200 OK
956 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
958 // Submit the request to the service and store the response.
959 String method = ServiceRequestType.READ.httpMethodName();
960 String url = getResourceURL(resourceId);
961 int statusCode = submitRequest(method, url);
963 // Check the status code of the response: does it match
964 // the expected response(s)?
965 if (logger.isDebugEnabled()) {
966 logger.debug("testSubmitRequest: url=" + url
967 + " status=" + statusCode);
969 Assert.assertEquals(statusCode, EXPECTED_STATUS);
973 // ---------------------------------------------------------------
974 // Utility methods used by tests above
975 // ---------------------------------------------------------------
977 * Creates the collection object instance.
979 * @param commonPartName the common part name
980 * @param identifier the identifier
981 * @return the multipart output
983 private MultipartOutput createCollectionObjectInstance(String commonPartName,
985 return createCollectionObjectInstance(commonPartName,
986 "objectNumber-" + identifier,
987 "objectName-" + identifier);
991 * Creates the collection object instance.
993 * @param commonPartName the common part name
994 * @param objectNumber the object number
995 * @param objectName the object name
996 * @return the multipart output
998 private MultipartOutput createCollectionObjectInstance(String commonPartName,
999 String objectNumber, String objectName) {
1000 CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
1001 ResponsibleDepartmentList deptList = new ResponsibleDepartmentList();
1002 List<String> depts = deptList.getResponsibleDepartment();
1003 // @TODO Use properly formatted refNames for representative departments
1004 // in this example test record. The following are mere placeholders.
1005 depts.add("urn:org.collectionspace.services.department:Registrar");
1007 depts.add("urn:org.walkerart.department:Fine Art");
1009 multivalue = !multivalue;
1010 //FIXME: Title does not need to be set.
1011 collectionObject.setTitle("atitle");
1012 collectionObject.setResponsibleDepartments(deptList);
1013 collectionObject.setObjectNumber(objectNumber);
1014 collectionObject.setOtherNumber("urn:org.walkerart.id:123");
1015 collectionObject.setObjectName(objectName);
1016 collectionObject.setAge(""); //test for null string
1017 collectionObject.setBriefDescription("Papier mache bird cow mask with horns, "
1018 + "painted red with black and yellow spots. "
1019 + "Puerto Rico. ca. 8" high, 6" wide, projects 10" (with horns).");
1021 CollectionobjectsNaturalhistory conh = new CollectionobjectsNaturalhistory();
1022 conh.setNhString("test-string");
1024 conh.setNhLong(9999);
1027 MultipartOutput multipart = createCollectionObjectInstance(commonPartName, collectionObject, conh);
1032 * Creates the collection object instance.
1034 * @param commonPartName the common part name
1035 * @param collectionObject the collection object
1036 * @param conh the conh
1037 * @return the multipart output
1039 private MultipartOutput createCollectionObjectInstance(String commonPartName,
1040 CollectionobjectsCommon collectionObject, CollectionobjectsNaturalhistory conh) {
1042 MultipartOutput multipart = CollectionObjectFactory.createCollectionObjectInstance(
1043 commonPartName, collectionObject, getNHPartName(), conh);
1044 if (logger.isDebugEnabled()) {
1045 logger.debug("to be created, collectionobject common");
1046 logger.debug(objectAsXmlString(collectionObject,
1047 CollectionobjectsCommon.class));
1051 if (logger.isDebugEnabled()) {
1052 logger.debug("to be created, collectionobject nhistory");
1053 logger.debug(objectAsXmlString(conh,
1054 CollectionobjectsNaturalhistory.class));
1062 * createCollectionObjectInstanceFromXml uses JAXB unmarshaller to retrieve
1063 * collectionobject from given file
1064 * @param commonPartName
1065 * @param commonPartFileName
1069 private MultipartOutput createCollectionObjectInstanceFromXml(String testName, String commonPartName,
1070 String commonPartFileName) throws Exception {
1072 CollectionobjectsCommon collectionObject =
1073 (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class,
1074 commonPartFileName);
1075 MultipartOutput multipart = new MultipartOutput();
1076 OutputPart commonPart = multipart.addPart(collectionObject,
1077 MediaType.APPLICATION_XML_TYPE);
1078 commonPart.getHeaders().add("label", commonPartName);
1080 if (logger.isDebugEnabled()) {
1081 logger.debug(testName + " to be created, collectionobject common");
1082 logger.debug(objectAsXmlString(collectionObject,
1083 CollectionobjectsCommon.class));
1090 * createCollectionObjectInstanceFromRawXml uses stringified collectionobject
1091 * retrieve from given file
1092 * @param commonPartName
1093 * @param commonPartFileName
1097 private MultipartOutput createCollectionObjectInstanceFromRawXml(String testName, String commonPartName,
1098 String commonPartFileName) throws Exception {
1100 MultipartOutput multipart = new MultipartOutput();
1101 String stringObject = getXmlDocumentAsString(commonPartFileName);
1102 if (logger.isDebugEnabled()) {
1103 logger.debug(testName + " to be created, collectionobject common " + "\n" + stringObject);
1105 OutputPart commonPart = multipart.addPart(stringObject,
1106 MediaType.APPLICATION_XML_TYPE);
1107 commonPart.getHeaders().add("label", commonPartName);
1114 * Gets the nH part name.
1116 * @return the nH part name
1118 private String getNHPartName() {
1119 return "collectionobjects_naturalhistory";
1123 * Creates the from xml file.
1125 * @param testName the test name
1126 * @param fileName the file name
1127 * @param useJaxb the use jaxb
1128 * @return the string
1129 * @throws Exception the exception
1131 private String createFromXmlFile(String testName, String fileName, boolean useJaxb) throws Exception {
1132 // Perform setup, such as initializing the type of service request
1133 // (e.g. CREATE, DELETE), its valid and expected status codes, and
1134 // its associated HTTP method name (e.g. POST, DELETE).
1135 setupCreate(testName);
1137 MultipartOutput multipart = null;
1139 CollectionObjectClient client = new CollectionObjectClient();
1141 multipart = createCollectionObjectInstanceFromXml(testName,
1142 client.getCommonPartName(), fileName);
1144 multipart = createCollectionObjectInstanceFromRawXml(testName,
1145 client.getCommonPartName(), fileName);
1147 ClientResponse<Response> res = client.create(multipart);
1148 int statusCode = res.getStatus();
1150 if (logger.isDebugEnabled()) {
1151 logger.debug(testName + ": status = " + statusCode);
1153 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1154 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1155 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1156 String newId = extractId(res);
1157 allResourceIdsCreated.add(newId);