]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
1b29dc3400c9439783abedc3783fb4a1bf3b47b2
[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 CollectionObjectClient client = new CollectionObjectClient();
60     private String knownResourceId = null;
61     private List<String> allResourceIdsCreated = new ArrayList();
62     private boolean multivalue; //toggle
63
64     /*
65      * This method is called only by the parent class, AbstractServiceTest
66      */
67     @Override
68     protected String getServicePathComponent() {
69         return client.getServicePathComponent();
70     }
71
72     // ---------------------------------------------------------------
73     // CRUD tests : CREATE tests
74     // ---------------------------------------------------------------
75     // Success outcomes
76     @Override
77     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
78     public void create(String testName) throws Exception {
79
80         // Perform setup, such as initializing the type of service request
81         // (e.g. CREATE, DELETE), its valid and expected status codes, and
82         // its associated HTTP method name (e.g. POST, DELETE).
83         setupCreate(testName);
84
85         // Submit the request to the service and store the response.
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 newId =
136             createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp1.xml", false);
137         testSubmitRequest(newId);
138     }
139
140     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
141         dependsOnMethods = {"create", "testSubmitRequest"})
142     public void createFromXmlRFWS2(String testName) throws Exception {
143         String newId =
144             createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp2.xml", false);
145         testSubmitRequest(newId);
146     }
147
148     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
149         dependsOnMethods = {"create", "testSubmitRequest"})
150     public void createFromXmlRFWS3(String testName) throws Exception {
151         String newId =
152             createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp3.xml", false);
153         testSubmitRequest(newId);
154     }
155
156     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
157         dependsOnMethods = {"create", "testSubmitRequest"})
158     public void createFromXmlRFWS4(String testName) throws Exception {
159         String newId =
160             createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp4.xml", false);
161         testSubmitRequest(newId);
162     }
163
164     /*
165      * Tests to diagnose and verify the fixed status of CSPACE-1248,
166      * "Wedged records created!" (i.e. records with child repeatable
167      * fields, which contain null values, can be successfully created
168      * but an error occurs on trying to retrieve those records).
169      */
170     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
171         dependsOnMethods = {"create", "testSubmitRequest"})
172     public void createWithNullValueRepeatableField(String testName) throws Exception {
173         String newId =
174             createFromXmlFile(testName, "./target/test-classes/test-data/repfield_null1.xml", false);
175         if (logger.isDebugEnabled()) {
176             logger.debug("Successfully created record with null value repeatable field.");
177             logger.debug("Attempting to retrieve just-created record ...");
178         }
179         testSubmitRequest(newId);
180     }
181
182     /* (non-Javadoc)
183      * @see org.collectionspace.services.client.test.ServiceTest#createList()
184      */
185     @Override
186     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
187     dependsOnMethods = {"create"})
188     public void createList(String testName) throws Exception {
189         for (int i = 0; i < 3; i++) {
190             create(testName);
191         }
192     }
193
194     // Failure outcomes
195     // Placeholders until the three tests below can be uncommented.
196     // See Issue CSPACE-401.
197     @Override
198     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
199     public void createWithEmptyEntityBody(String testName) throws Exception {
200     }
201
202     @Override
203     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
204     public void createWithMalformedXml(String testName) throws Exception {
205         setupCreate(testName);
206
207         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
208         collectionObject.setTitle("atitle");
209         //don't set objectNumber to check validation
210         collectionObject.setObjectName("some name");
211         MultipartOutput multipart =
212                 createCollectionObjectInstance(client.getCommonPartName(), collectionObject, null);
213         ClientResponse<Response> res = client.create(multipart);
214         int statusCode = res.getStatus();
215
216         if (logger.isDebugEnabled()) {
217             logger.debug(testName + ": status = " + statusCode);
218         }
219         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
220                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
221         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
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     // CRUD tests : READ tests
311     // ---------------------------------------------------------------
312     // Success outcomes
313     @Override
314     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
315     dependsOnMethods = {"create"})
316     public void read(String testName) throws Exception {
317
318         // Perform setup.
319         setupRead(testName);
320
321         // Submit the request to the service and store the response.
322         ClientResponse<MultipartInput> res = client.read(knownResourceId);
323         int statusCode = res.getStatus();
324
325         // Check the status code of the response: does it match
326         // the expected response(s)?
327         if (logger.isDebugEnabled()) {
328             logger.debug(testName + ": status = " + statusCode);
329         }
330         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
331                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
332         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
333
334         MultipartInput input = (MultipartInput) res.getEntity();
335
336         if (logger.isDebugEnabled()) {
337             logger.debug(testName + ": Reading Common part ...");
338         }
339         CollectionobjectsCommon collectionObject =
340                 (CollectionobjectsCommon) extractPart(input,
341                 client.getCommonPartName(), CollectionobjectsCommon.class);
342         Assert.assertNotNull(collectionObject);
343
344         if (logger.isDebugEnabled()) {
345             logger.debug(testName + ": Reading Natural History part ...");
346         }
347         CollectionobjectsNaturalhistory conh =
348                 (CollectionobjectsNaturalhistory) extractPart(input,
349                 getNHPartName(), CollectionobjectsNaturalhistory.class);
350         Assert.assertNotNull(conh);
351     }
352
353     // Failure outcomes
354     @Override
355     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
356     dependsOnMethods = {"read"})
357     public void readNonExistent(String testName) throws Exception {
358
359         // Perform setup.
360         setupReadNonExistent(testName);
361
362         // Submit the request to the service and store the response.
363         ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
364         int statusCode = res.getStatus();
365
366         // Check the status code of the response: does it match
367         // the expected response(s)?
368         if (logger.isDebugEnabled()) {
369             logger.debug(testName + ": status = " + statusCode);
370         }
371         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
372                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
373         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
374     }
375
376     // ---------------------------------------------------------------
377     // CRUD tests : READ_LIST tests
378     // ---------------------------------------------------------------
379     // Success outcomes
380     @Override
381     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
382     dependsOnMethods = {"createList", "read"})
383     public void readList(String testName) throws Exception {
384
385         // Perform setup.
386         setupReadList(testName);
387
388         // Submit the request to the service and store the response.
389         ClientResponse<CollectionobjectsCommonList> res = client.readList();
390         CollectionobjectsCommonList list = res.getEntity();
391         int statusCode = res.getStatus();
392
393         // Check the status code of the response: does it match
394         // the expected response(s)?
395         if (logger.isDebugEnabled()) {
396             logger.debug(testName + ": status = " + statusCode);
397         }
398         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
399                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
400         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
401
402         // Optionally output additional data about list members for debugging.
403         boolean iterateThroughList = false;
404         if (iterateThroughList && logger.isDebugEnabled()) {
405             List<CollectionobjectsCommonList.CollectionObjectListItem> items =
406                     list.getCollectionObjectListItem();
407             int i = 0;
408
409             for (CollectionobjectsCommonList.CollectionObjectListItem item : items) {
410                 logger.debug(testName + ": list-item[" + i + "] csid="
411                         + item.getCsid());
412                 logger.debug(testName + ": list-item[" + i + "] objectNumber="
413                         + item.getObjectNumber());
414                 logger.debug(testName + ": list-item[" + i + "] URI="
415                         + item.getUri());
416                 i++;
417
418             }
419         }
420     }
421
422     // Failure outcomes
423     // None at present.
424     // ---------------------------------------------------------------
425     // CRUD tests : UPDATE tests
426     // ---------------------------------------------------------------
427     // Success outcomes
428     @Override
429     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
430     dependsOnMethods = {"read"})
431     public void update(String testName) throws Exception {
432
433         // Perform setup.
434         setupUpdate(testName);
435
436         // Read an existing resource that will be updated.
437         ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
438
439         // Extract its common part.
440         MultipartInput input = (MultipartInput) res.getEntity();
441         CollectionobjectsCommon collectionObject =
442                 (CollectionobjectsCommon) extractPart(input,
443                 client.getCommonPartName(), CollectionobjectsCommon.class);
444         Assert.assertNotNull(collectionObject);
445
446         // Change the content of one or more fields in the common part.
447         collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
448         collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
449         if (logger.isDebugEnabled()) {
450             logger.debug("sparse update that will be sent in update request:");
451             logger.debug(objectAsXmlString(collectionObject,
452                     CollectionobjectsCommon.class));
453         }
454
455         // Send the changed resource to be updated.
456         res = updateSend(testName, knownResourceId, collectionObject);
457         int statusCode = res.getStatus();
458         // Check the status code of the response: does it match the expected response(s)?
459         if (logger.isDebugEnabled()) {
460             logger.debug(testName + ": status = " + statusCode);
461         }
462         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
463                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
464         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
465
466         // Read the response and verify that the resource was correctly updated.
467         input = (MultipartInput) res.getEntity();
468         CollectionobjectsCommon updatedCollectionObject =
469                 (CollectionobjectsCommon) extractPart(input,
470                 client.getCommonPartName(), CollectionobjectsCommon.class);
471         Assert.assertNotNull(updatedCollectionObject);
472         Assert.assertEquals(updatedCollectionObject.getObjectName(),
473                 collectionObject.getObjectName(),
474                 "Data in updated object did not match submitted data.");
475
476     }
477
478     private ClientResponse<MultipartInput> updateRetrieve(String testName, String id) {
479         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
480         ClientResponse<MultipartInput> res = client.read(id);
481         if (logger.isDebugEnabled()) {
482             logger.debug("read in updateRetrieve for " + testName + " status = " + res.getStatus());
483         }
484         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS);
485         if (logger.isDebugEnabled()) {
486             logger.debug("got object to updateRetrieve for " + testName + " with ID: " + id);
487         }
488         return res;
489     }
490
491     private ClientResponse<MultipartInput> updateSend(String testName, String id,
492             CollectionobjectsCommon collectionObject) {
493         MultipartOutput output = new MultipartOutput();
494         OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
495         commonPart.getHeaders().add("label", client.getCommonPartName());
496         ClientResponse<MultipartInput> res = client.update(knownResourceId, output);
497         return res;
498     }
499
500     // Failure outcomes
501     // Placeholders until the three tests below can be uncommented.
502     // See Issue CSPACE-401.
503     @Override
504     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
505     dependsOnMethods = {"read"})
506     public void updateWithEmptyEntityBody(String testName) throws Exception {
507     }
508
509     @Override
510     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
511     dependsOnMethods = {"read"})
512     public void updateWithMalformedXml(String testName) throws Exception {
513         // Perform setup.
514         setupUpdate(testName);
515         if (logger.isDebugEnabled()) {
516             logger.debug(testName + " got object to update with ID: " + knownResourceId);
517         }
518
519         // Read an existing record for updating
520         ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
521
522         MultipartInput input = (MultipartInput) res.getEntity();
523         CollectionobjectsCommon collectionObject =
524                 (CollectionobjectsCommon) extractPart(input,
525                 client.getCommonPartName(), CollectionobjectsCommon.class);
526         Assert.assertNotNull(collectionObject);
527
528         //update with invalid content
529         collectionObject.setObjectNumber("");
530
531         if (logger.isDebugEnabled()) {
532             logger.debug(testName + " updated object");
533             logger.debug(objectAsXmlString(collectionObject,
534                     CollectionobjectsCommon.class));
535         }
536
537         // Submit the request to the service and store the response.
538         res = updateSend(testName, knownResourceId, collectionObject);
539         int statusCode = res.getStatus();
540         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
541                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
542         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
543
544     }
545
546     @Override
547     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
548     dependsOnMethods = {"read"})
549     public void updateWithWrongXmlSchema(String testName) throws Exception {
550     }
551
552     /*
553     @Override
554     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
555     dependsOnMethods = {"create", "update", "testSubmitRequest"})
556     public void updateWithEmptyEntityBody(String testName) throws Exception {
557
558     // Perform setup.
559     setupUpdateWithEmptyEntityBody(testName);
560
561     // Submit the request to the service and store the response.
562     String method = REQUEST_TYPE.httpMethodName();
563     String url = getResourceURL(knownResourceId);
564     String mediaType = MediaType.APPLICATION_XML;
565     final String entity = "";
566     int statusCode = submitRequest(method, url, mediaType, entity);
567
568     // Check the status code of the response: does it match
569     // the expected response(s)?
570     if(logger.isDebugEnabled()){
571     logger.debug(testName + ": url=" + url +
572     " status=" + statusCode);
573     }
574     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
575     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
576     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
577     }
578
579     @Override
580     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
581     dependsOnMethods = {"create", "update", "testSubmitRequest"})
582     public void updateWithMalformedXml() throws Exception {
583
584     // Perform setup.
585     setupUpdateWithMalformedXml(testName);
586
587     // Submit the request to the service and store the response.
588     String method = REQUEST_TYPE.httpMethodName();
589     String url = getResourceURL(knownResourceId);
590     final String entity = MALFORMED_XML_DATA;
591     String mediaType = MediaType.APPLICATION_XML;
592     int statusCode = submitRequest(method, url, mediaType, entity);
593
594     // Check the status code of the response: does it match
595     // the expected response(s)?
596     if(logger.isDebugEnabled()){
597     logger.debug(testName + ": url=" + url +
598     " status=" + statusCode);
599     }
600     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
601     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
602     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
603     }
604
605     @Override
606     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
607     dependsOnMethods = {"create", "update", "testSubmitRequest"})
608     public void updateWithWrongXmlSchema(String testName) throws Exception {
609
610     // Perform setup.
611     setupUpdateWithWrongXmlSchema(String testName);
612
613     // Submit the request to the service and store the response.
614     String method = REQUEST_TYPE.httpMethodName();
615     String url = getResourceURL(knownResourceId);
616     String mediaType = MediaType.APPLICATION_XML;
617     final String entity = WRONG_XML_SCHEMA_DATA;
618     int statusCode = submitRequest(method, url, mediaType, entity);
619
620     // Check the status code of the response: does it match
621     // the expected response(s)?
622     if(logger.isDebugEnabled()){
623     logger.debug(testName + ": url=" + url +
624     " status=" + statusCode);
625     }
626     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
627     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
628     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
629     }
630      */
631     @Override
632     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
633     dependsOnMethods = {"update", "testSubmitRequest"})
634     public void updateNonExistent(String testName) throws Exception {
635
636         // Perform setup.
637         setupUpdateNonExistent(testName);
638
639         // Submit the request to the service and store the response.
640         //
641         // Note: The ID used in this 'create' call may be arbitrary.
642         // The only relevant ID may be the one used in updateCollectionObject(), below.
643         MultipartOutput multipart =
644                 createCollectionObjectInstance(client.getCommonPartName(),
645                 NON_EXISTENT_ID);
646         ClientResponse<MultipartInput> res =
647                 client.update(NON_EXISTENT_ID, multipart);
648         int statusCode = res.getStatus();
649
650         // Check the status code of the response: does it match
651         // the expected response(s)?
652         if (logger.isDebugEnabled()) {
653             logger.debug(testName + ": status = " + statusCode);
654         }
655         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
656                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
657         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
658     }
659
660     // ---------------------------------------------------------------
661     // CRUD tests : DELETE tests
662     // ---------------------------------------------------------------
663     // Success outcomes
664     @Override
665     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
666     dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
667     public void delete(String testName) throws Exception {
668
669         // Perform setup.
670         setupDelete(testName);
671
672         // Submit the request to the service and store the response.
673         ClientResponse<Response> res = client.delete(knownResourceId);
674         int statusCode = res.getStatus();
675
676         // Check the status code of the response: does it match
677         // the expected response(s)?
678         if (logger.isDebugEnabled()) {
679             logger.debug(testName + ": status = " + statusCode);
680         }
681         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
682                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
683         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
684     }
685
686     // Failure outcomes
687     @Override
688     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
689     dependsOnMethods = {"delete"})
690     public void deleteNonExistent(String testName) throws Exception {
691
692         // Perform setup.
693         setupDeleteNonExistent(testName);
694
695         // Submit the request to the service and store the response.
696         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
697         int statusCode = res.getStatus();
698
699         // Check the status code of the response: does it match
700         // the expected response(s)?
701         if (logger.isDebugEnabled()) {
702             logger.debug(testName + ": status = " + statusCode);
703         }
704         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
705                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
706         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
707     }
708
709     // ---------------------------------------------------------------
710     // Utility tests : tests of code used in tests above
711     // ---------------------------------------------------------------
712     /**
713      * Tests the code for manually submitting data that is used by several
714      * of the methods above.
715      */
716
717     @Test(dependsOnMethods = {"create", "read"})
718     public void testSubmitRequest() throws Exception {
719         testSubmitRequest(knownResourceId);
720     }
721
722     private void testSubmitRequest(String resourceId) throws Exception {
723
724         // Expected status code: 200 OK
725         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
726
727         // Submit the request to the service and store the response.
728         String method = ServiceRequestType.READ.httpMethodName();
729         String url = getResourceURL(resourceId);
730         int statusCode = submitRequest(method, url);
731
732         // Check the status code of the response: does it match
733         // the expected response(s)?
734         if (logger.isDebugEnabled()) {
735             logger.debug("testSubmitRequest: url=" + url
736                     + " status=" + statusCode);
737         }
738         Assert.assertEquals(statusCode, EXPECTED_STATUS);
739
740     }
741
742     // ---------------------------------------------------------------
743     // Cleanup of resources created during testing
744     // ---------------------------------------------------------------
745     /**
746      * Deletes all resources created by tests, after all tests have been run.
747      *
748      * This cleanup method will always be run, even if one or more tests fail.
749      * For this reason, it attempts to remove all resources created
750      * at any point during testing, even if some of those resources
751      * may be expected to be deleted by certain tests.
752      */
753     @AfterClass(alwaysRun = true)
754     public void cleanUp() {
755         if (logger.isDebugEnabled()) {
756             logger.debug("Cleaning up temporary resources created for testing ...");
757         }
758         for (String resourceId : allResourceIdsCreated) {
759             // Note: Any non-success responses are ignored and not reported.
760             ClientResponse<Response> res = client.delete(resourceId);
761         }
762     }
763
764     // ---------------------------------------------------------------
765     // Utility methods used by tests above
766     // ---------------------------------------------------------------
767     private MultipartOutput createCollectionObjectInstance(String commonPartName,
768             String identifier) {
769         return createCollectionObjectInstance(commonPartName,
770                 "objectNumber-" + identifier,
771                 "objectName-" + identifier);
772     }
773
774     private MultipartOutput createCollectionObjectInstance(String commonPartName,
775             String objectNumber, String objectName) {
776         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
777         ResponsibleDepartmentList deptList = new ResponsibleDepartmentList();
778         List<String> depts = deptList.getResponsibleDepartment();
779         // @TODO Use properly formatted refNames for representative departments
780         // in this example test record. The following are mere placeholders.
781         depts.add("urn:org.collectionspace.services.department:Registrar");
782         if (multivalue) {
783             depts.add("urn:org.walkerart.department:Fine Art");
784         }
785         multivalue = !multivalue;
786         //FIXME: Title does not need to be set.
787         collectionObject.setTitle("atitle");
788         collectionObject.setResponsibleDepartments(deptList);
789         collectionObject.setObjectNumber(objectNumber);
790         collectionObject.setOtherNumber("urn:org.walkerart.id:123");
791         collectionObject.setObjectName(objectName);
792         collectionObject.setAge(""); //test for null string
793         collectionObject.setBriefDescription("Papier mache bird cow mask with horns, "
794                 + "painted red with black and yellow spots. "
795                 + "Puerto Rico. ca. 8&quot; high, 6&quot; wide, projects 10&quot; (with horns).");
796
797         CollectionobjectsNaturalhistory conh = new CollectionobjectsNaturalhistory();
798         conh.setNhString("test-string");
799         conh.setNhInt(999);
800         conh.setNhLong(9999);
801
802
803         MultipartOutput multipart = createCollectionObjectInstance(commonPartName, collectionObject, conh);
804         return multipart;
805     }
806
807     private MultipartOutput createCollectionObjectInstance(String commonPartName,
808             CollectionobjectsCommon collectionObject, CollectionobjectsNaturalhistory conh) {
809
810         MultipartOutput multipart = new MultipartOutput();
811         OutputPart commonPart = multipart.addPart(collectionObject,
812                 MediaType.APPLICATION_XML_TYPE);
813         commonPart.getHeaders().add("label", commonPartName);
814
815         if (logger.isDebugEnabled()) {
816             logger.debug("to be created, collectionobject common");
817             logger.debug(objectAsXmlString(collectionObject,
818                     CollectionobjectsCommon.class));
819         }
820
821         if (conh != null) {
822             OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
823             nhPart.getHeaders().add("label", getNHPartName());
824
825             if (logger.isDebugEnabled()) {
826                 logger.debug("to be created, collectionobject nhistory");
827                 logger.debug(objectAsXmlString(conh,
828                         CollectionobjectsNaturalhistory.class));
829             }
830         }
831         return multipart;
832
833     }
834
835     /**
836      * createCollectionObjectInstanceFromXml uses JAXB unmarshaller to retrieve
837      * collectionobject from given file
838      * @param commonPartName
839      * @param commonPartFileName
840      * @return
841      * @throws Exception
842      */
843     private MultipartOutput createCollectionObjectInstanceFromXml(String testName, String commonPartName,
844             String commonPartFileName) throws Exception {
845
846         CollectionobjectsCommon collectionObject =
847                 (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class,
848                 commonPartFileName);
849         MultipartOutput multipart = new MultipartOutput();
850         OutputPart commonPart = multipart.addPart(collectionObject,
851                 MediaType.APPLICATION_XML_TYPE);
852         commonPart.getHeaders().add("label", commonPartName);
853
854         if (logger.isDebugEnabled()) {
855             logger.debug(testName + " to be created, collectionobject common");
856             logger.debug(objectAsXmlString(collectionObject,
857                     CollectionobjectsCommon.class));
858         }
859         return multipart;
860
861     }
862
863     /**
864      * createCollectionObjectInstanceFromRawXml uses stringified collectionobject
865      * retrieve from given file
866      * @param commonPartName
867      * @param commonPartFileName
868      * @return
869      * @throws Exception
870      */
871     private MultipartOutput createCollectionObjectInstanceFromRawXml(String testName, String commonPartName,
872             String commonPartFileName) throws Exception {
873
874         MultipartOutput multipart = new MultipartOutput();
875         String stringObject = getXmlDocumentAsString(commonPartFileName);
876         if (logger.isDebugEnabled()) {
877             logger.debug(testName + " to be created, collectionobject common " + "\n" + stringObject);
878         }
879         OutputPart commonPart = multipart.addPart(stringObject,
880                 MediaType.APPLICATION_XML_TYPE);
881         commonPart.getHeaders().add("label", commonPartName);
882
883         return multipart;
884
885     }
886
887     private String getNHPartName() {
888         return "collectionobjects_naturalhistory";
889     }
890
891     private String createFromXmlFile(String testName, String fileName, boolean useJaxb) throws Exception {
892         // Perform setup, such as initializing the type of service request
893         // (e.g. CREATE, DELETE), its valid and expected status codes, and
894         // its associated HTTP method name (e.g. POST, DELETE).
895         setupCreate(testName);
896
897         MultipartOutput multipart = null;
898
899         if (useJaxb) {
900             multipart = createCollectionObjectInstanceFromXml(testName,
901                     client.getCommonPartName(), fileName);
902         } else {
903             multipart = createCollectionObjectInstanceFromRawXml(testName,
904                     client.getCommonPartName(), fileName);
905         }
906         ClientResponse<Response> res = client.create(multipart);
907         int statusCode = res.getStatus();
908
909         if (logger.isDebugEnabled()) {
910             logger.debug(testName + ": status = " + statusCode);
911         }
912         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
913                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
914         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
915         String newId = extractId(res);
916         allResourceIdsCreated.add(newId);
917         return newId;
918     }
919 }