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