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