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