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