]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
30beb96ca7bdf521673bf338da68ca6fff25bd66
[tmp/jakarta-migration.git] /
1 /**
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:
5  *
6  * http://www.collectionspace.org
7  * http://wiki.collectionspace.org
8  *
9  * Copyright © 2009 Regents of the University of California
10  *
11  * Licensed under the Educational Community License (ECL), Version 2.0.
12  * You may not use this file except in compliance with this License.
13  *
14  * You may obtain a copy of the ECL 2.0 License at
15  * https://source.collectionspace.org/collection-space/LICENSE.txt
16  *
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.
22  */
23 package org.collectionspace.services.client.test;
24
25 import java.util.List;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
28
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.BriefDescriptionList;
34 import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
35 import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionobjectsNaturalhistory;
36 import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
37 import org.collectionspace.services.collectionobject.ResponsibleDepartmentList;
38 import org.collectionspace.services.collectionobject.ObjectNameGroup;
39 import org.collectionspace.services.collectionobject.ObjectNameList;
40 import org.collectionspace.services.collectionobject.OtherNumber;
41 import org.collectionspace.services.collectionobject.OtherNumberList;
42
43 import org.collectionspace.services.jaxb.AbstractCommonList;
44
45 import org.jboss.resteasy.client.ClientResponse;
46 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
47 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
48 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
49 import org.testng.Assert;
50 import org.testng.annotations.Test;
51
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 /**
56  * CollectionObjectServiceTest, carries out tests against a
57  * deployed and running CollectionObject Service.
58  *
59  * $LastChangedRevision$
60  * $LastChangedDate$
61  */
62 public class CollectionObjectServiceTest extends AbstractServiceTestImpl {
63
64     /** The logger. */
65     private final String CLASS_NAME = CollectionObjectServiceTest.class.getName();
66     private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
67     
68     // Instance variables specific to this test.
69     /** The known resource id. */
70     private String knownResourceId = null;
71
72     private final String OBJECT_NAME_VALUE = "an object name";
73
74     /* (non-Javadoc)
75      * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
76      */
77     @Override
78     protected String getServicePathComponent() {
79         return new CollectionObjectClient().getServicePathComponent();
80     }
81     
82     /* (non-Javadoc)
83      * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
84      */
85     @Override
86     protected CollectionSpaceClient getClientInstance() {
87         return new CollectionObjectClient();
88     }
89     
90     /* (non-Javadoc)
91      * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
92      */
93     @Override
94         protected AbstractCommonList getAbstractCommonList(
95                         ClientResponse<AbstractCommonList> response) {
96         return response.getEntity(CollectionobjectsCommonList.class);
97     }
98  
99     // ---------------------------------------------------------------
100     // CRUD tests : CREATE tests
101     // ---------------------------------------------------------------
102     // Success outcomes
103     /* (non-Javadoc)
104      * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String)
105      */
106     @Override
107     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
108     public void create(String testName) throws Exception {
109
110         if (logger.isDebugEnabled()) {
111             logger.debug(testBanner(testName, CLASS_NAME));
112         }
113         // Perform setup, such as initializing the type of service request
114         // (e.g. CREATE, DELETE), its valid and expected status codes, and
115         // its associated HTTP method name (e.g. POST, DELETE).
116         setupCreate();
117
118         // Submit the request to the service and store the response.
119         CollectionObjectClient client = new CollectionObjectClient();
120         String identifier = createIdentifier();
121         MultipartOutput multipart =
122                 createCollectionObjectInstance(client.getCommonPartName(), identifier);
123         ClientResponse<Response> res = client.create(multipart);
124         int statusCode = res.getStatus();
125
126         // Check the status code of the response: does it match
127         // the expected response(s)?
128         //
129         // Specifically:
130         // Does it fall within the set of valid status codes?
131         // Does it exactly match the expected status code?
132         if (logger.isDebugEnabled()) {
133             logger.debug(testName + ": status = " + statusCode);
134         }
135         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
136                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
137         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
138
139         // Store the ID returned from the first resource created
140         // for additional tests below.
141         if (knownResourceId == null) {
142             knownResourceId = extractId(res);
143             if (logger.isDebugEnabled()) {
144                 logger.debug(testName + ": knownResourceId=" + knownResourceId);
145             }
146         }
147
148         // Store the IDs from every resource created by tests,
149         // so they can be deleted after tests have been run.
150         allResourceIdsCreated.add(extractId(res));
151     }
152
153
154     /*
155      * Tests to diagnose and verify the fixed status of CSPACE-1026,
156      * "Whitespace at certain points in payload cause failure"
157      */
158     /**
159      * Creates the from xml cambridge.
160      *
161      * @param testName the test name
162      * @throws Exception the exception
163      */
164     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
165         dependsOnMethods = {"create", "testSubmitRequest"})
166     public void createFromXmlCambridge(String testName) throws Exception {
167         String newId =
168             createFromXmlFile(testName, "./test-data/testCambridge.xml", true);
169         testSubmitRequest(newId);
170     }
171
172    /*
173     * Tests to diagnose and fix CSPACE-2242.
174     *
175     * This is a bug identified in release 0.8 in which value instances of a
176     * repeatable field are not stored when the first value instance of that
177     * field is blank.
178     */
179
180     // Verify that record creation occurs successfully when the first value instance
181     // of a single, repeatable String scalar field is non-blank.
182     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
183         dependsOnMethods = {"create", "testSubmitRequest"}, groups = {"cspace2242group"})
184     public void createFromXmlNonBlankFirstValueInstance(String testName) throws Exception {
185         if (logger.isDebugEnabled()) {
186             logger.debug(testBanner(testName, CLASS_NAME));
187         }
188         String newId =
189             createFromXmlFile(testName, "./test-data/cspace-2242-first-value-instance-nonblank.xml", true);
190         CollectionobjectsCommon collectionObject = readCollectionObjectCommonPart(newId);
191         // Verify that at least one value instance of the repeatable field was successfully persisted.
192         BriefDescriptionList descriptionList = collectionObject.getBriefDescriptions();
193         List<String> descriptions = descriptionList.getBriefDescription();
194         Assert.assertTrue(descriptions.size() > 0);
195     }
196
197     // Verify that record creation occurs successfully when the first value instance
198     // of a single, repeatable String scalar field is blank.
199     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
200         dependsOnMethods = {"create", "testSubmitRequest"}, groups = {"cspace2242group"})
201     public void createFromXmlBlankFirstValueInstance(String testName) throws Exception {
202         if (logger.isDebugEnabled()) {
203             logger.debug(testBanner(testName, CLASS_NAME));
204         }
205         String newId =
206             createFromXmlFile(testName, "./test-data/cspace-2242-first-value-instance-blank.xml", true);
207         CollectionobjectsCommon collectionObject = readCollectionObjectCommonPart(newId);
208         // Verify that at least one value instance of the repeatable field was successfully persisted.
209         BriefDescriptionList descriptionList = collectionObject.getBriefDescriptions();
210         List<String> descriptions = descriptionList.getBriefDescription();
211         Assert.assertTrue(descriptions.size() > 0);
212     }
213
214     /**
215      * Creates the from xml rfw s1.
216      *
217      * @param testName the test name
218      * @throws Exception the exception
219      */
220     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
221         dependsOnMethods = {"create", "testSubmitRequest"})
222     public void createFromXmlRFWS1(String testName) throws Exception {
223         String testDataDir = System.getProperty("test-data.fileName");
224         String newId =
225             //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp1.xml", false);
226                 createFromXmlFile(testName, testDataDir + "/repfield_whitesp1.xml", false);
227         testSubmitRequest(newId);
228     }
229
230     /**
231      * Creates the from xml rfw s2.
232      *
233      * @param testName the test name
234      * @throws Exception the exception
235      */
236     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
237         dependsOnMethods = {"create", "testSubmitRequest"})
238     public void createFromXmlRFWS2(String testName) throws Exception {
239         String testDataDir = System.getProperty("test-data.fileName");
240         String newId =
241             //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp2.xml", false);
242                 createFromXmlFile(testName, testDataDir + "/repfield_whitesp2.xml", false);
243         testSubmitRequest(newId);
244     }
245
246     /**
247      * Creates the from xml rfw s3.
248      *
249      * @param testName the test name
250      * @throws Exception the exception
251      */
252     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
253         dependsOnMethods = {"create", "testSubmitRequest"})
254     public void createFromXmlRFWS3(String testName) throws Exception {
255         String testDataDir = System.getProperty("test-data.fileName");
256         String newId =
257             //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp3.xml", false);
258                 createFromXmlFile(testName, testDataDir + "/repfield_whitesp3.xml", false);
259         testSubmitRequest(newId);
260     }
261
262     /**
263      * Creates the from xml rfw s4.
264      *
265      * @param testName the test name
266      * @throws Exception the exception
267      */
268     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
269         dependsOnMethods = {"create", "testSubmitRequest"})
270     public void createFromXmlRFWS4(String testName) throws Exception {
271         String testDataDir = System.getProperty("test-data.fileName");
272         String newId =
273             createFromXmlFile(testName, testDataDir + "/repfield_whitesp4.xml", false);
274         testSubmitRequest(newId);
275     }
276
277     /*
278      * Tests to diagnose and verify the fixed status of CSPACE-1248,
279      * "Wedged records created!" (i.e. records with child repeatable
280      * fields, which contain null values, can be successfully created
281      * but an error occurs on trying to retrieve those records).
282      */
283
284     /**
285      * Creates a CollectionObject resource with a null value repeatable field.
286      *
287      * @param testName the test name
288      * @throws Exception the exception
289      */
290     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
291         dependsOnMethods = {"create", "testSubmitRequest"})
292     public void createWithNullValueRepeatableField(String testName) throws Exception {
293         String testDataDir = System.getProperty("test-data.fileName");
294         String newId =
295             createFromXmlFile(testName, testDataDir + "/repfield_null1.xml", false);
296         if (logger.isDebugEnabled()) {
297             logger.debug("Successfully created record with null value repeatable field.");
298             logger.debug("Attempting to retrieve just-created record ...");
299         }
300         testSubmitRequest(newId);
301     }
302     
303     /* (non-Javadoc)
304      * @see org.collectionspace.services.client.test.ServiceTest#createList()
305      */
306     @Override
307     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
308     dependsOnMethods = {"create"})
309     public void createList(String testName) throws Exception {
310         this.createPaginatedList(testName, DEFAULT_LIST_SIZE);
311     }
312
313     // Failure outcomes
314     // Placeholders until the three tests below can be uncommented.
315     // See Issue CSPACE-401.
316     /* (non-Javadoc)
317      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithEmptyEntityBody(java.lang.String)
318      */
319     @Override
320     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
321     public void createWithEmptyEntityBody(String testName) throws Exception {
322         //FIXME: Should this test really be empty?
323     }
324
325    /**
326     * Test how the service handles XML that is not well formed,
327     * when sent in the payload of a Create request.
328     *
329     * @param testName  The name of this test method.  This name is supplied
330     *     automatically, via reflection, by a TestNG 'data provider' in
331     *     a base class.
332     */
333     @Override
334     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
335     public void createWithMalformedXml(String testName) throws Exception {
336     }
337
338     /* (non-Javadoc)
339      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithWrongXmlSchema(java.lang.String)
340      */
341     @Override
342     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
343     public void createWithWrongXmlSchema(String testName) throws Exception {
344         //FIXME: Should this test really be empty?
345     }
346
347
348 /*
349     @Override
350     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
351     dependsOnMethods = {"create", "testSubmitRequest"})
352     public void createWithEmptyEntityBody(String testName) throwsException {
353
354         if (logger.isDebugEnabled()) {
355             logger.debug(testBanner(testName, CLASS_NAME));
356         }
357         // Perform setup.
358         setupCreateWithEmptyEntityBody();
359
360         // Submit the request to the service and store the response.
361         String method = REQUEST_TYPE.httpMethodName();
362         String url = getServiceRootURL();
363         String mediaType = MediaType.APPLICATION_XML;
364         final String entity = "";
365         int statusCode = submitRequest(method, url, mediaType, entity);
366
367         // Check the status code of the response: does it match
368         // the expected response(s)?
369         if(logger.isDebugEnabled()){
370         logger.debug(testName + ": url=" + url +
371         " status=" + statusCode);
372         }
373         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
374         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
375         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
376     }
377
378     @Override
379     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
380     dependsOnMethods = {"create", "testSubmitRequest"})
381     public void createWithMalformedXml(String testName) throws Exception {
382
383         if (logger.isDebugEnabled()) {
384             logger.debug(testBanner(testName, CLASS_NAME));
385         }
386         // Perform setup.
387         setupCreateWithMalformedXml();
388
389         // Submit the request to the service and store the response.
390         String method = REQUEST_TYPE.httpMethodName();
391         String url = getServiceRootURL();
392         String mediaType = MediaType.APPLICATION_XML;
393         final String entity = MALFORMED_XML_DATA; // Constant from base class.
394         int statusCode = submitRequest(method, url, mediaType, entity);
395
396         // Check the status code of the response: does it match
397         // the expected response(s)?
398         if(logger.isDebugEnabled()){
399         logger.debug(testName + ": url=" + url +
400         " status=" + statusCode);
401         }
402         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
403         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
404         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
405     }
406
407     @Override
408     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
409     dependsOnMethods = {"create", "testSubmitRequest"})
410     public void createWithWrongXmlSchema(String testName) throws Exception {
411
412         if (logger.isDebugEnabled()) {
413             logger.debug(testBanner(testName, CLASS_NAME));
414         }
415         // Perform setup.
416         setupCreateWithWrongXmlSchema();
417
418         // Submit the request to the service and store the response.
419         String method = REQUEST_TYPE.httpMethodName();
420         String url = getServiceRootURL();
421         String mediaType = MediaType.APPLICATION_XML;
422         final String entity = WRONG_XML_SCHEMA_DATA;
423         int statusCode = submitRequest(method, url, mediaType, entity);
424
425         // Check the status code of the response: does it match
426         // the expected response(s)?
427         if(logger.isDebugEnabled()){
428         logger.debug(testName + ": url=" + url +
429         " status=" + statusCode);
430         }
431         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
432         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
433         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
434     }
435 */
436
437    /**
438     * Test how the service handles, in a Create request, payloads
439     * containing null values (or, in the case of String fields,
440     * empty String values) in one or more fields which must be
441     * present and are required to contain non-empty values.
442     *
443     * This is a test of code and/or configuration in the service's
444     * validation routine(s).
445     *
446     * @param testName  The name of this test method.  This name is supplied
447     *     automatically, via reflection, by a TestNG 'data provider' in
448     *     a base class.
449     * @throws Exception 
450     */
451     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
452     public void createWithRequiredValuesNullOrEmpty(String testName) throws Exception {
453         if (logger.isDebugEnabled()) {
454             logger.debug(testBanner(testName, CLASS_NAME));
455         }
456         setupCreate();
457
458         // Build a payload with invalid content, by omitting a
459         // field (objectNumber) which must be present, and in which
460         // a non-empty value is required, as enforced by the service's
461         // validation routine(s).
462         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
463         collectionObject.setTitle("a title");
464
465         ObjectNameList objNameList = new ObjectNameList();
466         List<ObjectNameGroup> objNameGroups = objNameList.getObjectNameGroup();
467         ObjectNameGroup objectNameGroup = new ObjectNameGroup();
468         objectNameGroup.setObjectName("an object name");
469         objNameGroups.add(objectNameGroup);
470         collectionObject.setObjectNameList(objNameList);
471
472         // Submit the request to the service and store the response.
473         CollectionObjectClient client = new CollectionObjectClient();
474         MultipartOutput multipart =
475                 createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
476         ClientResponse<Response> res = client.create(multipart);
477         int statusCode = res.getStatus();
478
479         // Read the response and verify that the create attempt failed.
480         if (logger.isDebugEnabled()) {
481             logger.debug(testName + ": status = " + statusCode);
482         }
483         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
484                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
485         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
486
487         // FIXME: Consider splitting off the following into its own test method.
488         
489         // Build a payload with invalid content, by setting a value to the
490         // empty String, in a field that requires a non-empty value,
491         // as enforced by the service's validation routine(s).
492         collectionObject = new CollectionobjectsCommon();
493         collectionObject.setObjectNumber("");
494         collectionObject.setTitle("a title");
495         objNameList = new ObjectNameList();
496         objNameGroups = objNameList.getObjectNameGroup();
497         objectNameGroup = new ObjectNameGroup();
498         objectNameGroup.setObjectName(OBJECT_NAME_VALUE);
499         objNameGroups.add(objectNameGroup);
500         collectionObject.setObjectNameList(objNameList);
501
502         // Submit the request to the service and store the response.
503         multipart =
504             createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
505         res = client.create(multipart);
506         statusCode = res.getStatus();
507
508         // Read the response and verify that the create attempt failed.
509         if (logger.isDebugEnabled()) {
510             logger.debug(testName + ": status = " + statusCode);
511         }
512         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
513                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
514         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
515
516     }
517
518
519     // ---------------------------------------------------------------
520     // CRUD tests : READ tests
521     // ---------------------------------------------------------------
522     // Success outcomes
523     /* (non-Javadoc)
524      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String)
525      */
526     @Override
527     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
528     dependsOnMethods = {"create"})
529     public void read(String testName) throws Exception {
530
531         if (logger.isDebugEnabled()) {
532             logger.debug(testBanner(testName, CLASS_NAME));
533         }
534         // Perform setup.
535         setupRead();
536
537         // Submit the request to the service and store the response.
538         CollectionObjectClient client = new CollectionObjectClient();
539         ClientResponse<MultipartInput> res = client.read(knownResourceId);
540         int statusCode = res.getStatus();
541
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);
546         }
547         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
548                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
549         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
550
551         MultipartInput input = (MultipartInput) res.getEntity();
552
553         if (logger.isDebugEnabled()) {
554             logger.debug(testName + ": Reading Common part ...");
555         }
556         CollectionobjectsCommon collectionObject =
557                 (CollectionobjectsCommon) extractPart(input,
558                 client.getCommonPartName(), CollectionobjectsCommon.class);
559         Assert.assertNotNull(collectionObject);
560
561         if (logger.isDebugEnabled()) {
562             logger.debug(testName + ": Reading Natural History part ...");
563         }
564         CollectionobjectsNaturalhistory conh =
565                 (CollectionobjectsNaturalhistory) extractPart(input,
566                 getNHPartName(), CollectionobjectsNaturalhistory.class);
567         Assert.assertNotNull(conh);
568     }
569
570     // Failure outcomes
571     /* (non-Javadoc)
572      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readNonExistent(java.lang.String)
573      */
574     @Override
575     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
576     dependsOnMethods = {"read"})
577     public void readNonExistent(String testName) throws Exception {
578
579         if (logger.isDebugEnabled()) {
580             logger.debug(testBanner(testName, CLASS_NAME));
581         }
582         // Perform setup.
583         setupReadNonExistent();
584
585         // Submit the request to the service and store the response.
586         CollectionObjectClient client = new CollectionObjectClient();
587         ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
588         int statusCode = res.getStatus();
589
590         // Check the status code of the response: does it match
591         // the expected response(s)?
592         if (logger.isDebugEnabled()) {
593             logger.debug(testName + ": status = " + statusCode);
594         }
595         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
596                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
597         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
598     }
599
600     
601     // ---------------------------------------------------------------
602     // CRUD tests : READ_LIST tests
603     // ---------------------------------------------------------------
604     // Success outcomes
605     /* (non-Javadoc)
606      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readList(java.lang.String)
607      */
608     @Override
609     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
610     dependsOnMethods = {"createList", "read"})
611     public void readList(String testName) throws Exception {
612
613         if (logger.isDebugEnabled()) {
614             logger.debug(testBanner(testName, CLASS_NAME));
615         }
616         // Perform setup.
617         setupReadList();
618
619         // Submit the request to the service and store the response.
620         CollectionObjectClient client = new CollectionObjectClient();
621         ClientResponse<CollectionobjectsCommonList> res = client.readList();
622         CollectionobjectsCommonList list = res.getEntity();
623         int statusCode = res.getStatus();
624
625         // Check the status code of the response: does it match
626         // the expected response(s)?
627         if (logger.isDebugEnabled()) {
628             logger.debug(testName + ": status = " + statusCode);
629         }
630         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
631                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
632         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
633
634         // Optionally output additional data about list members for debugging.
635         boolean iterateThroughList = false;
636         if (iterateThroughList && logger.isDebugEnabled()) {
637             List<CollectionobjectsCommonList.CollectionObjectListItem> items =
638                     list.getCollectionObjectListItem();
639             int i = 0;
640
641             for (CollectionobjectsCommonList.CollectionObjectListItem item : items) {
642                 logger.debug(testName + ": list-item[" + i + "] csid="
643                         + item.getCsid());
644                 logger.debug(testName + ": list-item[" + i + "] objectNumber="
645                         + item.getObjectNumber());
646                 logger.debug(testName + ": list-item[" + i + "] URI="
647                         + item.getUri());
648                 i++;
649
650             }
651         }
652     }
653
654     // Failure outcomes
655     // None at present.
656     // ---------------------------------------------------------------
657     // CRUD tests : UPDATE tests
658     // ---------------------------------------------------------------
659     // Success outcomes
660     /* (non-Javadoc)
661      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String)
662      */
663     @Override
664     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
665     dependsOnMethods = {"read"})
666     public void update(String testName) throws Exception {
667
668         if (logger.isDebugEnabled()) {
669             logger.debug(testBanner(testName, CLASS_NAME));
670         }
671         // Perform setup.
672         setupUpdate();
673
674         // Read an existing resource that will be updated.
675         ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
676
677         // Extract its common part.
678         CollectionObjectClient client = new CollectionObjectClient();
679         MultipartInput input = (MultipartInput) res.getEntity();
680         CollectionobjectsCommon collectionObject =
681                 (CollectionobjectsCommon) extractPart(input,
682                 client.getCommonPartName(), CollectionobjectsCommon.class);
683         Assert.assertNotNull(collectionObject);
684
685         // Change the content of one or more fields in the common part.
686         collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
687         
688         ObjectNameList objNameList = collectionObject.getObjectNameList();
689         List<ObjectNameGroup> objNameGroups = objNameList.getObjectNameGroup();
690         Assert.assertNotNull(objNameGroups);
691         Assert.assertTrue(objNameGroups.size() >= 1);
692         String objectName = objNameGroups.get(0).getObjectName();
693         Assert.assertEquals(objectName, OBJECT_NAME_VALUE);
694         String updatedObjectName = "updated-" + objectName;
695         objNameGroups.get(0).setObjectName(updatedObjectName);
696         collectionObject.setObjectNameList(objNameList);
697
698         if (logger.isDebugEnabled()) {
699             logger.debug("sparse update that will be sent in update request:");
700             logger.debug(objectAsXmlString(collectionObject,
701                     CollectionobjectsCommon.class));
702         }
703
704         // Send the changed resource to be updated.
705         res = updateSend(testName, knownResourceId, collectionObject);
706         int statusCode = res.getStatus();
707         // Check the status code of the response: does it match the expected response(s)?
708         if (logger.isDebugEnabled()) {
709             logger.debug(testName + ": status = " + statusCode);
710         }
711         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
712                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
713         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
714
715         // Read the response and verify that the resource was correctly updated.
716         input = (MultipartInput) res.getEntity();
717         CollectionobjectsCommon updatedCollectionObject =
718                 (CollectionobjectsCommon) extractPart(input,
719                 client.getCommonPartName(), CollectionobjectsCommon.class);
720         Assert.assertNotNull(updatedCollectionObject);
721
722         objNameList = collectionObject.getObjectNameList();
723         objNameGroups = objNameList.getObjectNameGroup();
724         Assert.assertNotNull(objNameGroups);
725         Assert.assertTrue(objNameGroups.size() >= 1);
726         Assert.assertEquals(updatedObjectName,
727                 objNameGroups.get(0).getObjectName(),
728                 "Data in updated object did not match submitted data.");
729
730     }
731
732     /**
733      * Update retrieve.
734      *
735      * @param testName the test name
736      * @param id the id
737      * @return the client response
738      */
739     private ClientResponse<MultipartInput> updateRetrieve(String testName, String id) {
740         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
741         CollectionObjectClient client = new CollectionObjectClient();
742         ClientResponse<MultipartInput> res = client.read(id);
743         if (logger.isDebugEnabled()) {
744             logger.debug("read in updateRetrieve for " + testName + " status = " + res.getStatus());
745         }
746         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS);
747         if (logger.isDebugEnabled()) {
748             logger.debug("got object to updateRetrieve for " + testName + " with ID: " + id);
749         }
750         return res;
751     }
752
753     /**
754      * Update send.
755      *
756      * @param testName the test name
757      * @param id the id
758      * @param collectionObject the collection object
759      * @return the client response
760      */
761     private ClientResponse<MultipartInput> updateSend(String testName, String id,
762             CollectionobjectsCommon collectionObject) {
763         MultipartOutput output = new MultipartOutput();
764         OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
765         CollectionObjectClient client = new CollectionObjectClient();
766         commonPart.getHeaders().add("label", client.getCommonPartName());
767         ClientResponse<MultipartInput> res = client.update(knownResourceId, output);
768         return res;
769     }
770
771     // Failure outcomes
772     // Placeholders until the three tests below can be uncommented.
773     // See Issue CSPACE-401.
774     /* (non-Javadoc)
775      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithEmptyEntityBody(java.lang.String)
776      */
777     @Override
778     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
779     dependsOnMethods = {"read"})
780     public void updateWithEmptyEntityBody(String testName) throws Exception {
781         //FIXME: Should this test really be empty?
782     }
783
784    /**
785     * Test how the service handles XML that is not well formed,
786     * when sent in the payload of an Update request.
787     *
788     * @param testName  The name of this test method.  This name is supplied
789     *     automatically, via reflection, by a TestNG 'data provider' in
790     *     a base class.
791     */
792     @Override
793     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
794     dependsOnMethods = {"read"})
795     public void updateWithMalformedXml(String testName) throws Exception {
796         //FIXME: Should this test really be empty?
797     }
798
799     /* (non-Javadoc)
800      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithWrongXmlSchema(java.lang.String)
801      */
802     @Override
803     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
804     dependsOnMethods = {"read"})
805     public void updateWithWrongXmlSchema(String testName) throws Exception {
806         //FIXME: Should this test really be empty?
807     }
808
809 /*
810     @Override
811     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
812     dependsOnMethods = {"create", "update", "testSubmitRequest"})
813     public void updateWithEmptyEntityBody(String testName) throws Exception {
814
815         if (logger.isDebugEnabled()) {
816             logger.debug(testBanner(testName, CLASS_NAME));
817         }
818         // Perform setup.
819         setupUpdateWithEmptyEntityBody();
820
821         // Submit the request to the service and store the response.
822         String method = REQUEST_TYPE.httpMethodName();
823         String url = getResourceURL(knownResourceId);
824         String mediaType = MediaType.APPLICATION_XML;
825         final String entity = "";
826         int statusCode = submitRequest(method, url, mediaType, entity);
827
828         // Check the status code of the response: does it match
829         // the expected response(s)?
830         if(logger.isDebugEnabled()){
831         logger.debug(testName + ": url=" + url +
832         " status=" + statusCode);
833         }
834         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
835         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
836         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
837     }
838
839     @Override
840     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
841     dependsOnMethods = {"create", "update", "testSubmitRequest"})
842     public void updateWithMalformedXml() throws Exception {
843
844         if (logger.isDebugEnabled()) {
845             logger.debug(testBanner(testName, CLASS_NAME));
846         }
847         // Perform setup.
848         setupUpdateWithMalformedXml();
849
850         // Submit the request to the service and store the response.
851         String method = REQUEST_TYPE.httpMethodName();
852         String url = getResourceURL(knownResourceId);
853         final String entity = MALFORMED_XML_DATA;
854         String mediaType = MediaType.APPLICATION_XML;
855         int statusCode = submitRequest(method, url, mediaType, entity);
856
857         // Check the status code of the response: does it match
858         // the expected response(s)?
859         if(logger.isDebugEnabled()){
860         logger.debug(testName + ": url=" + url +
861         " status=" + statusCode);
862         }
863         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
864         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
865         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
866     }
867
868     @Override
869     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
870     dependsOnMethods = {"create", "update", "testSubmitRequest"})
871     public void updateWithWrongXmlSchema(String testName) throws Exception {
872
873         if (logger.isDebugEnabled()) {
874             logger.debug(testBanner(testName, CLASS_NAME));
875         }
876         // Perform setup.
877         setupUpdateWithWrongXmlSchema();
878
879         // Submit the request to the service and store the response.
880         String method = REQUEST_TYPE.httpMethodName();
881         String url = getResourceURL(knownResourceId);
882         String mediaType = MediaType.APPLICATION_XML;
883         final String entity = WRONG_XML_SCHEMA_DATA;
884         int statusCode = submitRequest(method, url, mediaType, entity);
885
886         // Check the status code of the response: does it match
887         // the expected response(s)?
888         if(logger.isDebugEnabled()){
889         logger.debug(testName + ": url=" + url +
890         " status=" + statusCode);
891         }
892         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
893         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
894         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
895     }
896 */
897
898     /* (non-Javadoc)
899  * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateNonExistent(java.lang.String)
900  */
901 @Override
902     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
903     dependsOnMethods = {"update", "testSubmitRequest"})
904     public void updateNonExistent(String testName) throws Exception {
905
906         if (logger.isDebugEnabled()) {
907             logger.debug(testBanner(testName, CLASS_NAME));
908         }
909         // Perform setup.
910         setupUpdateNonExistent();
911
912         // Submit the request to the service and store the response.
913         //
914         // Note: The ID used in this 'create' call may be arbitrary.
915         // The only relevant ID may be the one used in updateCollectionObject(), below.
916         CollectionObjectClient client = new CollectionObjectClient();
917         MultipartOutput multipart =
918                 createCollectionObjectInstance(client.getCommonPartName(),
919                 NON_EXISTENT_ID);
920         ClientResponse<MultipartInput> res =
921                 client.update(NON_EXISTENT_ID, multipart);
922         int statusCode = res.getStatus();
923
924         // Check the status code of the response: does it match
925         // the expected response(s)?
926         if (logger.isDebugEnabled()) {
927             logger.debug(testName + ": status = " + statusCode);
928         }
929         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
930                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
931         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
932     }
933
934    /**
935     * Test how the service handles, in an Update request, payloads
936     * containing null values (or, in the case of String fields,
937     * empty String values) in one or more fields in which non-empty
938     * values are required.
939     *
940     * This is a test of code and/or configuration in the service's
941     * validation routine(s).
942     *
943     * @param testName  The name of this test method.  This name is supplied
944     *     automatically, via reflection, by a TestNG 'data provider' in
945     *     a base class.
946  * @throws Exception 
947     */
948     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
949     dependsOnMethods = {"read"})
950     public void updateWithRequiredValuesNullOrEmpty(String testName) throws Exception {
951   
952         if (logger.isDebugEnabled()) {
953             logger.debug(testBanner(testName, CLASS_NAME));
954         }
955         // Perform setup.
956         setupUpdate();
957         if (logger.isDebugEnabled()) {
958             logger.debug(testName + " got object to update with ID: " + knownResourceId);
959         }
960
961         // Read an existing record for updating.
962         ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
963
964         CollectionObjectClient client = new CollectionObjectClient();
965         MultipartInput input = (MultipartInput) res.getEntity();
966         CollectionobjectsCommon collectionObject =
967                 (CollectionobjectsCommon) extractPart(input,
968                 client.getCommonPartName(), CollectionobjectsCommon.class);
969         Assert.assertNotNull(collectionObject);
970
971         // Update with invalid content, by setting a value to the
972         // empty String, in a field that requires a non-empty value,
973         // as enforced by the service's validation routine(s).
974         collectionObject.setObjectNumber("");
975
976         if (logger.isDebugEnabled()) {
977             logger.debug(testName + " updated object");
978             logger.debug(objectAsXmlString(collectionObject,
979                     CollectionobjectsCommon.class));
980         }
981
982         // Submit the request to the service and store the response.
983         res = updateSend(testName, knownResourceId, collectionObject);
984         int statusCode = res.getStatus();
985
986         // Read the response and verify that the update attempt failed.
987         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
988                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
989         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
990
991     }
992
993     // ---------------------------------------------------------------
994     // CRUD tests : DELETE tests
995     // ---------------------------------------------------------------
996     // Success outcomes
997     /* (non-Javadoc)
998      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String)
999      */
1000     @Override
1001     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
1002     dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
1003     public void delete(String testName) throws Exception {
1004
1005         if (logger.isDebugEnabled()) {
1006             logger.debug(testBanner(testName, CLASS_NAME));
1007         }
1008         // Perform setup.
1009         setupDelete();
1010
1011         // Submit the request to the service and store the response.
1012         CollectionObjectClient client = new CollectionObjectClient();
1013         ClientResponse<Response> res = client.delete(knownResourceId);
1014         int statusCode = res.getStatus();
1015
1016         // Check the status code of the response: does it match
1017         // the expected response(s)?
1018         if (logger.isDebugEnabled()) {
1019             logger.debug(testName + ": status = " + statusCode);
1020         }
1021         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1022                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1023         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1024     }
1025
1026     // Failure outcomes
1027     /* (non-Javadoc)
1028      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String)
1029      */
1030     @Override
1031     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
1032     dependsOnMethods = {"delete"})
1033     public void deleteNonExistent(String testName) throws Exception {
1034
1035         if (logger.isDebugEnabled()) {
1036             logger.debug(testBanner(testName, CLASS_NAME));
1037         }
1038         // Perform setup.
1039         setupDeleteNonExistent();
1040
1041         // Submit the request to the service and store the response.
1042         CollectionObjectClient client = new CollectionObjectClient();
1043         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
1044         int statusCode = res.getStatus();
1045
1046         // Check the status code of the response: does it match
1047         // the expected response(s)?
1048         if (logger.isDebugEnabled()) {
1049             logger.debug(testName + ": status = " + statusCode);
1050         }
1051         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1052                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1053         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1054     }
1055
1056     // ---------------------------------------------------------------
1057     // Utility tests : tests of code used in tests above
1058     // ---------------------------------------------------------------
1059     /**
1060      * Tests the code for manually submitting data that is used by several
1061      * of the methods above.
1062      * @throws Exception 
1063      */
1064
1065     @Test(dependsOnMethods = {"create", "read"})
1066     public void testSubmitRequest() throws Exception {
1067         testSubmitRequest(knownResourceId);
1068     }
1069
1070     /**
1071      * Test submit request.
1072      *
1073      * @param resourceId the resource id
1074      * @throws Exception the exception
1075      */
1076     private void testSubmitRequest(String resourceId) throws Exception {
1077
1078         // Expected status code: 200 OK
1079         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
1080
1081         // Submit the request to the service and store the response.
1082         String method = ServiceRequestType.READ.httpMethodName();
1083         String url = getResourceURL(resourceId);
1084         int statusCode = submitRequest(method, url);
1085
1086         // Check the status code of the response: does it match
1087         // the expected response(s)?
1088         if (logger.isDebugEnabled()) {
1089             logger.debug("testSubmitRequest: url=" + url
1090                     + " status=" + statusCode);
1091         }
1092         Assert.assertEquals(statusCode, EXPECTED_STATUS);
1093
1094     }
1095
1096     // ---------------------------------------------------------------
1097     // Utility methods used by tests above
1098     // ---------------------------------------------------------------
1099     /**
1100      * Creates the collection object instance.
1101      *
1102      * @param commonPartName the common part name
1103      * @param identifier the identifier
1104      * @return the multipart output
1105      */
1106     private MultipartOutput createCollectionObjectInstance(String commonPartName,
1107             String identifier) {
1108         return createCollectionObjectInstance(commonPartName,
1109                 "objectNumber-" + identifier,
1110                 "objectName-" + identifier);
1111     }
1112
1113     /**
1114      * Creates the collection object instance.
1115      *
1116      * @param commonPartName the common part name
1117      * @param objectNumber the object number
1118      * @param objectName the object name
1119      * @return the multipart output
1120      */
1121     private MultipartOutput createCollectionObjectInstance(String commonPartName,
1122             String objectNumber, String objectName) {
1123         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
1124
1125         BriefDescriptionList descriptionList = new BriefDescriptionList();
1126         List<String> descriptions = descriptionList.getBriefDescription();
1127         descriptions.add("Papier mache bird cow mask with horns, "
1128                 + "painted red with black and yellow spots. "
1129                 + "Puerto Rico. ca. 8&quot; high, 6&quot; wide, projects 10&quot; (with horns).");
1130         descriptions.add("Papier mache bird cow mask with horns, "
1131                 + "painted red with black and yellow spots. "
1132                 + "Puerto Rico. ca. 8&quot; high, 6&quot; wide, projects 10&quot; (with horns).");
1133
1134         ResponsibleDepartmentList deptList = new ResponsibleDepartmentList();
1135         List<String> depts = deptList.getResponsibleDepartment();
1136         // @TODO Use properly formatted refNames for representative departments
1137         // in this example test record. The following are mere placeholders.
1138         depts.add("urn:org.collectionspace.services.department:Registrar");
1139         depts.add("urn:org.walkerart.department:Fine Art");
1140
1141         OtherNumberList otherNumList = new OtherNumberList();
1142         List<OtherNumber> otherNumbers = otherNumList.getOtherNumber();
1143         
1144         OtherNumber otherNumber1 = new OtherNumber();        
1145         otherNumber1.setNumberValue("101." + objectName);
1146         otherNumber1.setNumberType("integer");
1147         otherNumbers.add(otherNumber1);
1148         
1149         OtherNumber otherNumber2 = new OtherNumber();
1150         otherNumber2.setNumberValue("101.502.23.456." + objectName);
1151         otherNumber2.setNumberType("ipaddress");
1152         otherNumbers.add(otherNumber2);        
1153         
1154         //FIXME: Title does not need to be set.
1155         collectionObject.setTitle("atitle");
1156         collectionObject.setResponsibleDepartments(deptList);
1157         collectionObject.setObjectNumber(objectNumber);
1158         
1159         collectionObject.setOtherNumberList(otherNumList);
1160
1161         // FIXME this can be removed when the repeatable other number list
1162         // is supported by the application layers
1163         collectionObject.setOtherNumber("urn:org.walkerart.id:123");
1164         
1165         ObjectNameList objNameList = new ObjectNameList();
1166         List<ObjectNameGroup> objNameGroups = objNameList.getObjectNameGroup();
1167         ObjectNameGroup objectNameGroup = new ObjectNameGroup();
1168         objectNameGroup.setObjectName(OBJECT_NAME_VALUE);
1169         objNameGroups.add(objectNameGroup);
1170         collectionObject.setObjectNameList(objNameList);
1171
1172         collectionObject.setAge(""); //test for null string
1173         collectionObject.setBriefDescriptions(descriptionList);
1174
1175         CollectionobjectsNaturalhistory conh = new CollectionobjectsNaturalhistory();
1176         conh.setNhString("test-string");
1177         conh.setNhInt(999);
1178         conh.setNhLong(9999);
1179
1180
1181         MultipartOutput multipart = createCollectionObjectInstance(commonPartName, collectionObject, conh);
1182         return multipart;
1183     }
1184
1185     /**
1186      * Creates the collection object instance.
1187      *
1188      * @param commonPartName the common part name
1189      * @param collectionObject the collection object
1190      * @param conh the conh
1191      * @return the multipart output
1192      */
1193     private MultipartOutput createCollectionObjectInstance(String commonPartName,
1194             CollectionobjectsCommon collectionObject, CollectionobjectsNaturalhistory conh) {
1195
1196         MultipartOutput multipart = CollectionObjectFactory.createCollectionObjectInstance(
1197                 commonPartName, collectionObject, getNHPartName(), conh);
1198         if (logger.isDebugEnabled()) {
1199             logger.debug("to be created, collectionobject common");
1200             logger.debug(objectAsXmlString(collectionObject,
1201                     CollectionobjectsCommon.class));
1202         }
1203
1204         if (conh != null) {
1205             if (logger.isDebugEnabled()) {
1206                 logger.debug("to be created, collectionobject nhistory");
1207                 logger.debug(objectAsXmlString(conh,
1208                         CollectionobjectsNaturalhistory.class));
1209             }
1210         }
1211         return multipart;
1212
1213     }
1214
1215     /**
1216      * createCollectionObjectInstanceFromXml uses JAXB unmarshaller to retrieve
1217      * collectionobject from given file
1218      * @param commonPartName
1219      * @param commonPartFileName
1220      * @return
1221      * @throws Exception
1222      */
1223     private MultipartOutput createCollectionObjectInstanceFromXml(String testName, String commonPartName,
1224             String commonPartFileName) throws Exception {
1225
1226         CollectionobjectsCommon collectionObject =
1227                 (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class,
1228                 commonPartFileName);
1229         MultipartOutput multipart = new MultipartOutput();
1230         OutputPart commonPart = multipart.addPart(collectionObject,
1231                 MediaType.APPLICATION_XML_TYPE);
1232         commonPart.getHeaders().add("label", commonPartName);
1233
1234         if (logger.isDebugEnabled()) {
1235             logger.debug(testName + " to be created, collectionobject common");
1236             logger.debug(objectAsXmlString(collectionObject,
1237                     CollectionobjectsCommon.class));
1238         }
1239         return multipart;
1240
1241     }
1242
1243     /**
1244      * createCollectionObjectInstanceFromRawXml uses stringified collectionobject
1245      * retrieve from given file
1246      * @param commonPartName
1247      * @param commonPartFileName
1248      * @return
1249      * @throws Exception
1250      */
1251     private MultipartOutput createCollectionObjectInstanceFromRawXml(String testName, String commonPartName,
1252             String commonPartFileName) throws Exception {
1253
1254         MultipartOutput multipart = new MultipartOutput();
1255         String stringObject = getXmlDocumentAsString(commonPartFileName);
1256         if (logger.isDebugEnabled()) {
1257             logger.debug(testName + " to be created, collectionobject common " + "\n" + stringObject);
1258         }
1259         OutputPart commonPart = multipart.addPart(stringObject,
1260                 MediaType.APPLICATION_XML_TYPE);
1261         commonPart.getHeaders().add("label", commonPartName);
1262
1263         return multipart;
1264
1265     }
1266
1267     /**
1268      * Gets the nH part name.
1269      *
1270      * @return the nH part name
1271      */
1272     private String getNHPartName() {
1273         return "collectionobjects_naturalhistory";
1274     }
1275
1276     /**
1277      * Creates the from xml file.
1278      *
1279      * @param testName the test name
1280      * @param fileName the file name
1281      * @param useJaxb the use jaxb
1282      * @return the string
1283      * @throws Exception the exception
1284      */
1285     private String createFromXmlFile(String testName, String fileName, boolean useJaxb) throws Exception {
1286   
1287         // Perform setup.
1288         setupCreate();
1289
1290         MultipartOutput multipart = null;
1291
1292         CollectionObjectClient client = new CollectionObjectClient();
1293         if (useJaxb) {
1294             multipart = createCollectionObjectInstanceFromXml(testName,
1295                     client.getCommonPartName(), fileName);
1296         } else {
1297             multipart = createCollectionObjectInstanceFromRawXml(testName,
1298                     client.getCommonPartName(), fileName);
1299         }
1300         ClientResponse<Response> res = client.create(multipart);
1301         int statusCode = res.getStatus();
1302
1303         if (logger.isDebugEnabled()) {
1304             logger.debug(testName + ": status = " + statusCode);
1305         }
1306         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1307                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1308         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1309         String newId = extractId(res);
1310         allResourceIdsCreated.add(newId);
1311         return newId;
1312     }
1313
1314     // FIXME: This duplicates code in read(), and should be consolidated.
1315     // This is an expedient to support reading and verifying the contents
1316     // of resources that have been created from test data XML files.
1317     private CollectionobjectsCommon readCollectionObjectCommonPart(String csid)
1318         throws Exception {
1319
1320         String testName = "readCollectionObjectCommonPart";
1321
1322         setupRead();
1323
1324         // Submit the request to the service and store the response.
1325         CollectionObjectClient client = new CollectionObjectClient();
1326         ClientResponse<MultipartInput> res = client.read(csid);
1327         int statusCode = res.getStatus();
1328
1329         // Check the status code of the response: does it match
1330         // the expected response(s)?
1331         if (logger.isDebugEnabled()) {
1332             logger.debug(testName + ": status = " + statusCode);
1333         }
1334         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1335                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1336         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1337
1338         MultipartInput input = (MultipartInput) res.getEntity();
1339
1340         if (logger.isDebugEnabled()) {
1341             logger.debug(testName + ": Reading Common part ...");
1342         }
1343         CollectionobjectsCommon collectionObject =
1344                 (CollectionobjectsCommon) extractPart(input,
1345                 client.getCommonPartName(), CollectionobjectsCommon.class);
1346         Assert.assertNotNull(collectionObject);
1347
1348         return collectionObject;
1349      }
1350 }