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