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