]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
92e47298677f9afadbc91bff639a21e316c6fc27
[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         ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
437
438         if (logger.isDebugEnabled()) {
439             logger.debug("got object to update with ID: " + knownResourceId);
440         }
441         MultipartInput input = (MultipartInput) res.getEntity();
442         CollectionobjectsCommon collectionObject =
443                 (CollectionobjectsCommon) extractPart(input,
444                 client.getCommonPartName(), CollectionobjectsCommon.class);
445         Assert.assertNotNull(collectionObject);
446
447         // Update the content of this resource.
448         collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
449         collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
450         if (logger.isDebugEnabled()) {
451             logger.debug("updated object");
452             logger.debug(objectAsXmlString(collectionObject,
453                     CollectionobjectsCommon.class));
454         }
455
456         res = updateSend(testName, knownResourceId, collectionObject);
457
458         int statusCode = res.getStatus();
459         // Check the status code of the response: does it match the expected response(s)?
460         if (logger.isDebugEnabled()) {
461             logger.debug(testName + ": status = " + statusCode);
462         }
463         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
464                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
465         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
466
467
468         input = (MultipartInput) res.getEntity();
469         CollectionobjectsCommon updatedCollectionObject =
470                 (CollectionobjectsCommon) extractPart(input,
471                 client.getCommonPartName(), CollectionobjectsCommon.class);
472         Assert.assertNotNull(updatedCollectionObject);
473
474         Assert.assertEquals(updatedCollectionObject.getObjectName(),
475                 collectionObject.getObjectName(),
476                 "Data in updated object did not match submitted data.");
477
478     }
479
480     private ClientResponse<MultipartInput> updateRetrieve(String testName, String id) {
481         ClientResponse<MultipartInput> res =
482                 client.read(id);
483         if (logger.isDebugEnabled()) {
484             logger.debug("read in updateRetrieve for " + testName + " status = " + res.getStatus());
485         }
486         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
487
488         if (logger.isDebugEnabled()) {
489             logger.debug("got object to updateRetrieve for " + testName + " with ID: " + id);
490         }
491         return res;
492     }
493
494     private ClientResponse<MultipartInput> updateSend(String testName, String id,
495             CollectionobjectsCommon collectionObject) {
496         MultipartOutput output = new MultipartOutput();
497         OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
498         commonPart.getHeaders().add("label", client.getCommonPartName());
499
500         ClientResponse<MultipartInput> res = client.update(knownResourceId, output);
501         // Check the status code of the response: does it match the expected response(s)?
502         if (logger.isDebugEnabled()) {
503             logger.debug("updateSend for " + testName + ": status = " + res.getStatus());
504         }
505         return res;
506     }
507
508     // Failure outcomes
509     // Placeholders until the three tests below can be uncommented.
510     // See Issue CSPACE-401.
511     @Override
512     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
513     dependsOnMethods = {"read"})
514     public void updateWithEmptyEntityBody(String testName) throws Exception {
515     }
516
517     @Override
518     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
519     dependsOnMethods = {"read"})
520     public void updateWithMalformedXml(String testName) throws Exception {
521         // Perform setup.
522         setupUpdate(testName);
523         if (logger.isDebugEnabled()) {
524             logger.debug(testName + " got object to update with ID: " + knownResourceId);
525         }
526
527         ClientResponse<MultipartInput> res = updateRetrieve(testName, knownResourceId);
528
529         MultipartInput input = (MultipartInput) res.getEntity();
530         CollectionobjectsCommon collectionObject =
531                 (CollectionobjectsCommon) extractPart(input,
532                 client.getCommonPartName(), CollectionobjectsCommon.class);
533         Assert.assertNotNull(collectionObject);
534
535         //update with invalid content
536         collectionObject.setObjectNumber("");
537
538         if (logger.isDebugEnabled()) {
539             logger.debug(testName + " updated object");
540             logger.debug(objectAsXmlString(collectionObject,
541                     CollectionobjectsCommon.class));
542         }
543
544         // Submit the request to the service and store the response.
545         res = updateSend(testName, knownResourceId, collectionObject);
546         int statusCode = res.getStatus();
547         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
548                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
549         Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode());
550
551     }
552
553     @Override
554     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
555     dependsOnMethods = {"read"})
556     public void updateWithWrongXmlSchema(String testName) throws Exception {
557     }
558
559     /*
560     @Override
561     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
562     dependsOnMethods = {"create", "update", "testSubmitRequest"})
563     public void updateWithEmptyEntityBody(String testName) throws Exception {
564     
565     // Perform setup.
566     setupUpdateWithEmptyEntityBody(testName);
567
568     // Submit the request to the service and store the response.
569     String method = REQUEST_TYPE.httpMethodName();
570     String url = getResourceURL(knownResourceId);
571     String mediaType = MediaType.APPLICATION_XML;
572     final String entity = "";
573     int statusCode = submitRequest(method, url, mediaType, entity);
574
575     // Check the status code of the response: does it match
576     // the expected response(s)?
577     if(logger.isDebugEnabled()){
578     logger.debug(testName + ": url=" + url +
579     " status=" + statusCode);
580     }
581     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
582     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
583     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
584     }
585
586     @Override
587     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
588     dependsOnMethods = {"create", "update", "testSubmitRequest"})
589     public void updateWithMalformedXml() throws Exception {
590
591     // Perform setup.
592     setupUpdateWithMalformedXml(testName);
593
594     // Submit the request to the service and store the response.
595     String method = REQUEST_TYPE.httpMethodName();
596     String url = getResourceURL(knownResourceId);
597     final String entity = MALFORMED_XML_DATA;
598     String mediaType = MediaType.APPLICATION_XML;
599     int statusCode = submitRequest(method, url, mediaType, entity);
600
601     // Check the status code of the response: does it match
602     // the expected response(s)?
603     if(logger.isDebugEnabled()){
604     logger.debug(testName + ": url=" + url +
605     " status=" + statusCode);
606     }
607     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
608     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
609     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
610     }
611
612     @Override
613     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
614     dependsOnMethods = {"create", "update", "testSubmitRequest"})
615     public void updateWithWrongXmlSchema(String testName) throws Exception {
616     
617     // Perform setup.
618     setupUpdateWithWrongXmlSchema(String testName);
619
620     // Submit the request to the service and store the response.
621     String method = REQUEST_TYPE.httpMethodName();
622     String url = getResourceURL(knownResourceId);
623     String mediaType = MediaType.APPLICATION_XML;
624     final String entity = WRONG_XML_SCHEMA_DATA;
625     int statusCode = submitRequest(method, url, mediaType, entity);
626
627     // Check the status code of the response: does it match
628     // the expected response(s)?
629     if(logger.isDebugEnabled()){
630     logger.debug(testName + ": url=" + url +
631     " status=" + statusCode);
632     }
633     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
634     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
635     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
636     }
637      */
638     @Override
639     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
640     dependsOnMethods = {"update", "testSubmitRequest"})
641     public void updateNonExistent(String testName) throws Exception {
642
643         // Perform setup.
644         setupUpdateNonExistent(testName);
645
646         // Submit the request to the service and store the response.
647         //
648         // Note: The ID used in this 'create' call may be arbitrary.
649         // The only relevant ID may be the one used in updateCollectionObject(), below.
650         MultipartOutput multipart =
651                 createCollectionObjectInstance(client.getCommonPartName(),
652                 NON_EXISTENT_ID);
653         ClientResponse<MultipartInput> res =
654                 client.update(NON_EXISTENT_ID, multipart);
655         int statusCode = res.getStatus();
656
657         // Check the status code of the response: does it match
658         // the expected response(s)?
659         if (logger.isDebugEnabled()) {
660             logger.debug(testName + ": status = " + statusCode);
661         }
662         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
663                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
664         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
665     }
666
667     // ---------------------------------------------------------------
668     // CRUD tests : DELETE tests
669     // ---------------------------------------------------------------
670     // Success outcomes
671     @Override
672     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
673     dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
674     public void delete(String testName) throws Exception {
675
676         // Perform setup.
677         setupDelete(testName);
678
679         // Submit the request to the service and store the response.
680         ClientResponse<Response> res = client.delete(knownResourceId);
681         int statusCode = res.getStatus();
682
683         // Check the status code of the response: does it match
684         // the expected response(s)?
685         if (logger.isDebugEnabled()) {
686             logger.debug(testName + ": status = " + statusCode);
687         }
688         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
689                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
690         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
691     }
692
693     // Failure outcomes
694     @Override
695     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
696     dependsOnMethods = {"delete"})
697     public void deleteNonExistent(String testName) throws Exception {
698
699         // Perform setup.
700         setupDeleteNonExistent(testName);
701
702         // Submit the request to the service and store the response.
703         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
704         int statusCode = res.getStatus();
705
706         // Check the status code of the response: does it match
707         // the expected response(s)?
708         if (logger.isDebugEnabled()) {
709             logger.debug(testName + ": status = " + statusCode);
710         }
711         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
712                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
713         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
714     }
715
716     // ---------------------------------------------------------------
717     // Utility tests : tests of code used in tests above
718     // ---------------------------------------------------------------
719     /**
720      * Tests the code for manually submitting data that is used by several
721      * of the methods above.
722      */
723
724     @Test(dependsOnMethods = {"create", "read"})
725     public void testSubmitRequest() throws Exception {
726         testSubmitRequest(knownResourceId);
727     }
728
729     private void testSubmitRequest(String resourceId) throws Exception {
730
731         // Expected status code: 200 OK
732         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
733
734         // Submit the request to the service and store the response.
735         String method = ServiceRequestType.READ.httpMethodName();
736         String url = getResourceURL(resourceId);
737         int statusCode = submitRequest(method, url);
738
739         // Check the status code of the response: does it match
740         // the expected response(s)?
741         if (logger.isDebugEnabled()) {
742             logger.debug("testSubmitRequest: url=" + url
743                     + " status=" + statusCode);
744         }
745         Assert.assertEquals(statusCode, EXPECTED_STATUS);
746
747     }
748
749     // ---------------------------------------------------------------
750     // Cleanup of resources created during testing
751     // ---------------------------------------------------------------
752     /**
753      * Deletes all resources created by tests, after all tests have been run.
754      *
755      * This cleanup method will always be run, even if one or more tests fail.
756      * For this reason, it attempts to remove all resources created
757      * at any point during testing, even if some of those resources
758      * may be expected to be deleted by certain tests.
759      */
760     @AfterClass(alwaysRun = true)
761     public void cleanUp() {
762         if (logger.isDebugEnabled()) {
763             logger.debug("Cleaning up temporary resources created for testing ...");
764         }
765         for (String resourceId : allResourceIdsCreated) {
766             // Note: Any non-success responses are ignored and not reported.
767             ClientResponse<Response> res = client.delete(resourceId);
768         }
769     }
770
771     // ---------------------------------------------------------------
772     // Utility methods used by tests above
773     // ---------------------------------------------------------------
774     private MultipartOutput createCollectionObjectInstance(String commonPartName,
775             String identifier) {
776         return createCollectionObjectInstance(commonPartName,
777                 "objectNumber-" + identifier,
778                 "objectName-" + identifier);
779     }
780
781     private MultipartOutput createCollectionObjectInstance(String commonPartName,
782             String objectNumber, String objectName) {
783         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
784         ResponsibleDepartmentList deptList = new ResponsibleDepartmentList();
785         List<String> depts = deptList.getResponsibleDepartment();
786         // @TODO Use properly formatted refNames for representative departments
787         // in this example test record. The following are mere placeholders.
788         depts.add("urn:org.collectionspace.services.department:Registrar");
789         if (multivalue) {
790             depts.add("urn:org.walkerart.department:Fine Art");
791         }
792         multivalue = !multivalue;
793         //FIXME: Title does not need to be set.
794         collectionObject.setTitle("atitle");
795         collectionObject.setResponsibleDepartments(deptList);
796         collectionObject.setObjectNumber(objectNumber);
797         collectionObject.setOtherNumber("urn:org.walkerart.id:123");
798         collectionObject.setObjectName(objectName);
799         collectionObject.setAge(""); //test for null string
800         collectionObject.setBriefDescription("Papier mache bird cow mask with horns, "
801                 + "painted red with black and yellow spots. "
802                 + "Puerto Rico. ca. 8&quot; high, 6&quot; wide, projects 10&quot; (with horns).");
803
804         CollectionobjectsNaturalhistory conh = new CollectionobjectsNaturalhistory();
805         conh.setNhString("test-string");
806         conh.setNhInt(999);
807         conh.setNhLong(9999);
808
809
810         MultipartOutput multipart = createCollectionObjectInstance(commonPartName, collectionObject, conh);
811         return multipart;
812     }
813
814     private MultipartOutput createCollectionObjectInstance(String commonPartName,
815             CollectionobjectsCommon collectionObject, CollectionobjectsNaturalhistory conh) {
816
817         MultipartOutput multipart = new MultipartOutput();
818         OutputPart commonPart = multipart.addPart(collectionObject,
819                 MediaType.APPLICATION_XML_TYPE);
820         commonPart.getHeaders().add("label", commonPartName);
821
822         if (logger.isDebugEnabled()) {
823             logger.debug("to be created, collectionobject common");
824             logger.debug(objectAsXmlString(collectionObject,
825                     CollectionobjectsCommon.class));
826         }
827
828         if (conh != null) {
829             OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
830             nhPart.getHeaders().add("label", getNHPartName());
831
832             if (logger.isDebugEnabled()) {
833                 logger.debug("to be created, collectionobject nhistory");
834                 logger.debug(objectAsXmlString(conh,
835                         CollectionobjectsNaturalhistory.class));
836             }
837         }
838         return multipart;
839
840     }
841
842     /**
843      * createCollectionObjectInstanceFromXml uses JAXB unmarshaller to retrieve
844      * collectionobject from given file
845      * @param commonPartName
846      * @param commonPartFileName
847      * @return
848      * @throws Exception
849      */
850     private MultipartOutput createCollectionObjectInstanceFromXml(String testName, String commonPartName,
851             String commonPartFileName) throws Exception {
852
853         CollectionobjectsCommon collectionObject =
854                 (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class,
855                 commonPartFileName);
856         MultipartOutput multipart = new MultipartOutput();
857         OutputPart commonPart = multipart.addPart(collectionObject,
858                 MediaType.APPLICATION_XML_TYPE);
859         commonPart.getHeaders().add("label", commonPartName);
860
861         if (logger.isDebugEnabled()) {
862             logger.debug(testName + " to be created, collectionobject common");
863             logger.debug(objectAsXmlString(collectionObject,
864                     CollectionobjectsCommon.class));
865         }
866         return multipart;
867
868     }
869
870     /**
871      * createCollectionObjectInstanceFromRawXml uses stringified collectionobject
872      * retrieve from given file
873      * @param commonPartName
874      * @param commonPartFileName
875      * @return
876      * @throws Exception
877      */
878     private MultipartOutput createCollectionObjectInstanceFromRawXml(String testName, String commonPartName,
879             String commonPartFileName) throws Exception {
880
881         MultipartOutput multipart = new MultipartOutput();
882         String stringObject = getXmlDocumentAsString(commonPartFileName);
883         if (logger.isDebugEnabled()) {
884             logger.debug(testName + " to be created, collectionobject common " + "\n" + stringObject);
885         }
886         OutputPart commonPart = multipart.addPart(stringObject,
887                 MediaType.APPLICATION_XML_TYPE);
888         commonPart.getHeaders().add("label", commonPartName);
889
890         return multipart;
891
892     }
893
894     private String getNHPartName() {
895         return "collectionobjects_naturalhistory";
896     }
897
898     private String createFromXmlFile(String testName, String fileName, boolean useJaxb) throws Exception {
899         // Perform setup, such as initializing the type of service request
900         // (e.g. CREATE, DELETE), its valid and expected status codes, and
901         // its associated HTTP method name (e.g. POST, DELETE).
902         setupCreate(testName);
903
904         MultipartOutput multipart = null;
905
906         if (useJaxb) {
907             multipart = createCollectionObjectInstanceFromXml(testName, 
908                     client.getCommonPartName(), fileName);
909         } else {
910             multipart = createCollectionObjectInstanceFromRawXml(testName, 
911                     client.getCommonPartName(), fileName);
912         }
913         ClientResponse<Response> res = client.create(multipart);
914         int statusCode = res.getStatus();
915
916         if (logger.isDebugEnabled()) {
917             logger.debug(testName + ": status = " + statusCode);
918         }
919         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
920                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
921         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
922         String newId = extractId(res);
923         allResourceIdsCreated.add(newId);
924         return newId;
925     }
926 }