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