]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
a32dacd2bebae8666d795e98d1c77a2fac919347
[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 (c)) 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.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import javax.ws.rs.core.MediaType;
30 import javax.ws.rs.core.Response;
31
32 import org.collectionspace.services.client.VocabularyClient;
33 import org.collectionspace.services.vocabulary.VocabulariesCommon;
34 import org.collectionspace.services.vocabulary.VocabulariesCommonList;
35 import org.collectionspace.services.vocabulary.VocabularyitemsCommon;
36 import org.collectionspace.services.vocabulary.VocabularyitemsCommonList;
37
38 import org.jboss.resteasy.client.ClientResponse;
39 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
40 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
41 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.testng.Assert;
45 import org.testng.annotations.AfterClass;
46 import org.testng.annotations.Test;
47
48 /**
49  * VocabularyServiceTest, carries out tests against a
50  * deployed and running Vocabulary Service.
51  *
52  * $LastChangedRevision: 753 $
53  * $LastChangedDate: 2009-09-23 11:03:36 -0700 (Wed, 23 Sep 2009) $
54  */
55 public class VocabularyServiceTest extends AbstractServiceTest {
56
57     private final Logger logger =
58         LoggerFactory.getLogger(VocabularyServiceTest.class);
59
60     // Instance variables specific to this test.
61     private VocabularyClient client = new VocabularyClient();
62     final String SERVICE_PATH_COMPONENT = "vocabularies";
63     final String ITEM_SERVICE_PATH_COMPONENT = "items";
64     private String knownResourceId = null;
65     private String knownResourceRefName = null;
66     private String knownItemResourceId = null;
67     private List<String> allResourceIdsCreated = new ArrayList<String>();
68     private Map<String, String> allResourceItemIdsCreated =
69         new HashMap<String, String>();
70     
71     protected String createRefName(String displayName) {
72         return displayName.replaceAll("\\W", "");
73     }    
74
75     // ---------------------------------------------------------------
76     // CRUD tests : CREATE tests
77     // ---------------------------------------------------------------
78     // Success outcomes
79     @Override
80     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class)
81     public void create(String testName) throws Exception {
82
83         // Perform setup, such as initializing the type of service request
84         // (e.g. CREATE, DELETE), its valid and expected status codes, and
85         // its associated HTTP method name (e.g. POST, DELETE).
86         setupCreate(testName);
87
88         // Submit the request to the service and store the response.
89         String identifier = createIdentifier();
90         String displayName = "displayName-" + identifier;
91         String refName = createRefName(displayName);
92         String typeName = "vocabType-" + identifier;
93         MultipartOutput multipart = 
94                 createVocabularyInstance(displayName, refName, typeName);
95         ClientResponse<Response> res = client.create(multipart);
96         int statusCode = res.getStatus();
97
98         // Check the status code of the response: does it match
99         // the expected response(s)?
100         //
101         // Specifically:
102         // Does it fall within the set of valid status codes?
103         // Does it exactly match the expected status code?
104         if(logger.isDebugEnabled()){
105             logger.debug(testName + ": status = " + statusCode);
106         }
107         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
108                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
109         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
110
111         // Store the refname from the first resource created
112         // for additional tests below.
113         knownResourceRefName = refName;
114
115         // Store the ID returned from the first resource created
116         // for additional tests below.
117         if (knownResourceId == null){
118             knownResourceId = extractId(res);
119             if (logger.isDebugEnabled()) {
120                 logger.debug(testName + ": knownResourceId=" + knownResourceId);
121             }
122         }
123         // Store the IDs from every resource created by tests,
124         // so they can be deleted after tests have been run.
125         allResourceIdsCreated.add(extractId(res));
126
127     }
128
129     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
130         dependsOnMethods = {"create"})
131     public void createItem(String testName) {
132         setupCreate(testName);
133
134         knownItemResourceId = createItemInVocab(knownResourceId);
135         if(logger.isDebugEnabled()){
136             logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
137         }
138     }
139
140     private String createItemInVocab(String vcsid) {
141
142         final String testName = "createItemInVocab";
143         if(logger.isDebugEnabled()){
144             logger.debug(testName + ":...");
145         }
146
147         // Submit the request to the service and store the response.
148         String identifier = createIdentifier();
149         String refName = createRefName(identifier);
150         MultipartOutput multipart = createVocabularyItemInstance(vcsid, identifier, refName);
151         ClientResponse<Response> res = client.createItem(vcsid, multipart);
152         int statusCode = res.getStatus();
153
154         // Check the status code of the response: does it match
155         // the expected response(s)?
156         if(logger.isDebugEnabled()){
157             logger.debug(testName + ": status = " + statusCode);
158         }
159         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
160                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
161         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
162
163         // Store the ID returned from the first item resource created
164         // for additional tests below.
165         if (knownItemResourceId == null){
166             knownItemResourceId = extractId(res);
167             if (logger.isDebugEnabled()) {
168                 logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
169             }
170         }
171
172         // Store the IDs from any item resources created
173         // by tests, along with the IDs of their parents, so these items
174         // can be deleted after all tests have been run.
175         //
176         // Item resource IDs are unique, so these are used as keys;
177         // the non-unique IDs of their parents are stored as associated values.
178         allResourceItemIdsCreated.put(extractId(res), vcsid);
179
180         return extractId(res);
181     }
182
183     @Override
184     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
185             dependsOnMethods = {"create", "createItem"})
186     public void createList(String testName) throws Exception {
187         for (int i = 0; i < 3; i++) {
188             create(testName);
189             // Add 3 items to each vocab
190             for (int j = 0; j < 3; j++) {
191                 createItem(testName);
192             }
193         }
194     }
195
196     // Failure outcomes
197     // Placeholders until the three tests below can be uncommented.
198     // See Issue CSPACE-401.
199     @Override
200     public void createWithEmptyEntityBody(String testName) throws Exception {
201     }
202
203     @Override
204     public void createWithMalformedXml(String testName) throws Exception {
205     }
206
207     @Override
208     public void createWithWrongXmlSchema(String testName) throws Exception {
209     }
210
211     /*
212     @Override
213     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
214         dependsOnMethods = {"create", "testSubmitRequest"})
215     public void createWithEmptyEntityBody(String testName) throws Exception {
216
217     // Perform setup.
218     setupCreateWithEmptyEntityBody(testName);
219
220     // Submit the request to the service and store the response.
221     String method = REQUEST_TYPE.httpMethodName();
222     String url = getServiceRootURL();
223     String mediaType = MediaType.APPLICATION_XML;
224     final String entity = "";
225     int statusCode = submitRequest(method, url, mediaType, entity);
226
227     // Check the status code of the response: does it match
228     // the expected response(s)?
229     if(logger.isDebugEnabled()) {
230         logger.debug(testName + ": url=" + url +
231             " status=" + statusCode);
232      }
233     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
234     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
235     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
236     }
237
238     @Override
239     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
240         dependsOnMethods = {"create", "testSubmitRequest"})
241     public void createWithMalformedXml(String testName) throws Exception {
242
243     // Perform setup.
244     setupCreateWithMalformedXml(testName);
245
246     // Submit the request to the service and store the response.
247     String method = REQUEST_TYPE.httpMethodName();
248     String url = getServiceRootURL();
249     String mediaType = MediaType.APPLICATION_XML;
250     final String entity = MALFORMED_XML_DATA; // Constant from base class.
251     int statusCode = submitRequest(method, url, mediaType, entity);
252
253     // Check the status code of the response: does it match
254     // the expected response(s)?
255     if(logger.isDebugEnabled()){
256         logger.debug(testName + ": url=" + url +
257             " status=" + statusCode);
258      }
259     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
260     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
261     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
262     }
263
264     @Override
265     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
266         dependsOnMethods = {"create", "testSubmitRequest"})
267     public void createWithWrongXmlSchema(String testName) throws Exception {
268
269     // Perform setup.
270     setupCreateWithWrongXmlSchema(testName);
271
272     // Submit the request to the service and store the response.
273     String method = REQUEST_TYPE.httpMethodName();
274     String url = getServiceRootURL();
275     String mediaType = MediaType.APPLICATION_XML;
276     final String entity = WRONG_XML_SCHEMA_DATA;
277     int statusCode = submitRequest(method, url, mediaType, entity);
278
279     // Check the status code of the response: does it match
280     // the expected response(s)?
281     if(logger.isDebugEnabled()){
282         logger.debug(testName + ": url=" + url +
283             " status=" + statusCode);
284      }
285     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
286     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
287     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
288     }
289      */
290
291     // ---------------------------------------------------------------
292     // CRUD tests : READ tests
293     // ---------------------------------------------------------------
294     // Success outcomes
295     @Override
296     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
297         dependsOnMethods = {"create"})
298     public void read(String testName) throws Exception {
299
300         // Perform setup.
301         setupRead();
302
303         // Submit the request to the service and store the response.
304         ClientResponse<MultipartInput> res = client.read(knownResourceId);
305         int statusCode = res.getStatus();
306
307         // Check the status code of the response: does it match
308         // the expected response(s)?
309         if(logger.isDebugEnabled()){
310             logger.debug(testName + ": status = " + statusCode);
311         }
312         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
313                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
314         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
315         //FIXME: remove the following try catch once Aron fixes signatures
316         try {
317             MultipartInput input = (MultipartInput) res.getEntity();
318             VocabulariesCommon vocabulary = (VocabulariesCommon) extractPart(input,
319                     client.getCommonPartName(), VocabulariesCommon.class);
320             Assert.assertNotNull(vocabulary);
321         } catch (Exception e) {
322             throw new RuntimeException(e);
323         }
324     }
325
326     /*
327     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
328             dependsOnMethods = {"read"})
329         public void readByName(String testName) throws Exception {
330
331             // Perform setup.
332             setupRead();
333
334             // Submit the request to the service and store the response.
335             ClientResponse<MultipartInput> res = client.read(knownResourceId);
336             int statusCode = res.getStatus();
337
338             // Check the status code of the response: does it match
339             // the expected response(s)?
340             if(logger.isDebugEnabled()){
341                 logger.debug(testName + ": status = " + statusCode);
342             }
343             Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
344                     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
345             Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
346             //FIXME: remove the following try catch once Aron fixes signatures
347             try {
348                 MultipartInput input = (MultipartInput) res.getEntity();
349                 VocabulariesCommon vocabulary = (VocabulariesCommon) extractPart(input,
350                         client.getCommonPartName(), VocabulariesCommon.class);
351                 Assert.assertNotNull(vocabulary);
352             } catch (Exception e) {
353                 throw new RuntimeException(e);
354             }
355         }
356     */
357
358     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
359         dependsOnMethods = {"createItem", "read"})
360     public void readItem(String testName) throws Exception {
361
362         // Perform setup.
363         setupRead(testName);
364
365         // Submit the request to the service and store the response.
366         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, knownItemResourceId);
367         int statusCode = res.getStatus();
368
369         // Check the status code of the response: does it match
370         // the expected response(s)?
371         if(logger.isDebugEnabled()){
372             logger.debug(testName + ": status = " + statusCode);
373         }
374         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
375                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
376         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
377
378         // Check whether we've received a vocabulary item.
379         MultipartInput input = (MultipartInput) res.getEntity();
380         VocabularyitemsCommon vocabularyItem = (VocabularyitemsCommon) extractPart(input,
381                 client.getItemCommonPartName(), VocabularyitemsCommon.class);
382         Assert.assertNotNull(vocabularyItem);
383
384     }
385
386     // Failure outcomes
387     @Override
388     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
389         dependsOnMethods = {"read"})
390     public void readNonExistent(String testName) {
391
392         // Perform setup.
393         setupReadNonExistent(testName);
394
395         // Submit the request to the service and store the response.
396         ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
397         int statusCode = res.getStatus();
398
399         // Check the status code of the response: does it match
400         // the expected response(s)?
401         if(logger.isDebugEnabled()){
402             logger.debug(testName + ": status = " + statusCode);
403         }
404         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
405                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
406         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
407     }
408
409     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
410         dependsOnMethods = {"readItem", "readNonExistent"})
411     public void readItemNonExistent(String testName) {
412
413         // Perform setup.
414         setupReadNonExistent(testName);
415
416         // Submit the request to the service and store the response.
417         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, NON_EXISTENT_ID);
418         int statusCode = res.getStatus();
419
420         // Check the status code of the response: does it match
421         // the expected response(s)?
422         if(logger.isDebugEnabled()){
423             logger.debug(testName + ": status = " + statusCode);
424         }
425         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
426                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
427         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
428     }
429     // ---------------------------------------------------------------
430     // CRUD tests : READ_LIST tests
431     // ---------------------------------------------------------------
432     // Success outcomes
433
434     @Override
435     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
436         dependsOnMethods = {"read"})
437     public void readList(String testName) throws Exception {
438
439         // Perform setup.
440         setupReadList(testName);
441
442         // Submit the request to the service and store the response.
443         ClientResponse<VocabulariesCommonList> res = client.readList();
444         VocabulariesCommonList list = res.getEntity();
445         int statusCode = res.getStatus();
446
447         // Check the status code of the response: does it match
448         // the expected response(s)?
449         if(logger.isDebugEnabled()){
450             logger.debug(testName + ": status = " + statusCode);
451         }
452         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
453                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
454         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
455
456         // Optionally output additional data about list members for debugging.
457         boolean iterateThroughList = false;
458         if (iterateThroughList && logger.isDebugEnabled()) {
459             List<VocabulariesCommonList.VocabularyListItem> items =
460                     list.getVocabularyListItem();
461             int i = 0;
462             for (VocabulariesCommonList.VocabularyListItem item : items) {
463                 String csid = item.getCsid();
464                 logger.debug(testName + ": list-item[" + i + "] csid=" +
465                         csid);
466                 logger.debug(testName + ": list-item[" + i + "] displayName=" +
467                         item.getDisplayName());
468                 logger.debug(testName + ": list-item[" + i + "] URI=" +
469                         item.getUri());
470                 readItemList(csid);
471                 i++;
472             }
473         }
474     }
475
476     @Test(dependsOnMethods = {"readItem"})
477     public void readItemList() {
478         readItemList(knownResourceId);
479     }
480
481     private void readItemList(String vcsid) {
482
483         final String testName = "readItemList";
484
485         // Perform setup.
486         setupReadList(testName);
487
488         // Submit the request to the service and store the response.
489         ClientResponse<VocabularyitemsCommonList> res =
490                 client.readItemList(vcsid);
491         VocabularyitemsCommonList list = res.getEntity();
492         int statusCode = res.getStatus();
493
494         // Check the status code of the response: does it match
495         // the expected response(s)?
496         if(logger.isDebugEnabled()){
497             logger.debug("  " + testName + ": status = " + statusCode);
498         }
499         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
500                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
501         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
502
503         // Optionally output additional data about list members for debugging.
504         boolean iterateThroughList = false;
505         if (iterateThroughList && logger.isDebugEnabled()) {
506             List<VocabularyitemsCommonList.VocabularyitemListItem> items =
507                     list.getVocabularyitemListItem();
508             int i = 0;
509             for (VocabularyitemsCommonList.VocabularyitemListItem item : items) {
510                 logger.debug("  " + testName + ": list-item[" + i + "] csid=" +
511                         item.getCsid());
512                 logger.debug("  " + testName + ": list-item[" + i + "] displayName=" +
513                         item.getDisplayName());
514                 logger.debug("  " + testName + ": list-item[" + i + "] URI=" +
515                         item.getUri());
516                 i++;
517             }
518         }
519     }
520
521     // Failure outcomes
522     // None at present.
523     // ---------------------------------------------------------------
524     // CRUD tests : UPDATE tests
525     // ---------------------------------------------------------------
526     // Success outcomes
527     @Override
528     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
529         dependsOnMethods = {"read"})
530     public void update(String testName) throws Exception {
531
532         // Perform setup.
533         setupUpdate(testName);
534
535         // Retrieve the contents of a resource to update.
536         ClientResponse<MultipartInput> res =
537                 client.read(knownResourceId);
538         if(logger.isDebugEnabled()){
539             logger.debug(testName + ": read status = " + res.getStatus());
540         }
541         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
542
543         if(logger.isDebugEnabled()){
544             logger.debug("got Vocabulary to update with ID: " + knownResourceId);
545         }
546         MultipartInput input = (MultipartInput) res.getEntity();
547         VocabulariesCommon vocabulary = (VocabulariesCommon) extractPart(input,
548                 client.getCommonPartName(), VocabulariesCommon.class);
549         Assert.assertNotNull(vocabulary);
550
551         // Update the contents of this resource.
552         vocabulary.setDisplayName("updated-" + vocabulary.getDisplayName());
553         vocabulary.setVocabType("updated-" + vocabulary.getVocabType());
554         if(logger.isDebugEnabled()){
555             logger.debug("to be updated Vocabulary");
556             logger.debug(objectAsXmlString(vocabulary, VocabulariesCommon.class));
557         }
558
559         // Submit the updated resource to the service and store the response.
560         MultipartOutput output = new MultipartOutput();
561         OutputPart commonPart = output.addPart(vocabulary, MediaType.APPLICATION_XML_TYPE);
562         commonPart.getHeaders().add("label", client.getCommonPartName());
563         res = client.update(knownResourceId, output);
564         int statusCode = res.getStatus();
565
566         // Check the status code of the response: does it match the expected response(s)?
567         if(logger.isDebugEnabled()){
568             logger.debug("update: status = " + statusCode);
569         }
570         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
571                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
572         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
573
574         // Retrieve the updated resource and verify that its contents exist.
575         input = (MultipartInput) res.getEntity();
576         VocabulariesCommon updatedVocabulary =
577                 (VocabulariesCommon) extractPart(input,
578                         client.getCommonPartName(), VocabulariesCommon.class);
579         Assert.assertNotNull(updatedVocabulary);
580
581         // Verify that the updated resource received the correct data.
582         Assert.assertEquals(updatedVocabulary.getDisplayName(),
583                 vocabulary.getDisplayName(),
584                 "Data in updated object did not match submitted data.");
585     }
586
587     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
588         dependsOnMethods = {"readItem", "update"})
589     public void updateItem(String testName) throws Exception {
590
591         // Perform setup.
592         setupUpdate(testName);
593
594         ClientResponse<MultipartInput> res =
595                 client.readItem(knownResourceId, knownItemResourceId);
596         if(logger.isDebugEnabled()){
597             logger.debug(testName + ": read status = " + res.getStatus());
598         }
599         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
600
601         if(logger.isDebugEnabled()){
602             logger.debug("got VocabularyItem to update with ID: " +
603                 knownItemResourceId +
604                 " in Vocab: " + knownResourceId );
605         }
606         MultipartInput input = (MultipartInput) res.getEntity();
607         VocabularyitemsCommon vocabularyItem = (VocabularyitemsCommon) extractPart(input,
608                 client.getItemCommonPartName(), VocabularyitemsCommon.class);
609         Assert.assertNotNull(vocabularyItem);
610
611         // Update the contents of this resource.
612         vocabularyItem.setDisplayName("updated-" + vocabularyItem.getDisplayName());
613         if(logger.isDebugEnabled()){
614             logger.debug("to be updated VocabularyItem");
615             logger.debug(objectAsXmlString(vocabularyItem,
616                 VocabularyitemsCommon.class));
617         }
618
619         // Submit the updated resource to the service and store the response.
620         MultipartOutput output = new MultipartOutput();
621         OutputPart commonPart = output.addPart(vocabularyItem, MediaType.APPLICATION_XML_TYPE);
622         commonPart.getHeaders().add("label", client.getItemCommonPartName());
623         res = client.updateItem(knownResourceId, knownItemResourceId, output);
624         int statusCode = res.getStatus();
625
626         // Check the status code of the response: does it match the expected response(s)?
627         if(logger.isDebugEnabled()){
628             logger.debug("updateItem: status = " + statusCode);
629         }
630         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
631                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
632         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
633
634         // Retrieve the updated resource and verify that its contents exist.
635         input = (MultipartInput) res.getEntity();
636         VocabularyitemsCommon updatedVocabularyItem =
637                 (VocabularyitemsCommon) extractPart(input,
638                         client.getItemCommonPartName(), VocabularyitemsCommon.class);
639         Assert.assertNotNull(updatedVocabularyItem);
640
641         // Verify that the updated resource received the correct data.
642         Assert.assertEquals(updatedVocabularyItem.getDisplayName(),
643                 vocabularyItem.getDisplayName(),
644                 "Data in updated VocabularyItem did not match submitted data.");
645     }
646
647     // Failure outcomes
648     // Placeholders until the three tests below can be uncommented.
649     // See Issue CSPACE-401.
650     @Override
651     public void updateWithEmptyEntityBody(String testName) throws Exception {
652     }
653
654     @Override
655     public void updateWithMalformedXml(String testName) throws Exception {
656     }
657
658     @Override
659     public void updateWithWrongXmlSchema(String testName) throws Exception {
660     }
661
662     /*
663     @Override
664     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
665         dependsOnMethods = {"create", "update", "testSubmitRequest"})
666     public void updateWithEmptyEntityBody(String testName) throws Exception {
667
668     // Perform setup.
669     setupUpdateWithEmptyEntityBody(testName);
670
671     // Submit the request to the service and store the response.
672     String method = REQUEST_TYPE.httpMethodName();
673     String url = getResourceURL(knownResourceId);
674     String mediaType = MediaType.APPLICATION_XML;
675     final String entity = "";
676     int statusCode = submitRequest(method, url, mediaType, entity);
677
678     // Check the status code of the response: does it match
679     // the expected response(s)?
680     if(logger.isDebugEnabled()){
681         logger.debug(testName + ": url=" + url +
682             " status=" + statusCode);
683      }
684     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
685     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
686     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
687     }
688
689     @Override
690     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
691         dependsOnMethods = {"create", "update", "testSubmitRequest"})
692     public void updateWithMalformedXml(String testName) throws Exception {
693
694     // Perform setup.
695     setupUpdateWithMalformedXml(testName);
696
697     // Submit the request to the service and store the response.
698     String method = REQUEST_TYPE.httpMethodName();
699     String url = getResourceURL(knownResourceId);
700     String mediaType = MediaType.APPLICATION_XML;
701     final String entity = MALFORMED_XML_DATA;
702     int statusCode = submitRequest(method, url, mediaType, entity);
703
704     // Check the status code of the response: does it match
705     // the expected response(s)?
706     if(logger.isDebugEnabled()){
707         logger.debug(testName + ": url=" + url +
708            " status=" + statusCode);
709      }
710     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
711     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
712     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
713     }
714
715     @Override
716     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
717         dependsOnMethods = {"create", "update", "testSubmitRequest"})
718     public void updateWithWrongXmlSchema(String testName) throws Exception {
719
720     // Perform setup.
721     setupUpdateWithWrongXmlSchema(testName);
722
723     // Submit the request to the service and store the response.
724     String method = REQUEST_TYPE.httpMethodName();
725     String url = getResourceURL(knownResourceId);
726     String mediaType = MediaType.APPLICATION_XML;
727     final String entity = WRONG_XML_SCHEMA_DATA;
728     int statusCode = submitRequest(method, url, mediaType, entity);
729
730     // Check the status code of the response: does it match
731     // the expected response(s)?
732     if(logger.isDebugEnabled()){
733         logger.debug("updateWithWrongXmlSchema: url=" + url +
734             " status=" + statusCode);
735      }
736     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
737     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
738     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
739     }
740      */
741
742
743     @Override
744     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
745         dependsOnMethods = {"update", "testSubmitRequest"})
746     public void updateNonExistent(String testName) throws Exception {
747
748         // Perform setup.
749         setupUpdateNonExistent(testName);
750
751         // Submit the request to the service and store the response.
752         // Note: The ID used in this 'create' call may be arbitrary.
753         // The only relevant ID may be the one used in update(), below.
754
755         // The only relevant ID may be the one used in update(), below.
756         MultipartOutput multipart = createVocabularyInstance(NON_EXISTENT_ID);
757         ClientResponse<MultipartInput> res =
758                 client.update(NON_EXISTENT_ID, multipart);
759         int statusCode = res.getStatus();
760
761         // Check the status code of the response: does it match
762         // the expected response(s)?
763         if(logger.isDebugEnabled()){
764             logger.debug(testName + ": status = " + statusCode);
765         }
766         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
767                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
768         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
769     }
770
771     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
772         dependsOnMethods = {"updateItem", "testItemSubmitRequest"})
773     public void updateNonExistentItem(String testName) throws Exception {
774
775         // Perform setup.
776         setupUpdateNonExistent(testName);
777
778         // Submit the request to the service and store the response.
779         // Note: The ID used in this 'create' call may be arbitrary.
780         // The only relevant ID may be the one used in update(), below.
781
782         // The only relevant ID may be the one used in update(), below.
783         MultipartOutput multipart = createVocabularyItemInstance(
784                         knownResourceId, NON_EXISTENT_ID, createRefName(NON_EXISTENT_ID));
785         ClientResponse<MultipartInput> res =
786                 client.updateItem(knownResourceId, NON_EXISTENT_ID, multipart);
787         int statusCode = res.getStatus();
788
789         // Check the status code of the response: does it match
790         // the expected response(s)?
791         if(logger.isDebugEnabled()){
792             logger.debug(testName + ": status = " + statusCode);
793         }
794         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
795                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
796         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
797     }
798
799     // ---------------------------------------------------------------
800     // CRUD tests : DELETE tests
801     // ---------------------------------------------------------------
802     // Success outcomes
803     @Override
804     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
805         dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
806     public void delete(String testName) throws Exception {
807
808         // Perform setup.
809         setupDelete(testName);
810
811         // Submit the request to the service and store the response.
812         ClientResponse<Response> res = client.delete(knownResourceId);
813         int statusCode = res.getStatus();
814
815         // Check the status code of the response: does it match
816         // the expected response(s)?
817         if(logger.isDebugEnabled()){
818             logger.debug(testName + ": status = " + statusCode);
819         }
820         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
821                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
822         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
823     }
824
825    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
826         dependsOnMethods = {"createItem", "readItemList", "testItemSubmitRequest",
827             "updateItem"})
828     public void deleteItem(String testName) throws Exception {
829
830         // Perform setup.
831         setupDelete(testName);
832
833         // Submit the request to the service and store the response.
834         ClientResponse<Response> res = client.deleteItem(knownResourceId, knownItemResourceId);
835         int statusCode = res.getStatus();
836
837         // Check the status code of the response: does it match
838         // the expected response(s)?
839         if(logger.isDebugEnabled()){
840             logger.debug("delete: status = " + statusCode);
841         }
842         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
843                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
844         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
845     }
846
847     // Failure outcomes
848     @Override
849     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
850         dependsOnMethods = {"delete"})
851     public void deleteNonExistent(String testName) throws Exception {
852
853         // Perform setup.
854         setupDeleteNonExistent(testName);
855
856         // Submit the request to the service and store the response.
857         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
858         int statusCode = res.getStatus();
859
860         // Check the status code of the response: does it match
861         // the expected response(s)?
862         if(logger.isDebugEnabled()){
863             logger.debug(testName + ": status = " + statusCode);
864         }
865         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
866                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
867         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
868     }
869
870     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
871         dependsOnMethods = {"deleteItem"})
872     public void deleteNonExistentItem(String testName) {
873
874         // Perform setup.
875         setupDeleteNonExistent(testName);
876
877         // Submit the request to the service and store the response.
878         ClientResponse<Response> res = client.deleteItem(knownResourceId, NON_EXISTENT_ID);
879         int statusCode = res.getStatus();
880
881         // Check the status code of the response: does it match
882         // the expected response(s)?
883         if(logger.isDebugEnabled()){
884             logger.debug(testName + ": status = " + statusCode);
885         }
886         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
887                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
888         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
889     }
890
891     // ---------------------------------------------------------------
892     // Utility tests : tests of code used in tests above
893     // ---------------------------------------------------------------
894     /**
895      * Tests the code for manually submitting data that is used by several
896      * of the methods above.
897      */
898     @Test(dependsOnMethods = {"create", "read"})
899     public void testSubmitRequest() {
900
901         // Expected status code: 200 OK
902         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
903
904         // Submit the request to the service and store the response.
905         String method = ServiceRequestType.READ.httpMethodName();
906         String url = getResourceURL(knownResourceId);
907         int statusCode = submitRequest(method, url);
908
909         // Check the status code of the response: does it match
910         // the expected response(s)?
911         if(logger.isDebugEnabled()){
912             logger.debug("testSubmitRequest: url=" + url +
913                 " status=" + statusCode);
914         }
915         Assert.assertEquals(statusCode, EXPECTED_STATUS);
916
917     }
918
919     @Test(dependsOnMethods = {"createItem", "readItem", "testSubmitRequest"})
920     public void testItemSubmitRequest() {
921
922         // Expected status code: 200 OK
923         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
924
925         // Submit the request to the service and store the response.
926         String method = ServiceRequestType.READ.httpMethodName();
927         String url = getItemResourceURL(knownResourceId, knownItemResourceId);
928         int statusCode = submitRequest(method, url);
929
930         // Check the status code of the response: does it match
931         // the expected response(s)?
932         if(logger.isDebugEnabled()){
933             logger.debug("testItemSubmitRequest: url=" + url +
934                 " status=" + statusCode);
935         }
936         Assert.assertEquals(statusCode, EXPECTED_STATUS);
937
938     }
939
940     // ---------------------------------------------------------------
941     // Cleanup of resources created during testing
942     // ---------------------------------------------------------------
943     
944     /**
945      * Deletes all resources created by tests, after all tests have been run.
946      *
947      * This cleanup method will always be run, even if one or more tests fail.
948      * For this reason, it attempts to remove all resources created
949      * at any point during testing, even if some of those resources
950      * may be expected to be deleted by certain tests.
951      */
952     @AfterClass(alwaysRun=true)
953     public void cleanUp() {
954
955         if (logger.isDebugEnabled()) {
956             logger.debug("Cleaning up temporary resources created for testing ...");
957         }
958         // Clean up vocabulary item resources.
959         String vocabularyResourceId;
960         String vocabularyItemResourceId;
961         for (Map.Entry<String, String> entry : allResourceItemIdsCreated.entrySet()) {
962             vocabularyItemResourceId = entry.getKey();
963             vocabularyResourceId = entry.getValue();
964             // Note: Any non-success responses are ignored and not reported.
965             ClientResponse<Response> res =
966                 client.deleteItem(vocabularyResourceId, vocabularyItemResourceId);
967         }
968         // Clean up vocabulary resources.
969         for (String resourceId : allResourceIdsCreated) {
970             // Note: Any non-success responses are ignored and not reported.
971             ClientResponse<Response> res = client.delete(resourceId);
972         }
973
974     }
975
976     // ---------------------------------------------------------------
977     // Utility methods used by tests above
978     // ---------------------------------------------------------------
979     @Override
980     public String getServicePathComponent() {
981         return SERVICE_PATH_COMPONENT;
982     }
983
984     public String getItemServicePathComponent() {
985         return ITEM_SERVICE_PATH_COMPONENT;
986     }
987
988     /**
989      * Returns the root URL for a service.
990      *
991      * This URL consists of a base URL for all services, followed by
992      * a path component for the owning vocabulary, followed by the 
993      * path component for the items.
994      *
995      * @return The root URL for a service.
996      */
997     protected String getItemServiceRootURL(String parentResourceIdentifier) {
998         return getResourceURL(parentResourceIdentifier) + "/" + getItemServicePathComponent();
999     }
1000
1001     /**
1002      * Returns the URL of a specific resource managed by a service, and
1003      * designated by an identifier (such as a universally unique ID, or UUID).
1004      *
1005      * @param  resourceIdentifier  An identifier (such as a UUID) for a resource.
1006      *
1007      * @return The URL of a specific resource managed by a service.
1008      */
1009     protected String getItemResourceURL(String parentResourceIdentifier, String resourceIdentifier) {
1010         return getItemServiceRootURL(parentResourceIdentifier) + "/" + resourceIdentifier;
1011     }
1012
1013     private MultipartOutput createVocabularyInstance(String identifier) {
1014         String displayName = "displayName-" + identifier;
1015         String refName = createRefName(displayName);
1016         String typeName = "vocabType-" + identifier;
1017         return createVocabularyInstance(
1018                 displayName, refName,typeName );
1019     }
1020
1021     private MultipartOutput createVocabularyInstance(
1022                 String displayName, String refName, String vocabType) {
1023         VocabulariesCommon vocabulary = new VocabulariesCommon();
1024         vocabulary.setDisplayName(displayName);
1025         if(refName!=null)
1026             vocabulary.setRefName(refName);
1027         vocabulary.setVocabType(vocabType);
1028         MultipartOutput multipart = new MultipartOutput();
1029         OutputPart commonPart = multipart.addPart(vocabulary, MediaType.APPLICATION_XML_TYPE);
1030         commonPart.getHeaders().add("label", client.getCommonPartName());
1031
1032         if(logger.isDebugEnabled()) {
1033             logger.debug("to be created, vocabulary common");
1034             logger.debug(objectAsXmlString(vocabulary, VocabulariesCommon.class));
1035         }
1036         return multipart;
1037     }
1038
1039     private MultipartOutput createVocabularyItemInstance(String inVocabulary,
1040         String displayName, String refName) {
1041         VocabularyitemsCommon vocabularyItem = new VocabularyitemsCommon();
1042         vocabularyItem.setDisplayName(displayName);
1043         if(refName!=null)
1044                 vocabularyItem.setRefName(refName);
1045         MultipartOutput multipart = new MultipartOutput();
1046         OutputPart commonPart = multipart.addPart(vocabularyItem,
1047             MediaType.APPLICATION_XML_TYPE);
1048         commonPart.getHeaders().add("label", client.getItemCommonPartName());
1049
1050         if(logger.isDebugEnabled()){
1051             logger.debug("to be created, vocabularyitem common");
1052             logger.debug(objectAsXmlString(vocabularyItem,
1053                 VocabularyitemsCommon.class));
1054         }
1055
1056         return multipart;
1057     }
1058 }