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