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