]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
f1861d2c68d3a82a8c1762f92680b0b0224088ea
[tmp/jakarta-migration.git] /
1 /**
2  * This document is a part of the source code and related artifacts
3  * for CollectionSpace, an open source collections management system
4  * for museums and related institutions:
5  *
6  * http://www.collectionspace.org
7  * http://wiki.collectionspace.org
8  *
9  * Copyright © 2009 Regents of the University of California
10  *
11  * Licensed under the Educational Community License (ECL), Version 2.0.
12  * You may not use this file except in compliance with this License.
13  *
14  * You may obtain a copy of the ECL 2.0 License at
15  * https://source.collectionspace.org/collection-space/LICENSE.txt
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 package org.collectionspace.services.client.test;
24
25 import java.util.ArrayList;
26 import java.util.List;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
29
30 import org.collectionspace.services.client.AbstractServiceClientImpl;
31 import org.collectionspace.services.client.CollectionObjectClient;
32 import org.collectionspace.services.client.CollectionSpaceClient;
33 import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
34 import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionobjectsNaturalhistory;
35 import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
36 import org.collectionspace.services.collectionobject.ResponsibleDepartmentList;
37 import org.collectionspace.services.jaxb.AbstractCommonList;
38
39 import org.jboss.resteasy.client.ClientResponse;
40 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
41 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
42 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
43 import org.testng.Assert;
44 import org.testng.annotations.AfterClass;
45 import org.testng.annotations.Test;
46
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 /**
51  * CollectionObjectServiceTest, carries out tests against a
52  * deployed and running CollectionObject Service.
53  *
54  * $LastChangedRevision$
55  * $LastChangedDate$
56  */
57 public class CollectionObjectServiceTest extends AbstractServiceTestImpl {
58
59     /** The logger. */
60     private final Logger logger =
61             LoggerFactory.getLogger(CollectionObjectServiceTest.class);
62     // Instance variables specific to this test.
63     /** The known resource id. */
64     private String knownResourceId = null;
65     
66     /** The all resource ids created. */
67     private List<String> allResourceIdsCreated = new ArrayList();
68     
69     /** The multivalue. */
70     private boolean multivalue; //toggle
71
72     /**
73      * Gets the logger.
74      *
75      * @return the logger
76      */
77     private Logger getLogger() {
78         return this.logger;
79     }
80
81     /* (non-Javadoc)
82      * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
83      */
84     @Override
85     protected String getServicePathComponent() {
86         return new CollectionObjectClient().getServicePathComponent();
87     }
88     
89     /* (non-Javadoc)
90      * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
91      */
92     @Override
93     protected CollectionSpaceClient getClientInstance() {
94         return new CollectionObjectClient();
95     }
96     
97     /* (non-Javadoc)
98      * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
99      */
100     @Override
101         protected AbstractCommonList getAbstractCommonList(
102                         ClientResponse<AbstractCommonList> response) {
103         return response.getEntity(CollectionobjectsCommonList.class);
104     }
105  
106     // ---------------------------------------------------------------
107     // CRUD tests : CREATE tests
108     // ---------------------------------------------------------------
109     // Success outcomes
110     /* (non-Javadoc)
111      * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String)
112      */
113     @Override
114     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
115     public void create(String testName) throws Exception {
116
117         // Perform setup, such as initializing the type of service request
118         // (e.g. CREATE, DELETE), its valid and expected status codes, and
119         // its associated HTTP method name (e.g. POST, DELETE).
120         setupCreate(testName);
121
122         // Submit the request to the service and store the response.
123         CollectionObjectClient client = new CollectionObjectClient();
124         String identifier = createIdentifier();
125         MultipartOutput multipart =
126                 createCollectionObjectInstance(client.getCommonPartName(), identifier);
127         ClientResponse<Response> res = client.create(multipart);
128         int statusCode = res.getStatus();
129
130         // Check the status code of the response: does it match
131         // the expected response(s)?
132         //
133         // Specifically:
134         // Does it fall within the set of valid status codes?
135         // Does it exactly match the expected status code?
136         if (logger.isDebugEnabled()) {
137             logger.debug(testName + ": status = " + statusCode);
138         }
139         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
140                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
141         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
142
143         // Store the ID returned from the first resource created
144         // for additional tests below.
145         if (knownResourceId == null) {
146             knownResourceId = extractId(res);
147             if (logger.isDebugEnabled()) {
148                 logger.debug(testName + ": knownResourceId=" + knownResourceId);
149             }
150         }
151
152         // Store the IDs from every resource created by tests,
153         // so they can be deleted after tests have been run.
154         allResourceIdsCreated.add(extractId(res));
155     }
156
157
158     /*
159      * Tests to diagnose and verify the fixed status of CSPACE-1026,
160      * "Whitespace at certain points in payload cause failure"
161      */
162     /**
163      * Creates the from xml cambridge.
164      *
165      * @param testName the test name
166      * @throws Exception the exception
167      */
168     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
169         dependsOnMethods = {"create", "testSubmitRequest"})
170     public void createFromXmlCambridge(String testName) throws Exception {
171         String newId =
172             createFromXmlFile(testName, "./test-data/testCambridge.xml", true);
173         testSubmitRequest(newId);
174     }
175
176     /**
177      * Creates the from xml rfw s1.
178      *
179      * @param testName the test name
180      * @throws Exception the exception
181      */
182     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
183         dependsOnMethods = {"create", "testSubmitRequest"})
184     public void createFromXmlRFWS1(String testName) throws Exception {
185         String testDataDir = System.getProperty("test-data.fileName");
186         String newId =
187             //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp1.xml", false);
188                 createFromXmlFile(testName, testDataDir + "/repfield_whitesp1.xml", false);
189         testSubmitRequest(newId);
190     }
191
192     /**
193      * Creates the from xml rfw s2.
194      *
195      * @param testName the test name
196      * @throws Exception the exception
197      */
198     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
199         dependsOnMethods = {"create", "testSubmitRequest"})
200     public void createFromXmlRFWS2(String testName) throws Exception {
201         String testDataDir = System.getProperty("test-data.fileName");
202         String newId =
203             //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp2.xml", false);
204                 createFromXmlFile(testName, testDataDir + "/repfield_whitesp2.xml", false);
205         testSubmitRequest(newId);
206     }
207
208     /**
209      * Creates the from xml rfw s3.
210      *
211      * @param testName the test name
212      * @throws Exception the exception
213      */
214     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
215         dependsOnMethods = {"create", "testSubmitRequest"})
216     public void createFromXmlRFWS3(String testName) throws Exception {
217         String testDataDir = System.getProperty("test-data.fileName");
218         String newId =
219             //createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp3.xml", false);
220                 createFromXmlFile(testName, testDataDir + "/repfield_whitesp3.xml", false);
221         testSubmitRequest(newId);
222     }
223
224     /**
225      * Creates the from xml rfw s4.
226      *
227      * @param testName the test name
228      * @throws Exception the exception
229      */
230     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
231         dependsOnMethods = {"create", "testSubmitRequest"})
232     public void createFromXmlRFWS4(String testName) throws Exception {
233         String testDataDir = System.getProperty("test-data.fileName");
234         String newId =
235             createFromXmlFile(testName, testDataDir + "/repfield_whitesp4.xml", false);
236         testSubmitRequest(newId);
237     }
238
239     /*
240      * Tests to diagnose and verify the fixed status of CSPACE-1248,
241      * "Wedged records created!" (i.e. records with child repeatable
242      * fields, which contain null values, can be successfully created
243      * but an error occurs on trying to retrieve those records).
244      */
245     /**
246      * Creates the with null value repeatable field.
247      *
248      * @param testName the test name
249      * @throws Exception the exception
250      */
251     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
252         dependsOnMethods = {"create", "testSubmitRequest"})
253     public void createWithNullValueRepeatableField(String testName) throws Exception {
254         String testDataDir = System.getProperty("test-data.fileName");
255         String newId =
256             createFromXmlFile(testName, testDataDir + "/repfield_null1.xml", false);
257         if (logger.isDebugEnabled()) {
258             logger.debug("Successfully created record with null value repeatable field.");
259             logger.debug("Attempting to retrieve just-created record ...");
260         }
261         testSubmitRequest(newId);
262     }
263
264     /* (non-Javadoc)
265      * @see org.collectionspace.services.client.test.ServiceTest#createList()
266      */
267     @Override
268     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
269     dependsOnMethods = {"create"})
270     public void createList(String testName) throws Exception {
271         for (int i = 0; i < DEFAULT_LIST_SIZE; i++) {
272             create(testName);
273         }
274     }
275
276     // Failure outcomes
277     // Placeholders until the three tests below can be uncommented.
278     // See Issue CSPACE-401.
279     /* (non-Javadoc)
280      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithEmptyEntityBody(java.lang.String)
281      */
282     @Override
283     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
284     public void createWithEmptyEntityBody(String testName) throws Exception {
285     }
286
287    /**
288     * Test how the service handles XML that is not well formed,
289     * when sent in the payload of a Create request.
290     *
291     * @param testName  The name of this test method.  This name is supplied
292     *     automatically, via reflection, by a TestNG 'data provider' in
293     *     a base class.
294     */
295     @Override
296     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
297     public void createWithMalformedXml(String testName) throws Exception {
298         setupCreate(testName);
299     }
300
301     /* (non-Javadoc)
302      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithWrongXmlSchema(java.lang.String)
303      */
304     @Override
305     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
306     public void createWithWrongXmlSchema(String testName) throws Exception {
307     }
308
309
310 /*
311     @Override
312     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
313     dependsOnMethods = {"create", "testSubmitRequest"})
314     public void createWithEmptyEntityBody(String testName) throwsException {
315
316     // Perform setup.
317     setupCreateWithEmptyEntityBody(testName);
318
319     // Submit the request to the service and store the response.
320     String method = REQUEST_TYPE.httpMethodName();
321     String url = getServiceRootURL();
322     String mediaType = MediaType.APPLICATION_XML;
323     final String entity = "";
324     int statusCode = submitRequest(method, url, mediaType, entity);
325
326     // Check the status code of the response: does it match
327     // the expected response(s)?
328     if(logger.isDebugEnabled()){
329     logger.debug(testName + ": url=" + url +
330     " status=" + statusCode);
331     }
332     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
333     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
334     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
335     }
336
337     @Override
338     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
339     dependsOnMethods = {"create", "testSubmitRequest"})
340     public void createWithMalformedXml(String testName) throws Exception {
341
342     // Perform setup.
343     setupCreateWithMalformedXml(testName);
344
345     // Submit the request to the service and store the response.
346     String method = REQUEST_TYPE.httpMethodName();
347     String url = getServiceRootURL();
348     String mediaType = MediaType.APPLICATION_XML;
349     final String entity = MALFORMED_XML_DATA; // Constant from base class.
350     int statusCode = submitRequest(method, url, mediaType, entity);
351
352     // Check the status code of the response: does it match
353     // the expected response(s)?
354     if(logger.isDebugEnabled()){
355     logger.debug(testName + ": url=" + url +
356     " status=" + statusCode);
357     }
358     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
359     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
360     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
361     }
362
363     @Override
364     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
365     dependsOnMethods = {"create", "testSubmitRequest"})
366     public void createWithWrongXmlSchema(String testName) throws Exception {
367
368     // Perform setup.
369     setupCreateWithWrongXmlSchema(testName);
370
371     // Submit the request to the service and store the response.
372     String method = REQUEST_TYPE.httpMethodName();
373     String url = getServiceRootURL();
374     String mediaType = MediaType.APPLICATION_XML;
375     final String entity = WRONG_XML_SCHEMA_DATA;
376     int statusCode = submitRequest(method, url, mediaType, entity);
377
378     // Check the status code of the response: does it match
379     // the expected response(s)?
380     if(logger.isDebugEnabled()){
381     logger.debug(testName + ": url=" + url +
382     " status=" + statusCode);
383     }
384     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
385     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
386     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
387     }
388 */
389
390    /**
391     * Test how the service handles, in a Create request, payloads
392     * containing null values (or, in the case of String fields,
393     * empty String values) in one or more fields which must be
394     * present and are required to contain non-empty values.
395     *
396     * This is a test of code and/or configuration in the service's
397     * validation routine(s).
398     *
399     * @param testName  The name of this test method.  This name is supplied
400     *     automatically, via reflection, by a TestNG 'data provider' in
401     *     a base class.
402     */
403     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
404     public void createWithRequiredValuesNullOrEmpty(String testName) throws Exception {
405         setupCreate(testName);
406
407         // Build a payload with invalid content, by omitting a
408         // field (objectNumber) which must be present, and in which
409         // a non-empty value is required, as enforced by the service's
410         // validation routine(s).
411         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
412         collectionObject.setTitle("atitle");
413         collectionObject.setObjectName("some name");
414
415         // Submit the request to the service and store the response.
416         CollectionObjectClient client = new CollectionObjectClient();
417         MultipartOutput multipart =
418                 createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
419         ClientResponse<Response> res = client.create(multipart);
420         int statusCode = res.getStatus();
421
422         // Read the response and verify that the create attempt failed.
423         if (logger.isDebugEnabled()) {
424             logger.debug(testName + ": status = " + statusCode);
425         }
426         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
427                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
428         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
429
430         // FIXME: Consider splitting off the following into its own test method.
431         
432         // Build a payload with invalid content, by setting a value to the
433         // empty String, in a field that requires a non-empty value,
434         // as enforced by the service's validation routine(s).
435         collectionObject = new CollectionobjectsCommon();
436         collectionObject.setTitle("atitle");
437         collectionObject.setObjectName("some name");
438         collectionObject.setObjectNumber("");
439
440         // Submit the request to the service and store the response.
441         multipart =
442             createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
443         res = client.create(multipart);
444         statusCode = res.getStatus();
445
446         // Read the response and verify that the create attempt failed.
447         if (logger.isDebugEnabled()) {
448             logger.debug(testName + ": status = " + statusCode);
449         }
450         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
451                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
452         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
453
454     }
455
456
457     // ---------------------------------------------------------------
458     // CRUD tests : READ tests
459     // ---------------------------------------------------------------
460     // Success outcomes
461     /* (non-Javadoc)
462      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String)
463      */
464     @Override
465     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
466     dependsOnMethods = {"create"})
467     public void read(String testName) throws Exception {
468
469         // Perform setup.
470         setupRead(testName);
471
472         // Submit the request to the service and store the response.
473         CollectionObjectClient client = new CollectionObjectClient();
474         ClientResponse<MultipartInput> res = client.read(knownResourceId);
475         int statusCode = res.getStatus();
476
477         // Check the status code of the response: does it match
478         // the expected response(s)?
479         if (logger.isDebugEnabled()) {
480             logger.debug(testName + ": status = " + statusCode);
481         }
482         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
483                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
484         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
485
486         MultipartInput input = (MultipartInput) res.getEntity();
487
488         if (logger.isDebugEnabled()) {
489             logger.debug(testName + ": Reading Common part ...");
490         }
491         CollectionobjectsCommon collectionObject =
492                 (CollectionobjectsCommon) extractPart(input,
493                 client.getCommonPartName(), CollectionobjectsCommon.class);
494         Assert.assertNotNull(collectionObject);
495
496         if (logger.isDebugEnabled()) {
497             logger.debug(testName + ": Reading Natural History part ...");
498         }
499         CollectionobjectsNaturalhistory conh =
500                 (CollectionobjectsNaturalhistory) extractPart(input,
501                 getNHPartName(), CollectionobjectsNaturalhistory.class);
502         Assert.assertNotNull(conh);
503     }
504
505     // Failure outcomes
506     /* (non-Javadoc)
507      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readNonExistent(java.lang.String)
508      */
509     @Override
510     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
511     dependsOnMethods = {"read"})
512     public void readNonExistent(String testName) throws Exception {
513
514         // Perform setup.
515         setupReadNonExistent(testName);
516
517         // Submit the request to the service and store the response.
518         CollectionObjectClient client = new CollectionObjectClient();
519         ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
520         int statusCode = res.getStatus();
521
522         // Check the status code of the response: does it match
523         // the expected response(s)?
524         if (logger.isDebugEnabled()) {
525             logger.debug(testName + ": status = " + statusCode);
526         }
527         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
528                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
529         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
530     }
531
532     
533     // ---------------------------------------------------------------
534     // CRUD tests : READ_LIST tests
535     // ---------------------------------------------------------------
536     // Success outcomes
537     /* (non-Javadoc)
538      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readList(java.lang.String)
539      */
540     @Override
541     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
542     dependsOnMethods = {"createList", "read"})
543     public void readList(String testName) throws Exception {
544
545         // Perform setup.
546         setupReadList(testName);
547
548         // Submit the request to the service and store the response.
549         CollectionObjectClient client = new CollectionObjectClient();
550         ClientResponse<CollectionobjectsCommonList> res = client.readList();
551         CollectionobjectsCommonList list = res.getEntity();
552         int statusCode = res.getStatus();
553
554         // Check the status code of the response: does it match
555         // the expected response(s)?
556         if (logger.isDebugEnabled()) {
557             logger.debug(testName + ": status = " + statusCode);
558         }
559         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
560                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
561         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
562
563         // Optionally output additional data about list members for debugging.
564         boolean iterateThroughList = false;
565         if (iterateThroughList && logger.isDebugEnabled()) {
566             List<CollectionobjectsCommonList.CollectionObjectListItem> items =
567                     list.getCollectionObjectListItem();
568             int i = 0;
569
570             for (CollectionobjectsCommonList.CollectionObjectListItem item : items) {
571                 logger.debug(testName + ": list-item[" + i + "] csid="
572                         + item.getCsid());
573                 logger.debug(testName + ": list-item[" + i + "] objectNumber="
574                         + item.getObjectNumber());
575                 logger.debug(testName + ": list-item[" + i + "] URI="
576                         + item.getUri());
577                 i++;
578
579             }
580         }
581     }
582
583     // Failure outcomes
584     // None at present.
585     // ---------------------------------------------------------------
586     // CRUD tests : UPDATE tests
587     // ---------------------------------------------------------------
588     // Success outcomes
589     /* (non-Javadoc)
590      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String)
591      */
592     @Override
593     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
594     dependsOnMethods = {"read"})
595     public void update(String testName) throws Exception {
596
597         // Perform setup.
598         setupUpdate(testName);
599
600         // Read an existing resource that will be updated.
601         ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
602
603         // Extract its common part.
604         CollectionObjectClient client = new CollectionObjectClient();
605         MultipartInput input = (MultipartInput) res.getEntity();
606         CollectionobjectsCommon collectionObject =
607                 (CollectionobjectsCommon) extractPart(input,
608                 client.getCommonPartName(), CollectionobjectsCommon.class);
609         Assert.assertNotNull(collectionObject);
610
611         // Change the content of one or more fields in the common part.
612         collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
613         collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
614         if (logger.isDebugEnabled()) {
615             logger.debug("sparse update that will be sent in update request:");
616             logger.debug(objectAsXmlString(collectionObject,
617                     CollectionobjectsCommon.class));
618         }
619
620         // Send the changed resource to be updated.
621         res = updateSend(testName, knownResourceId, collectionObject);
622         int statusCode = res.getStatus();
623         // Check the status code of the response: does it match the expected response(s)?
624         if (logger.isDebugEnabled()) {
625             logger.debug(testName + ": status = " + statusCode);
626         }
627         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
628                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
629         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
630
631         // Read the response and verify that the resource was correctly updated.
632         input = (MultipartInput) res.getEntity();
633         CollectionobjectsCommon updatedCollectionObject =
634                 (CollectionobjectsCommon) extractPart(input,
635                 client.getCommonPartName(), CollectionobjectsCommon.class);
636         Assert.assertNotNull(updatedCollectionObject);
637         Assert.assertEquals(updatedCollectionObject.getObjectName(),
638                 collectionObject.getObjectName(),
639                 "Data in updated object did not match submitted data.");
640
641     }
642
643     /**
644      * Update retrieve.
645      *
646      * @param testName the test name
647      * @param id the id
648      * @return the client response
649      */
650     private ClientResponse<MultipartInput> updateRetrieve(String testName, String id) {
651         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
652         CollectionObjectClient client = new CollectionObjectClient();
653         ClientResponse<MultipartInput> res = client.read(id);
654         if (logger.isDebugEnabled()) {
655             logger.debug("read in updateRetrieve for " + testName + " status = " + res.getStatus());
656         }
657         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS);
658         if (logger.isDebugEnabled()) {
659             logger.debug("got object to updateRetrieve for " + testName + " with ID: " + id);
660         }
661         return res;
662     }
663
664     /**
665      * Update send.
666      *
667      * @param testName the test name
668      * @param id the id
669      * @param collectionObject the collection object
670      * @return the client response
671      */
672     private ClientResponse<MultipartInput> updateSend(String testName, String id,
673             CollectionobjectsCommon collectionObject) {
674         MultipartOutput output = new MultipartOutput();
675         OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
676         CollectionObjectClient client = new CollectionObjectClient();
677         commonPart.getHeaders().add("label", client.getCommonPartName());
678         ClientResponse<MultipartInput> res = client.update(knownResourceId, output);
679         return res;
680     }
681
682     // Failure outcomes
683     // Placeholders until the three tests below can be uncommented.
684     // See Issue CSPACE-401.
685     /* (non-Javadoc)
686      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithEmptyEntityBody(java.lang.String)
687      */
688     @Override
689     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
690     dependsOnMethods = {"read"})
691     public void updateWithEmptyEntityBody(String testName) throws Exception {
692     }
693
694    /**
695     * Test how the service handles XML that is not well formed,
696     * when sent in the payload of an Update request.
697     *
698     * @param testName  The name of this test method.  This name is supplied
699     *     automatically, via reflection, by a TestNG 'data provider' in
700     *     a base class.
701     */
702     @Override
703     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
704     dependsOnMethods = {"read"})
705     public void updateWithMalformedXml(String testName) throws Exception {
706     }
707
708     /* (non-Javadoc)
709      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithWrongXmlSchema(java.lang.String)
710      */
711     @Override
712     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
713     dependsOnMethods = {"read"})
714     public void updateWithWrongXmlSchema(String testName) throws Exception {
715     }
716
717 /*
718     @Override
719     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
720     dependsOnMethods = {"create", "update", "testSubmitRequest"})
721     public void updateWithEmptyEntityBody(String testName) throws Exception {
722
723     // Perform setup.
724     setupUpdateWithEmptyEntityBody(testName);
725
726     // Submit the request to the service and store the response.
727     String method = REQUEST_TYPE.httpMethodName();
728     String url = getResourceURL(knownResourceId);
729     String mediaType = MediaType.APPLICATION_XML;
730     final String entity = "";
731     int statusCode = submitRequest(method, url, mediaType, entity);
732
733     // Check the status code of the response: does it match
734     // the expected response(s)?
735     if(logger.isDebugEnabled()){
736     logger.debug(testName + ": url=" + url +
737     " status=" + statusCode);
738     }
739     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
740     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
741     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
742     }
743
744     @Override
745     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
746     dependsOnMethods = {"create", "update", "testSubmitRequest"})
747     public void updateWithMalformedXml() throws Exception {
748
749     // Perform setup.
750     setupUpdateWithMalformedXml(testName);
751
752     // Submit the request to the service and store the response.
753     String method = REQUEST_TYPE.httpMethodName();
754     String url = getResourceURL(knownResourceId);
755     final String entity = MALFORMED_XML_DATA;
756     String mediaType = MediaType.APPLICATION_XML;
757     int statusCode = submitRequest(method, url, mediaType, entity);
758
759     // Check the status code of the response: does it match
760     // the expected response(s)?
761     if(logger.isDebugEnabled()){
762     logger.debug(testName + ": url=" + url +
763     " status=" + statusCode);
764     }
765     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
766     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
767     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
768     }
769
770     @Override
771     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
772     dependsOnMethods = {"create", "update", "testSubmitRequest"})
773     public void updateWithWrongXmlSchema(String testName) throws Exception {
774
775     // Perform setup.
776     setupUpdateWithWrongXmlSchema(String testName);
777
778     // Submit the request to the service and store the response.
779     String method = REQUEST_TYPE.httpMethodName();
780     String url = getResourceURL(knownResourceId);
781     String mediaType = MediaType.APPLICATION_XML;
782     final String entity = WRONG_XML_SCHEMA_DATA;
783     int statusCode = submitRequest(method, url, mediaType, entity);
784
785     // Check the status code of the response: does it match
786     // the expected response(s)?
787     if(logger.isDebugEnabled()){
788     logger.debug(testName + ": url=" + url +
789     " status=" + statusCode);
790     }
791     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
792     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
793     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
794     }
795 */
796
797     /* (non-Javadoc)
798  * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateNonExistent(java.lang.String)
799  */
800 @Override
801     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
802     dependsOnMethods = {"update", "testSubmitRequest"})
803     public void updateNonExistent(String testName) throws Exception {
804
805         // Perform setup.
806         setupUpdateNonExistent(testName);
807
808         // Submit the request to the service and store the response.
809         //
810         // Note: The ID used in this 'create' call may be arbitrary.
811         // The only relevant ID may be the one used in updateCollectionObject(), below.
812         CollectionObjectClient client = new CollectionObjectClient();
813         MultipartOutput multipart =
814                 createCollectionObjectInstance(client.getCommonPartName(),
815                 NON_EXISTENT_ID);
816         ClientResponse<MultipartInput> res =
817                 client.update(NON_EXISTENT_ID, multipart);
818         int statusCode = res.getStatus();
819
820         // Check the status code of the response: does it match
821         // the expected response(s)?
822         if (logger.isDebugEnabled()) {
823             logger.debug(testName + ": status = " + statusCode);
824         }
825         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
826                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
827         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
828     }
829
830    /**
831     * Test how the service handles, in an Update request, payloads
832     * containing null values (or, in the case of String fields,
833     * empty String values) in one or more fields in which non-empty
834     * values are required.
835     *
836     * This is a test of code and/or configuration in the service's
837     * validation routine(s).
838     *
839     * @param testName  The name of this test method.  This name is supplied
840     *     automatically, via reflection, by a TestNG 'data provider' in
841     *     a base class.
842     */
843     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
844     dependsOnMethods = {"read"})
845     public void updateWithRequiredValuesNullOrEmpty(String testName) throws Exception {
846         // Perform setup.
847         setupUpdate(testName);
848         if (logger.isDebugEnabled()) {
849             logger.debug(testName + " got object to update with ID: " + knownResourceId);
850         }
851
852         // Read an existing record for updating.
853         ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
854
855         CollectionObjectClient client = new CollectionObjectClient();
856         MultipartInput input = (MultipartInput) res.getEntity();
857         CollectionobjectsCommon collectionObject =
858                 (CollectionobjectsCommon) extractPart(input,
859                 client.getCommonPartName(), CollectionobjectsCommon.class);
860         Assert.assertNotNull(collectionObject);
861
862         // Update with invalid content, by setting a value to the
863         // empty String, in a field that requires a non-empty value,
864         // as enforced by the service's validation routine(s).
865         collectionObject.setObjectNumber("");
866
867         if (logger.isDebugEnabled()) {
868             logger.debug(testName + " updated object");
869             logger.debug(objectAsXmlString(collectionObject,
870                     CollectionobjectsCommon.class));
871         }
872
873         // Submit the request to the service and store the response.
874         res = updateSend(testName, knownResourceId, collectionObject);
875         int statusCode = res.getStatus();
876
877         // Read the response and verify that the update attempt failed.
878         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
879                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
880         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
881
882     }
883
884     // ---------------------------------------------------------------
885     // CRUD tests : DELETE tests
886     // ---------------------------------------------------------------
887     // Success outcomes
888     /* (non-Javadoc)
889      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String)
890      */
891     @Override
892     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
893     dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
894     public void delete(String testName) throws Exception {
895
896         // Perform setup.
897         setupDelete(testName);
898
899         // Submit the request to the service and store the response.
900         CollectionObjectClient client = new CollectionObjectClient();
901         ClientResponse<Response> res = client.delete(knownResourceId);
902         int statusCode = res.getStatus();
903
904         // Check the status code of the response: does it match
905         // the expected response(s)?
906         if (logger.isDebugEnabled()) {
907             logger.debug(testName + ": status = " + statusCode);
908         }
909         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
910                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
911         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
912     }
913
914     // Failure outcomes
915     /* (non-Javadoc)
916      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String)
917      */
918     @Override
919     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
920     dependsOnMethods = {"delete"})
921     public void deleteNonExistent(String testName) throws Exception {
922
923         // Perform setup.
924         setupDeleteNonExistent(testName);
925
926         // Submit the request to the service and store the response.
927         CollectionObjectClient client = new CollectionObjectClient();
928         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
929         int statusCode = res.getStatus();
930
931         // Check the status code of the response: does it match
932         // the expected response(s)?
933         if (logger.isDebugEnabled()) {
934             logger.debug(testName + ": status = " + statusCode);
935         }
936         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
937                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
938         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
939     }
940
941     // ---------------------------------------------------------------
942     // Utility tests : tests of code used in tests above
943     // ---------------------------------------------------------------
944     /**
945      * Tests the code for manually submitting data that is used by several
946      * of the methods above.
947      */
948
949     @Test(dependsOnMethods = {"create", "read"})
950     public void testSubmitRequest() throws Exception {
951         testSubmitRequest(knownResourceId);
952     }
953
954     /**
955      * Test submit request.
956      *
957      * @param resourceId the resource id
958      * @throws Exception the exception
959      */
960     private void testSubmitRequest(String resourceId) throws Exception {
961
962         // Expected status code: 200 OK
963         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
964
965         // Submit the request to the service and store the response.
966         String method = ServiceRequestType.READ.httpMethodName();
967         String url = getResourceURL(resourceId);
968         int statusCode = submitRequest(method, url);
969
970         // Check the status code of the response: does it match
971         // the expected response(s)?
972         if (logger.isDebugEnabled()) {
973             logger.debug("testSubmitRequest: url=" + url
974                     + " status=" + statusCode);
975         }
976         Assert.assertEquals(statusCode, EXPECTED_STATUS);
977
978     }
979
980     // ---------------------------------------------------------------
981     // Cleanup of resources created during testing
982     // ---------------------------------------------------------------
983     /**
984      * Deletes all resources created by tests, after all tests have been run.
985      *
986      * This cleanup method will always be run, even if one or more tests fail.
987      * For this reason, it attempts to remove all resources created
988      * at any point during testing, even if some of those resources
989      * may be expected to be deleted by certain tests.
990      */
991     @AfterClass(alwaysRun = true)
992     public void cleanUp() {
993         String noTest = System.getProperty("noTestCleanup");
994         if(Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
995             if (logger.isDebugEnabled()) {
996                 logger.debug("Skipping Cleanup phase ...");
997             }
998             return;
999         }
1000         if (logger.isDebugEnabled()) {
1001             logger.debug("Cleaning up temporary resources created for testing ...");
1002         }
1003        CollectionObjectClient client = new CollectionObjectClient();
1004        for (String resourceId : allResourceIdsCreated) {
1005             // Note: Any non-success responses are ignored and not reported.
1006             ClientResponse<Response> res = client.delete(resourceId);
1007         }
1008     }
1009
1010     // ---------------------------------------------------------------
1011     // Utility methods used by tests above
1012     // ---------------------------------------------------------------
1013     /**
1014      * Creates the collection object instance.
1015      *
1016      * @param commonPartName the common part name
1017      * @param identifier the identifier
1018      * @return the multipart output
1019      */
1020     private MultipartOutput createCollectionObjectInstance(String commonPartName,
1021             String identifier) {
1022         return createCollectionObjectInstance(commonPartName,
1023                 "objectNumber-" + identifier,
1024                 "objectName-" + identifier);
1025     }
1026
1027     /**
1028      * Creates the collection object instance.
1029      *
1030      * @param commonPartName the common part name
1031      * @param objectNumber the object number
1032      * @param objectName the object name
1033      * @return the multipart output
1034      */
1035     private MultipartOutput createCollectionObjectInstance(String commonPartName,
1036             String objectNumber, String objectName) {
1037         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
1038         ResponsibleDepartmentList deptList = new ResponsibleDepartmentList();
1039         List<String> depts = deptList.getResponsibleDepartment();
1040         // @TODO Use properly formatted refNames for representative departments
1041         // in this example test record. The following are mere placeholders.
1042         depts.add("urn:org.collectionspace.services.department:Registrar");
1043         if (multivalue) {
1044             depts.add("urn:org.walkerart.department:Fine Art");
1045         }
1046         multivalue = !multivalue;
1047         //FIXME: Title does not need to be set.
1048         collectionObject.setTitle("atitle");
1049         collectionObject.setResponsibleDepartments(deptList);
1050         collectionObject.setObjectNumber(objectNumber);
1051         collectionObject.setOtherNumber("urn:org.walkerart.id:123");
1052         collectionObject.setObjectName(objectName);
1053         collectionObject.setAge(""); //test for null string
1054         collectionObject.setBriefDescription("Papier mache bird cow mask with horns, "
1055                 + "painted red with black and yellow spots. "
1056                 + "Puerto Rico. ca. 8&quot; high, 6&quot; wide, projects 10&quot; (with horns).");
1057
1058         CollectionobjectsNaturalhistory conh = new CollectionobjectsNaturalhistory();
1059         conh.setNhString("test-string");
1060         conh.setNhInt(999);
1061         conh.setNhLong(9999);
1062
1063
1064         MultipartOutput multipart = createCollectionObjectInstance(commonPartName, collectionObject, conh);
1065         return multipart;
1066     }
1067
1068     /**
1069      * Creates the collection object instance.
1070      *
1071      * @param commonPartName the common part name
1072      * @param collectionObject the collection object
1073      * @param conh the conh
1074      * @return the multipart output
1075      */
1076     private MultipartOutput createCollectionObjectInstance(String commonPartName,
1077             CollectionobjectsCommon collectionObject, CollectionobjectsNaturalhistory conh) {
1078
1079         MultipartOutput multipart = new MultipartOutput();
1080         OutputPart commonPart = multipart.addPart(collectionObject,
1081                 MediaType.APPLICATION_XML_TYPE);
1082         commonPart.getHeaders().add("label", commonPartName);
1083
1084         if (logger.isDebugEnabled()) {
1085             logger.debug("to be created, collectionobject common");
1086             logger.debug(objectAsXmlString(collectionObject,
1087                     CollectionobjectsCommon.class));
1088         }
1089
1090         if (conh != null) {
1091             OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
1092             nhPart.getHeaders().add("label", getNHPartName());
1093
1094             if (logger.isDebugEnabled()) {
1095                 logger.debug("to be created, collectionobject nhistory");
1096                 logger.debug(objectAsXmlString(conh,
1097                         CollectionobjectsNaturalhistory.class));
1098             }
1099         }
1100         return multipart;
1101
1102     }
1103
1104     /**
1105      * createCollectionObjectInstanceFromXml uses JAXB unmarshaller to retrieve
1106      * collectionobject from given file
1107      * @param commonPartName
1108      * @param commonPartFileName
1109      * @return
1110      * @throws Exception
1111      */
1112     private MultipartOutput createCollectionObjectInstanceFromXml(String testName, String commonPartName,
1113             String commonPartFileName) throws Exception {
1114
1115         CollectionobjectsCommon collectionObject =
1116                 (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class,
1117                 commonPartFileName);
1118         MultipartOutput multipart = new MultipartOutput();
1119         OutputPart commonPart = multipart.addPart(collectionObject,
1120                 MediaType.APPLICATION_XML_TYPE);
1121         commonPart.getHeaders().add("label", commonPartName);
1122
1123         if (logger.isDebugEnabled()) {
1124             logger.debug(testName + " to be created, collectionobject common");
1125             logger.debug(objectAsXmlString(collectionObject,
1126                     CollectionobjectsCommon.class));
1127         }
1128         return multipart;
1129
1130     }
1131
1132     /**
1133      * createCollectionObjectInstanceFromRawXml uses stringified collectionobject
1134      * retrieve from given file
1135      * @param commonPartName
1136      * @param commonPartFileName
1137      * @return
1138      * @throws Exception
1139      */
1140     private MultipartOutput createCollectionObjectInstanceFromRawXml(String testName, String commonPartName,
1141             String commonPartFileName) throws Exception {
1142
1143         MultipartOutput multipart = new MultipartOutput();
1144         String stringObject = getXmlDocumentAsString(commonPartFileName);
1145         if (logger.isDebugEnabled()) {
1146             logger.debug(testName + " to be created, collectionobject common " + "\n" + stringObject);
1147         }
1148         OutputPart commonPart = multipart.addPart(stringObject,
1149                 MediaType.APPLICATION_XML_TYPE);
1150         commonPart.getHeaders().add("label", commonPartName);
1151
1152         return multipart;
1153
1154     }
1155
1156     /**
1157      * Gets the nH part name.
1158      *
1159      * @return the nH part name
1160      */
1161     private String getNHPartName() {
1162         return "collectionobjects_naturalhistory";
1163     }
1164
1165     /**
1166      * Creates the from xml file.
1167      *
1168      * @param testName the test name
1169      * @param fileName the file name
1170      * @param useJaxb the use jaxb
1171      * @return the string
1172      * @throws Exception the exception
1173      */
1174     private String createFromXmlFile(String testName, String fileName, boolean useJaxb) throws Exception {
1175         // Perform setup, such as initializing the type of service request
1176         // (e.g. CREATE, DELETE), its valid and expected status codes, and
1177         // its associated HTTP method name (e.g. POST, DELETE).
1178         setupCreate(testName);
1179
1180         MultipartOutput multipart = null;
1181
1182         CollectionObjectClient client = new CollectionObjectClient();
1183         if (useJaxb) {
1184             multipart = createCollectionObjectInstanceFromXml(testName,
1185                     client.getCommonPartName(), fileName);
1186         } else {
1187             multipart = createCollectionObjectInstanceFromRawXml(testName,
1188                     client.getCommonPartName(), fileName);
1189         }
1190         ClientResponse<Response> res = client.create(multipart);
1191         int statusCode = res.getStatus();
1192
1193         if (logger.isDebugEnabled()) {
1194             logger.debug(testName + ": status = " + statusCode);
1195         }
1196         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1197                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1198         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1199         String newId = extractId(res);
1200         allResourceIdsCreated.add(newId);
1201         return newId;
1202     }
1203 }