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