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