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