]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
3c4d389cd0ac41a6706055cd41c5dc22e5048082
[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
30 import javax.ws.rs.core.MediaType;
31 import javax.ws.rs.core.MultivaluedMap;
32 import javax.ws.rs.core.Response;
33
34 import org.collectionspace.services.client.ContactClient;
35 import org.collectionspace.services.client.ContactClientUtils;
36 import org.collectionspace.services.contact.ContactsCommon;
37 import org.collectionspace.services.contact.ContactsCommonList;
38 import org.collectionspace.services.PersonJAXBSchema;
39 import org.collectionspace.services.client.PersonAuthorityClient;
40 import org.collectionspace.services.client.PersonAuthorityClientUtils;
41 import org.collectionspace.services.person.PersonauthoritiesCommon;
42 import org.collectionspace.services.person.PersonauthoritiesCommonList;
43 import org.collectionspace.services.person.PersonsCommon;
44 import org.collectionspace.services.person.PersonsCommonList;
45 import org.jboss.resteasy.client.ClientResponse;
46 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
47 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
48 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.testng.Assert;
52 import org.testng.annotations.AfterClass;
53 import org.testng.annotations.Test;
54
55 /**
56  * PersonAuthorityServiceTest, carries out tests against a
57  * deployed and running PersonAuthority Service.
58  *
59  * $LastChangedRevision: 753 $
60  * $LastChangedDate: 2009-09-23 11:03:36 -0700 (Wed, 23 Sep 2009) $
61  */
62 public class PersonAuthorityServiceTest extends AbstractServiceTestImpl {
63
64     private final Logger logger =
65         LoggerFactory.getLogger(PersonAuthorityServiceTest.class);
66
67     // Instance variables specific to this test.
68     private PersonAuthorityClient client = new PersonAuthorityClient();
69     private ContactClient contactClient = new ContactClient();
70     final String SERVICE_PATH_COMPONENT = "personauthorities";
71     final String ITEM_SERVICE_PATH_COMPONENT = "items";
72     final String TEST_FORE_NAME = "John";
73     final String TEST_MIDDLE_NAME = null;
74     final String TEST_SUR_NAME = "Wayne";
75     final String TEST_BIRTH_DATE = "May 26, 1907";
76     final String TEST_DEATH_DATE = "June 11, 1979";
77  
78     private String knownResourceId = null;
79     private String lastPersonAuthId = null;
80     private String knownResourceRefName = null;
81     private String knownItemResourceId = null;
82     private String knownContactResourceId = null;
83     private int nItemsToCreateInList = 3;
84     private List<String> allResourceIdsCreated = new ArrayList<String>();
85     private Map<String, String> allResourceItemIdsCreated =
86         new HashMap<String, String>();
87     
88     // ---------------------------------------------------------------
89     // CRUD tests : CREATE tests
90     // ---------------------------------------------------------------
91     // Success outcomes
92     @Override
93     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class)
94     public void create(String testName) throws Exception {
95
96         // Perform setup, such as initializing the type of service request
97         // (e.g. CREATE, DELETE), its valid and expected status codes, and
98         // its associated HTTP method name (e.g. POST, DELETE).
99         setupCreate(testName);
100
101         // Submit the request to the service and store the response.
102         String identifier = createIdentifier();
103         String displayName = "displayName-" + identifier;
104         String baseRefName = PersonAuthorityClientUtils.createPersonAuthRefName(displayName, false);
105         String fullRefName = PersonAuthorityClientUtils.createPersonAuthRefName(displayName, true);
106         MultipartOutput multipart = 
107                 PersonAuthorityClientUtils.createPersonAuthorityInstance(
108                                 displayName, fullRefName, client.getCommonPartName());
109         ClientResponse<Response> res = client.create(multipart);
110         int statusCode = res.getStatus();
111
112         // Check the status code of the response: does it match
113         // the expected response(s)?
114         //
115         // Specifically:
116         // Does it fall within the set of valid status codes?
117         // Does it exactly match the expected status code?
118         if(logger.isDebugEnabled()){
119             logger.debug(testName + ": status = " + statusCode);
120         }
121         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
122                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
123         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
124
125         // Store the refname from the first resource created
126         // for additional tests below.
127         knownResourceRefName = baseRefName;
128
129         lastPersonAuthId = PersonAuthorityClientUtils.extractId(res);
130         // Store the ID returned from the first resource created
131         // for additional tests below.
132         if (knownResourceId == null){
133             knownResourceId = lastPersonAuthId;
134             if (logger.isDebugEnabled()) {
135                 logger.debug(testName + ": knownResourceId=" + knownResourceId);
136             }
137         }
138         // Store the IDs from every resource created by tests,
139         // so they can be deleted after tests have been run.
140         allResourceIdsCreated.add(lastPersonAuthId);
141
142     }
143
144     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
145         dependsOnMethods = {"create"})
146     public void createItem(String testName) {
147         setupCreate(testName);
148
149         knownItemResourceId = createItemInAuthority(lastPersonAuthId, knownResourceRefName);
150         if(logger.isDebugEnabled()){
151             logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
152         }
153     }
154
155     private String createItemInAuthority(String vcsid, String authRefName) {
156
157         final String testName = "createItemInAuthority";
158         if(logger.isDebugEnabled()){
159             logger.debug(testName + ":...");
160         }
161
162         // Submit the request to the service and store the response.
163         String identifier = createIdentifier();
164         Map<String, String> johnWayneMap = new HashMap<String,String>();
165         johnWayneMap.put(PersonJAXBSchema.FORE_NAME, TEST_FORE_NAME);
166         johnWayneMap.put(PersonJAXBSchema.SUR_NAME, TEST_SUR_NAME);
167         johnWayneMap.put(PersonJAXBSchema.GENDER, "male");
168         johnWayneMap.put(PersonJAXBSchema.BIRTH_DATE, TEST_BIRTH_DATE);
169         johnWayneMap.put(PersonJAXBSchema.BIRTH_PLACE, "Winterset, Iowa");
170         johnWayneMap.put(PersonJAXBSchema.DEATH_DATE, TEST_DEATH_DATE);
171         johnWayneMap.put(PersonJAXBSchema.BIO_NOTE, "born Marion Robert Morrison and better" +
172                         "known by his stage name John Wayne, was an American film actor, director " +
173                         "and producer. He epitomized rugged masculinity and has become an enduring " +
174                         "American icon. He is famous for his distinctive voice, walk and height. " +
175                         "He was also known for his conservative political views and his support in " +
176                         "the 1950s for anti-communist positions.");
177         String refName = PersonAuthorityClientUtils.createPersonRefName(authRefName, "John Wayne", true);
178         MultipartOutput multipart = 
179                 PersonAuthorityClientUtils.createPersonInstance(vcsid, refName, johnWayneMap,
180                                 client.getItemCommonPartName() );
181         ClientResponse<Response> res = client.createItem(vcsid, multipart);
182         int statusCode = res.getStatus();
183         String extractedID = PersonAuthorityClientUtils.extractId(res);
184
185         // Check the status code of the response: does it match
186         // the expected response(s)?
187         if(logger.isDebugEnabled()){
188             logger.debug(testName + ": status = " + statusCode);
189         }
190         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
191                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
192         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
193
194         
195         // Store the ID returned from the first item resource created
196         // for additional tests below.
197         if (knownItemResourceId == null){
198             knownItemResourceId = extractedID;
199             if (logger.isDebugEnabled()) {
200                 logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
201             }
202         }
203
204         // Store the IDs from any item resources created
205         // by tests, along with the IDs of their parents, so these items
206         // can be deleted after all tests have been run.
207         //
208         // Item resource IDs are unique, so these are used as keys;
209         // the non-unique IDs of their parents are stored as associated values.
210         allResourceItemIdsCreated.put(extractedID, vcsid);
211
212         return extractedID;
213     }
214
215     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
216         dependsOnMethods = {"create", "createItem"})
217     public void createContact(String testName) {
218         setupCreate(testName);
219         knownContactResourceId = createContactInItem(knownResourceId, knownItemResourceId);
220         if(logger.isDebugEnabled()){
221             logger.debug(testName + ": knownContactResourceId=" + knownContactResourceId);
222         }
223     }
224
225    private String createContactInItem(String authorityId, String itemId) {
226
227         final String testName = "createContactInItem";
228         setupCreate(testName);
229         if(logger.isDebugEnabled()){
230             logger.debug(testName + ":...");
231         }
232
233         // Submit the request to the service and store the response.
234         String identifier = createIdentifier();
235         MultipartOutput multipart =
236             ContactClientUtils.createContactInstance(authorityId, itemId, identifier);
237         ClientResponse<Response> res =
238              client.createContact(authorityId, itemId, multipart);
239         int statusCode = res.getStatus();
240         String extractedID = PersonAuthorityClientUtils.extractId(res);
241
242         // Check the status code of the response: does it match
243         // the expected response(s)?
244         if(logger.isDebugEnabled()){
245             logger.debug(testName + ": status = " + statusCode);
246         }
247         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
248                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
249         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
250
251         // Store the ID returned from the first contact resource created
252         // for additional tests below.
253         if (knownContactResourceId == null){
254             knownContactResourceId = extractedID;
255             if (logger.isDebugEnabled()) {
256                 logger.debug(testName + ": knownContactResourceId=" + knownContactResourceId);
257             }
258         }
259
260         // Store the IDs from any item resources created
261         // by tests, along with the IDs of their parents, so these items
262         // can be deleted after all tests have been run.
263         //
264         // Item resource IDs are unique, so these are used as keys;
265         // the non-unique IDs of their parents are stored as associated values.
266         allResourceItemIdsCreated.put(extractedID, knownContactResourceId);
267
268         return extractedID;
269     }
270
271     @Override
272     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
273             dependsOnMethods = {"create", "createItem"})
274     public void createList(String testName) throws Exception {
275         for (int i = 0; i < 3; i++) {
276             create(testName);
277             knownResourceId = lastPersonAuthId;
278             if (logger.isDebugEnabled()) {
279                 logger.debug(testName + ": Resetting knownResourceId to" + knownResourceId);
280             }
281             // Add nItemsToCreateInList items to each personauthority
282             for (int j = 0; j < nItemsToCreateInList; j++) {
283                 createItem(testName);
284             }
285         }
286     }
287
288     // Failure outcomes
289     // Placeholders until the three tests below can be uncommented.
290     // See Issue CSPACE-401.
291     @Override
292     public void createWithEmptyEntityBody(String testName) throws Exception {
293     }
294
295     @Override
296     public void createWithMalformedXml(String testName) throws Exception {
297     }
298
299     @Override
300     public void createWithWrongXmlSchema(String testName) throws Exception {
301     }
302
303     /*
304     @Override
305     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
306         dependsOnMethods = {"create", "testSubmitRequest"})
307     public void createWithEmptyEntityBody(String testName) throws Exception {
308
309     // Perform setup.
310     setupCreateWithEmptyEntityBody(testName);
311
312     // Submit the request to the service and store the response.
313     String method = REQUEST_TYPE.httpMethodName();
314     String url = getServiceRootURL();
315     String mediaType = MediaType.APPLICATION_XML;
316     final String entity = "";
317     int statusCode = submitRequest(method, url, mediaType, entity);
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 + ": url=" + url +
323             " status=" + statusCode);
324      }
325     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
326     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
327     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
328     }
329
330     @Override
331     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
332         dependsOnMethods = {"create", "testSubmitRequest"})
333     public void createWithMalformedXml(String testName) throws Exception {
334
335     // Perform setup.
336     setupCreateWithMalformedXml(testName);
337
338     // Submit the request to the service and store the response.
339     String method = REQUEST_TYPE.httpMethodName();
340     String url = getServiceRootURL();
341     String mediaType = MediaType.APPLICATION_XML;
342     final String entity = MALFORMED_XML_DATA; // Constant from base class.
343     int statusCode = submitRequest(method, url, mediaType, entity);
344
345     // Check the status code of the response: does it match
346     // the expected response(s)?
347     if(logger.isDebugEnabled()){
348         logger.debug(testName + ": url=" + url +
349             " status=" + statusCode);
350      }
351     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
352     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
353     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
354     }
355
356     @Override
357     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
358         dependsOnMethods = {"create", "testSubmitRequest"})
359     public void createWithWrongXmlSchema(String testName) throws Exception {
360
361     // Perform setup.
362     setupCreateWithWrongXmlSchema(testName);
363
364     // Submit the request to the service and store the response.
365     String method = REQUEST_TYPE.httpMethodName();
366     String url = getServiceRootURL();
367     String mediaType = MediaType.APPLICATION_XML;
368     final String entity = WRONG_XML_SCHEMA_DATA;
369     int statusCode = submitRequest(method, url, mediaType, entity);
370
371     // Check the status code of the response: does it match
372     // the expected response(s)?
373     if(logger.isDebugEnabled()){
374         logger.debug(testName + ": url=" + url +
375             " status=" + statusCode);
376      }
377     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
378     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
379     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
380     }
381      */
382
383     // ---------------------------------------------------------------
384     // CRUD tests : READ tests
385     // ---------------------------------------------------------------
386     // Success outcomes
387     @Override
388     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
389         dependsOnMethods = {"create"})
390     public void read(String testName) throws Exception {
391
392         // Perform setup.
393         setupRead();
394
395         // Submit the request to the service and store the response.
396         ClientResponse<MultipartInput> res = client.read(knownResourceId);
397         int statusCode = res.getStatus();
398
399         // Check the status code of the response: does it match
400         // the expected response(s)?
401         if(logger.isDebugEnabled()){
402             logger.debug(testName + ": status = " + statusCode);
403         }
404         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
405                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
406         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
407         //FIXME: remove the following try catch once Aron fixes signatures
408         try {
409             MultipartInput input = (MultipartInput) res.getEntity();
410             PersonauthoritiesCommon personAuthority = (PersonauthoritiesCommon) extractPart(input,
411                     client.getCommonPartName(), PersonauthoritiesCommon.class);
412             Assert.assertNotNull(personAuthority);
413         } catch (Exception e) {
414             throw new RuntimeException(e);
415         }
416     }
417
418     /*
419     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
420             dependsOnMethods = {"read"})
421         public void readByName(String testName) throws Exception {
422
423             // Perform setup.
424             setupRead();
425
426             // Submit the request to the service and store the response.
427             ClientResponse<MultipartInput> res = client.read(knownResourceId);
428             int statusCode = res.getStatus();
429
430             // Check the status code of the response: does it match
431             // the expected response(s)?
432             if(logger.isDebugEnabled()){
433                 logger.debug(testName + ": status = " + statusCode);
434             }
435             Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
436                     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
437             Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
438             //FIXME: remove the following try catch once Aron fixes signatures
439             try {
440                 MultipartInput input = (MultipartInput) res.getEntity();
441                 PersonauthoritiesCommon personAuthority = (PersonauthoritiesCommon) extractPart(input,
442                         client.getCommonPartName(), PersonauthoritiesCommon.class);
443                 Assert.assertNotNull(personAuthority);
444             } catch (Exception e) {
445                 throw new RuntimeException(e);
446             }
447         }
448     */
449
450     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
451         dependsOnMethods = {"createItem", "read"})
452     public void readItem(String testName) throws Exception {
453
454         // Perform setup.
455         setupRead(testName);
456
457         // Submit the request to the service and store the response.
458         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, knownItemResourceId);
459         int statusCode = res.getStatus();
460
461         // Check the status code of the response: does it match
462         // the expected response(s)?
463         if(logger.isDebugEnabled()){
464             logger.debug(testName + ": status = " + statusCode);
465         }
466         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
467                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
468         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
469
470         // Check whether we've received a person.
471         MultipartInput input = (MultipartInput) res.getEntity();
472         PersonsCommon person = (PersonsCommon) extractPart(input,
473                 client.getItemCommonPartName(), PersonsCommon.class);
474         Assert.assertNotNull(person);
475         boolean showFull = true;
476         if(showFull && logger.isDebugEnabled()){
477             logger.debug(testName + ": returned payload:");
478             logger.debug(objectAsXmlString(person, PersonsCommon.class));
479         }
480         Assert.assertEquals(person.getInAuthority(), knownResourceId);
481
482     }
483
484     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
485             dependsOnMethods = {"readItem", "updateItem"})
486     public void verifyItemDisplayName(String testName) throws Exception {
487
488         // Perform setup.
489         setupUpdate(testName);
490
491         // Submit the request to the service and store the response.
492         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, knownItemResourceId);
493         int statusCode = res.getStatus();
494
495         // Check the status code of the response: does it match
496         // the expected response(s)?
497         if(logger.isDebugEnabled()){
498             logger.debug(testName + ": status = " + statusCode);
499         }
500         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
501                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
502         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
503
504         // Check whether person has expected displayName.
505         MultipartInput input = (MultipartInput) res.getEntity();
506         PersonsCommon person = (PersonsCommon) extractPart(input,
507                 client.getItemCommonPartName(), PersonsCommon.class);
508         Assert.assertNotNull(person);
509         String displayName = person.getDisplayName();
510         // Make sure displayName matches computed form
511         String expectedDisplayName = 
512                 PersonAuthorityClientUtils.prepareDefaultDisplayName(
513                                                 TEST_FORE_NAME, null, TEST_SUR_NAME, 
514                                                 TEST_BIRTH_DATE, TEST_DEATH_DATE);
515         Assert.assertNotNull(displayName, expectedDisplayName);
516         
517         // Update the shortName and verify the computed name is updated.
518         person.setDisplayNameComputed(true);
519         person.setForeName("updated-" + TEST_FORE_NAME);
520         expectedDisplayName = 
521                 PersonAuthorityClientUtils.prepareDefaultDisplayName(
522                                 "updated-" + TEST_FORE_NAME, null, TEST_SUR_NAME, 
523                                 TEST_BIRTH_DATE, TEST_DEATH_DATE);
524
525         // Submit the updated resource to the service and store the response.
526         MultipartOutput output = new MultipartOutput();
527         OutputPart commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE);
528         commonPart.getHeaders().add("label", client.getItemCommonPartName());
529         res = client.updateItem(knownResourceId, knownItemResourceId, output);
530         statusCode = res.getStatus();
531
532         // Check the status code of the response: does it match the expected response(s)?
533         if(logger.isDebugEnabled()){
534             logger.debug("updateItem: status = " + statusCode);
535         }
536         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
537                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
538         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
539
540         // Retrieve the updated resource and verify that its contents exist.
541         input = (MultipartInput) res.getEntity();
542         PersonsCommon updatedPerson =
543                 (PersonsCommon) extractPart(input,
544                         client.getItemCommonPartName(), PersonsCommon.class);
545         Assert.assertNotNull(updatedPerson);
546
547         // Verify that the updated resource received the correct data.
548         Assert.assertEquals(updatedPerson.getForeName(),
549                 person.getForeName(),
550                 "Updated ForeName in Person did not match submitted data.");
551         // Verify that the updated resource computes the right displayName.
552         Assert.assertEquals(updatedPerson.getDisplayName(),
553                         expectedDisplayName,
554                 "Updated ForeName in Person not reflected in computed DisplayName.");
555
556         // Now Update the displayName, not computed and verify the computed name is overriden.
557         person.setDisplayNameComputed(false);
558         expectedDisplayName = "TestName";
559         person.setDisplayName(expectedDisplayName);
560
561         // Submit the updated resource to the service and store the response.
562         output = new MultipartOutput();
563         commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE);
564         commonPart.getHeaders().add("label", client.getItemCommonPartName());
565         res = client.updateItem(knownResourceId, knownItemResourceId, output);
566         statusCode = res.getStatus();
567
568         // Check the status code of the response: does it match the expected response(s)?
569         if(logger.isDebugEnabled()){
570             logger.debug("updateItem: status = " + statusCode);
571         }
572         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
573                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
574         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
575
576         // Retrieve the updated resource and verify that its contents exist.
577         input = (MultipartInput) res.getEntity();
578         updatedPerson =
579                 (PersonsCommon) extractPart(input,
580                         client.getItemCommonPartName(), PersonsCommon.class);
581         Assert.assertNotNull(updatedPerson);
582
583         // Verify that the updated resource received the correct data.
584         Assert.assertEquals(updatedPerson.isDisplayNameComputed(), false,
585                 "Updated displayNameComputed in Person did not match submitted data.");
586         // Verify that the updated resource computes the right displayName.
587         Assert.assertEquals(updatedPerson.getDisplayName(),
588                         expectedDisplayName,
589                 "Updated DisplayName (not computed) in Person not stored.");
590     }
591
592     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
593             dependsOnMethods = {"verifyItemDisplayName"})
594     public void verifyIllegalItemDisplayName(String testName) throws Exception {
595
596         // Perform setup.
597         setupUpdateWithWrongXmlSchema(testName);
598
599         // Submit the request to the service and store the response.
600         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, knownItemResourceId);
601         int statusCode = res.getStatus();
602
603         // Check the status code of the response: does it match
604         // the expected response(s)?
605         if(logger.isDebugEnabled()){
606             logger.debug(testName + ": status = " + statusCode);
607         }
608         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
609                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
610         Assert.assertEquals(statusCode, Response.Status.OK.getStatusCode());
611
612         // Check whether Person has expected displayName.
613         MultipartInput input = (MultipartInput) res.getEntity();
614         PersonsCommon person = (PersonsCommon) extractPart(input,
615                 client.getItemCommonPartName(), PersonsCommon.class);
616         Assert.assertNotNull(person);
617         // Try to Update with computed false and no displayName
618         person.setDisplayNameComputed(false);
619         person.setDisplayName(null);
620
621         // Submit the updated resource to the service and store the response.
622         MultipartOutput output = new MultipartOutput();
623         OutputPart commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE);
624         commonPart.getHeaders().add("label", client.getItemCommonPartName());
625         res = client.updateItem(knownResourceId, knownItemResourceId, output);
626         statusCode = res.getStatus();
627
628         // Check the status code of the response: does it match the expected response(s)?
629         if(logger.isDebugEnabled()){
630             logger.debug("updateItem: status = " + statusCode);
631         }
632         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
633                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
634         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
635     }
636     
637     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
638         dependsOnMethods = {"create", "createItem",
639         "createContact", "read", "readItem"})
640     public void readContact(String testName) throws Exception {
641
642         // Perform setup.
643         setupRead(testName);
644
645         // Submit the request to the service and store the response.
646         ClientResponse<MultipartInput> res =
647             client.readContact(knownResourceId, knownItemResourceId,
648             knownContactResourceId);
649         int statusCode = res.getStatus();
650
651         // Check the status code of the response: does it match
652         // the expected response(s)?
653         if(logger.isDebugEnabled()){
654             logger.debug(testName + ": status = " + statusCode);
655         }
656         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
657                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
658         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
659
660         // Check whether we've received a contact.
661         MultipartInput input = (MultipartInput) res.getEntity();
662         ContactsCommon contact = (ContactsCommon) extractPart(input,
663                 contactClient.getCommonPartName(), ContactsCommon.class);
664         Assert.assertNotNull(contact);
665         boolean showFull = true;
666         if(showFull && logger.isDebugEnabled()){
667             logger.debug(testName + ": returned payload:");
668             logger.debug(objectAsXmlString(contact, ContactsCommon.class));
669         }
670         Assert.assertEquals(contact.getInAuthority(), knownResourceId);
671         Assert.assertEquals(contact.getInItem(), knownItemResourceId);
672
673     }
674
675     // Failure outcomes
676     @Override
677     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
678         dependsOnMethods = {"read"})
679     public void readNonExistent(String testName) {
680
681         // Perform setup.
682         setupReadNonExistent(testName);
683
684         // Submit the request to the service and store the response.
685         ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
686         int statusCode = res.getStatus();
687
688         // Check the status code of the response: does it match
689         // the expected response(s)?
690         if(logger.isDebugEnabled()){
691             logger.debug(testName + ": status = " + statusCode);
692         }
693         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
694                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
695         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
696     }
697
698     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
699         dependsOnMethods = {"readItem", "readNonExistent"})
700     public void readItemNonExistent(String testName) {
701
702         // Perform setup.
703         setupReadNonExistent(testName);
704
705         // Submit the request to the service and store the response.
706         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, NON_EXISTENT_ID);
707         int statusCode = res.getStatus();
708
709         // Check the status code of the response: does it match
710         // the expected response(s)?
711         if(logger.isDebugEnabled()){
712             logger.debug(testName + ": status = " + statusCode);
713         }
714         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
715                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
716         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
717     }
718
719     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
720         dependsOnMethods = {"readContact", "readNonExistent", "readItemNonExistent"})
721     public void readContactNonExistent(String testName) {
722
723         // Perform setup.
724         setupReadNonExistent(testName);
725
726         // Submit the request to the service and store the response.
727         ClientResponse<MultipartInput> res =
728             client.readContact(knownResourceId, knownItemResourceId, NON_EXISTENT_ID);
729         int statusCode = res.getStatus();
730
731         // Check the status code of the response: does it match
732         // the expected response(s)?
733         if(logger.isDebugEnabled()){
734             logger.debug(testName + ": status = " + statusCode);
735         }
736         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
737                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
738         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
739     }
740
741     // ---------------------------------------------------------------
742     // CRUD tests : READ_LIST tests
743     // ---------------------------------------------------------------
744     // Success outcomes
745
746     @Override
747     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
748         dependsOnMethods = {"createList", "read"})
749     public void readList(String testName) throws Exception {
750
751         // Perform setup.
752         setupReadList(testName);
753
754         // Submit the request to the service and store the response.
755         ClientResponse<PersonauthoritiesCommonList> res = client.readList();
756         PersonauthoritiesCommonList list = res.getEntity();
757         int statusCode = res.getStatus();
758
759         // Check the status code of the response: does it match
760         // the expected response(s)?
761         if(logger.isDebugEnabled()){
762             logger.debug(testName + ": status = " + statusCode);
763         }
764         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
765                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
766         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
767
768         // Optionally output additional data about list members for debugging.
769         boolean iterateThroughList = false;
770         if (iterateThroughList && logger.isDebugEnabled()) {
771             List<PersonauthoritiesCommonList.PersonauthorityListItem> items =
772                     list.getPersonauthorityListItem();
773             int i = 0;
774             for (PersonauthoritiesCommonList.PersonauthorityListItem item : items) {
775                 String csid = item.getCsid();
776                 logger.debug(testName + ": list-item[" + i + "] csid=" +
777                         csid);
778                 logger.debug(testName + ": list-item[" + i + "] displayName=" +
779                         item.getDisplayName());
780                 logger.debug(testName + ": list-item[" + i + "] URI=" +
781                         item.getUri());
782                 readItemList(csid);
783                 i++;
784             }
785         }
786     }
787
788     @Test(dependsOnMethods = {"createList", "readItem"})
789     public void readItemList() {
790         readItemList(knownResourceId);
791     }
792
793     private void readItemList(String vcsid) {
794
795         final String testName = "readItemList";
796
797         // Perform setup.
798         setupReadList(testName);
799
800         // Submit the request to the service and store the response.
801         ClientResponse<PersonsCommonList> res =
802                 client.readItemList(vcsid);
803         PersonsCommonList list = res.getEntity();
804         int statusCode = res.getStatus();
805
806         // Check the status code of the response: does it match
807         // the expected response(s)?
808         if(logger.isDebugEnabled()){
809             logger.debug("  " + testName + ": status = " + statusCode);
810         }
811         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
812                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
813         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
814
815         List<PersonsCommonList.PersonListItem> items =
816             list.getPersonListItem();
817         int nItemsReturned = items.size();
818         if(logger.isDebugEnabled()){
819             logger.debug("  " + testName + ": Expected "
820                         + nItemsToCreateInList+" items; got: "+nItemsReturned);
821         }
822         Assert.assertEquals( nItemsReturned, nItemsToCreateInList);
823
824         int i = 0;
825         for (PersonsCommonList.PersonListItem item : items) {
826                 Assert.assertTrue((null != item.getRefName()), "Item refName is null!");
827                 Assert.assertTrue((null != item.getDisplayName()), "Item displayName is null!");
828                 // Optionally output additional data about list members for debugging.
829                 boolean showDetails = true;
830                 if (showDetails && logger.isDebugEnabled()) {
831                 logger.debug("  " + testName + ": list-item[" + i + "] csid=" +
832                         item.getCsid());
833                 logger.debug("  " + testName + ": list-item[" + i + "] displayName=" +
834                         item.getDisplayName());
835                 logger.debug("  " + testName + ": list-item[" + i + "] URI=" +
836                         item.getUri());
837             }
838             i++;
839         }
840     }
841
842     // Failure outcomes
843     // None at present.
844     // ---------------------------------------------------------------
845     // CRUD tests : UPDATE tests
846     // ---------------------------------------------------------------
847     // Success outcomes
848     @Override
849     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
850         dependsOnMethods = {"read"})
851     public void update(String testName) throws Exception {
852
853         // Perform setup.
854         setupUpdate(testName);
855
856         // Retrieve the contents of a resource to update.
857         ClientResponse<MultipartInput> res =
858                 client.read(knownResourceId);
859         if(logger.isDebugEnabled()){
860             logger.debug(testName + ": read status = " + res.getStatus());
861         }
862         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
863
864         if(logger.isDebugEnabled()){
865             logger.debug("got PersonAuthority to update with ID: " + knownResourceId);
866         }
867         MultipartInput input = (MultipartInput) res.getEntity();
868         PersonauthoritiesCommon personAuthority = (PersonauthoritiesCommon) extractPart(input,
869                 client.getCommonPartName(), PersonauthoritiesCommon.class);
870         Assert.assertNotNull(personAuthority);
871
872         // Update the contents of this resource.
873         personAuthority.setDisplayName("updated-" + personAuthority.getDisplayName());
874         personAuthority.setVocabType("updated-" + personAuthority.getVocabType());
875         if(logger.isDebugEnabled()){
876             logger.debug("to be updated PersonAuthority");
877             logger.debug(objectAsXmlString(personAuthority, PersonauthoritiesCommon.class));
878         }
879
880         // Submit the updated resource to the service and store the response.
881         MultipartOutput output = new MultipartOutput();
882         OutputPart commonPart = output.addPart(personAuthority, MediaType.APPLICATION_XML_TYPE);
883         commonPart.getHeaders().add("label", client.getCommonPartName());
884         res = client.update(knownResourceId, output);
885         int statusCode = res.getStatus();
886
887         // Check the status code of the response: does it match the expected response(s)?
888         if(logger.isDebugEnabled()){
889             logger.debug("update: status = " + statusCode);
890         }
891         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
892                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
893         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
894
895         // Retrieve the updated resource and verify that its contents exist.
896         input = (MultipartInput) res.getEntity();
897         PersonauthoritiesCommon updatedPersonAuthority =
898                 (PersonauthoritiesCommon) extractPart(input,
899                         client.getCommonPartName(), PersonauthoritiesCommon.class);
900         Assert.assertNotNull(updatedPersonAuthority);
901
902         // Verify that the updated resource received the correct data.
903         Assert.assertEquals(updatedPersonAuthority.getDisplayName(),
904                 personAuthority.getDisplayName(),
905                 "Data in updated object did not match submitted data.");
906     }
907
908     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
909         dependsOnMethods = {"readItem", "update"})
910     public void updateItem(String testName) throws Exception {
911
912         // Perform setup.
913         setupUpdate(testName);
914
915         ClientResponse<MultipartInput> res =
916                 client.readItem(knownResourceId, knownItemResourceId);
917         if(logger.isDebugEnabled()){
918             logger.debug(testName + ": read status = " + res.getStatus());
919         }
920         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
921
922         if(logger.isDebugEnabled()){
923             logger.debug("got Person to update with ID: " +
924                 knownItemResourceId +
925                 " in PersonAuthority: " + knownResourceId );
926         }
927         MultipartInput input = (MultipartInput) res.getEntity();
928         PersonsCommon person = (PersonsCommon) extractPart(input,
929                 client.getItemCommonPartName(), PersonsCommon.class);
930         Assert.assertNotNull(person);
931
932         // Update the contents of this resource.
933         person.setForeName("updated-" + person.getForeName());
934         if(logger.isDebugEnabled()){
935             logger.debug("to be updated Person");
936             logger.debug(objectAsXmlString(person,
937                 PersonsCommon.class));
938         }
939
940         // Submit the updated resource to the service and store the response.
941         MultipartOutput output = new MultipartOutput();
942         OutputPart commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE);
943         commonPart.getHeaders().add("label", client.getItemCommonPartName());
944         res = client.updateItem(knownResourceId, knownItemResourceId, output);
945         int statusCode = res.getStatus();
946
947         // Check the status code of the response: does it match the expected response(s)?
948         if(logger.isDebugEnabled()){
949             logger.debug("updateItem: status = " + statusCode);
950         }
951         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
952                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
953         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
954
955         // Retrieve the updated resource and verify that its contents exist.
956         input = (MultipartInput) res.getEntity();
957         PersonsCommon updatedPerson =
958                 (PersonsCommon) extractPart(input,
959                         client.getItemCommonPartName(), PersonsCommon.class);
960         Assert.assertNotNull(updatedPerson);
961
962         // Verify that the updated resource received the correct data.
963         Assert.assertEquals(updatedPerson.getForeName(),
964                 person.getForeName(),
965                 "Data in updated Person did not match submitted data.");
966     }
967
968     // Failure outcomes
969     // Placeholders until the three tests below can be uncommented.
970     // See Issue CSPACE-401.
971     @Override
972     public void updateWithEmptyEntityBody(String testName) throws Exception {
973     }
974
975     @Override
976     public void updateWithMalformedXml(String testName) throws Exception {
977     }
978
979     @Override
980     public void updateWithWrongXmlSchema(String testName) throws Exception {
981     }
982
983     /*
984     @Override
985     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
986         dependsOnMethods = {"create", "update", "testSubmitRequest"})
987     public void updateWithEmptyEntityBody(String testName) throws Exception {
988
989     // Perform setup.
990     setupUpdateWithEmptyEntityBody(testName);
991
992     // Submit the request to the service and store the response.
993     String method = REQUEST_TYPE.httpMethodName();
994     String url = getResourceURL(knownResourceId);
995     String mediaType = MediaType.APPLICATION_XML;
996     final String entity = "";
997     int statusCode = submitRequest(method, url, mediaType, entity);
998
999     // Check the status code of the response: does it match
1000     // the expected response(s)?
1001     if(logger.isDebugEnabled()){
1002         logger.debug(testName + ": url=" + url +
1003             " status=" + statusCode);
1004      }
1005     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1006     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1007     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1008     }
1009
1010     @Override
1011     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
1012         dependsOnMethods = {"create", "update", "testSubmitRequest"})
1013     public void updateWithMalformedXml(String testName) throws Exception {
1014
1015     // Perform setup.
1016     setupUpdateWithMalformedXml(testName);
1017
1018     // Submit the request to the service and store the response.
1019     String method = REQUEST_TYPE.httpMethodName();
1020     String url = getResourceURL(knownResourceId);
1021     String mediaType = MediaType.APPLICATION_XML;
1022     final String entity = MALFORMED_XML_DATA;
1023     int statusCode = submitRequest(method, url, mediaType, entity);
1024
1025     // Check the status code of the response: does it match
1026     // the expected response(s)?
1027     if(logger.isDebugEnabled()){
1028         logger.debug(testName + ": url=" + url +
1029            " status=" + statusCode);
1030      }
1031     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1032     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1033     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1034     }
1035
1036     @Override
1037     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
1038         dependsOnMethods = {"create", "update", "testSubmitRequest"})
1039     public void updateWithWrongXmlSchema(String testName) throws Exception {
1040
1041     // Perform setup.
1042     setupUpdateWithWrongXmlSchema(testName);
1043
1044     // Submit the request to the service and store the response.
1045     String method = REQUEST_TYPE.httpMethodName();
1046     String url = getResourceURL(knownResourceId);
1047     String mediaType = MediaType.APPLICATION_XML;
1048     final String entity = WRONG_XML_SCHEMA_DATA;
1049     int statusCode = submitRequest(method, url, mediaType, entity);
1050
1051     // Check the status code of the response: does it match
1052     // the expected response(s)?
1053     if(logger.isDebugEnabled()){
1054         logger.debug("updateWithWrongXmlSchema: url=" + url +
1055             " status=" + statusCode);
1056      }
1057     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1058     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1059     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1060     }
1061      */
1062
1063
1064     @Override
1065     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1066         dependsOnMethods = {"update", "testSubmitRequest"})
1067     public void updateNonExistent(String testName) throws Exception {
1068
1069         // Perform setup.
1070         setupUpdateNonExistent(testName);
1071
1072         // Submit the request to the service and store the response.
1073         // Note: The ID used in this 'create' call may be arbitrary.
1074         // The only relevant ID may be the one used in update(), below.
1075
1076         // The only relevant ID may be the one used in update(), below.
1077         String displayName = "displayName-NON_EXISTENT_ID";
1078         String fullRefName = PersonAuthorityClientUtils.createPersonAuthRefName(displayName, true);
1079         MultipartOutput multipart = PersonAuthorityClientUtils.createPersonAuthorityInstance(
1080                                 displayName, fullRefName, client.getCommonPartName());
1081         ClientResponse<MultipartInput> res =
1082                 client.update(NON_EXISTENT_ID, multipart);
1083         int statusCode = res.getStatus();
1084
1085         // Check the status code of the response: does it match
1086         // the expected response(s)?
1087         if(logger.isDebugEnabled()){
1088             logger.debug(testName + ": status = " + statusCode);
1089         }
1090         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1091                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1092         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1093     }
1094
1095     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1096         dependsOnMethods = {"updateItem", "testItemSubmitRequest"})
1097     public void updateNonExistentItem(String testName) throws Exception {
1098
1099         // Perform setup.
1100         setupUpdateNonExistent(testName);
1101
1102         // Submit the request to the service and store the response.
1103         // Note: The ID used in this 'create' call may be arbitrary.
1104         // The only relevant ID may be the one used in update(), below.
1105
1106         // The only relevant ID may be the one used in update(), below.
1107         Map<String, String> nonexMap = new HashMap<String,String>();
1108         nonexMap.put(PersonJAXBSchema.FORE_NAME, "John");
1109         nonexMap.put(PersonJAXBSchema.SUR_NAME, "Wayne");
1110         nonexMap.put(PersonJAXBSchema.GENDER, "male");
1111         MultipartOutput multipart = 
1112         PersonAuthorityClientUtils.createPersonInstance(NON_EXISTENT_ID, 
1113                         PersonAuthorityClientUtils.createPersonRefName(NON_EXISTENT_ID, NON_EXISTENT_ID, true), nonexMap,
1114                         client.getItemCommonPartName() );
1115         ClientResponse<MultipartInput> res =
1116                 client.updateItem(knownResourceId, NON_EXISTENT_ID, multipart);
1117         int statusCode = res.getStatus();
1118
1119         // Check the status code of the response: does it match
1120         // the expected response(s)?
1121         if(logger.isDebugEnabled()){
1122             logger.debug(testName + ": status = " + statusCode);
1123         }
1124         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1125                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1126         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1127     }
1128
1129     // ---------------------------------------------------------------
1130     // CRUD tests : DELETE tests
1131     // ---------------------------------------------------------------
1132     // Success outcomes
1133     @Override
1134     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1135         dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
1136     public void delete(String testName) throws Exception {
1137
1138         // Perform setup.
1139         setupDelete(testName);
1140
1141         // Submit the request to the service and store the response.
1142         ClientResponse<Response> res = client.delete(knownResourceId);
1143         int statusCode = res.getStatus();
1144
1145         // Check the status code of the response: does it match
1146         // the expected response(s)?
1147         if(logger.isDebugEnabled()){
1148             logger.debug(testName + ": status = " + statusCode);
1149         }
1150         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1151                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1152         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1153     }
1154
1155    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1156         dependsOnMethods = {"createItem", "readItemList", "testItemSubmitRequest",
1157             "updateItem", "verifyIllegalItemDisplayName"})
1158     public void deleteItem(String testName) throws Exception {
1159
1160         // Perform setup.
1161         setupDelete(testName);
1162
1163         // Submit the request to the service and store the response.
1164         ClientResponse<Response> res = client.deleteItem(knownResourceId, knownItemResourceId);
1165         int statusCode = res.getStatus();
1166
1167         // Check the status code of the response: does it match
1168         // the expected response(s)?
1169         if(logger.isDebugEnabled()){
1170             logger.debug("delete: status = " + statusCode);
1171         }
1172         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1173                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1174         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1175     }
1176
1177     // Failure outcomes
1178     @Override
1179     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1180         dependsOnMethods = {"delete"})
1181     public void deleteNonExistent(String testName) throws Exception {
1182
1183         // Perform setup.
1184         setupDeleteNonExistent(testName);
1185
1186         // Submit the request to the service and store the response.
1187         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
1188         int statusCode = res.getStatus();
1189
1190         // Check the status code of the response: does it match
1191         // the expected response(s)?
1192         if(logger.isDebugEnabled()){
1193             logger.debug(testName + ": status = " + statusCode);
1194         }
1195         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1196                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1197         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1198     }
1199
1200     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1201         dependsOnMethods = {"deleteItem"})
1202     public void deleteNonExistentItem(String testName) {
1203
1204         // Perform setup.
1205         setupDeleteNonExistent(testName);
1206
1207         // Submit the request to the service and store the response.
1208         ClientResponse<Response> res = client.deleteItem(knownResourceId, NON_EXISTENT_ID);
1209         int statusCode = res.getStatus();
1210
1211         // Check the status code of the response: does it match
1212         // the expected response(s)?
1213         if(logger.isDebugEnabled()){
1214             logger.debug(testName + ": status = " + statusCode);
1215         }
1216         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1217                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1218         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1219     }
1220
1221     // ---------------------------------------------------------------
1222     // Utility tests : tests of code used in tests above
1223     // ---------------------------------------------------------------
1224     /**
1225      * Tests the code for manually submitting data that is used by several
1226      * of the methods above.
1227      */
1228     @Test(dependsOnMethods = {"create", "read"})
1229     public void testSubmitRequest() {
1230
1231         // Expected status code: 200 OK
1232         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
1233
1234         // Submit the request to the service and store the response.
1235         String method = ServiceRequestType.READ.httpMethodName();
1236         String url = getResourceURL(knownResourceId);
1237         int statusCode = submitRequest(method, url);
1238
1239         // Check the status code of the response: does it match
1240         // the expected response(s)?
1241         if(logger.isDebugEnabled()){
1242             logger.debug("testSubmitRequest: url=" + url +
1243                 " status=" + statusCode);
1244         }
1245         Assert.assertEquals(statusCode, EXPECTED_STATUS);
1246
1247     }
1248
1249     @Test(dependsOnMethods = {"createItem", "readItem", "testSubmitRequest"})
1250     public void testItemSubmitRequest() {
1251
1252         // Expected status code: 200 OK
1253         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
1254
1255         // Submit the request to the service and store the response.
1256         String method = ServiceRequestType.READ.httpMethodName();
1257         String url = getItemResourceURL(knownResourceId, knownItemResourceId);
1258         int statusCode = submitRequest(method, url);
1259
1260         // Check the status code of the response: does it match
1261         // the expected response(s)?
1262         if(logger.isDebugEnabled()){
1263             logger.debug("testItemSubmitRequest: url=" + url +
1264                 " status=" + statusCode);
1265         }
1266         Assert.assertEquals(statusCode, EXPECTED_STATUS);
1267
1268     }
1269
1270     // ---------------------------------------------------------------
1271     // Cleanup of resources created during testing
1272     // ---------------------------------------------------------------
1273     
1274     /**
1275      * Deletes all resources created by tests, after all tests have been run.
1276      *
1277      * This cleanup method will always be run, even if one or more tests fail.
1278      * For this reason, it attempts to remove all resources created
1279      * at any point during testing, even if some of those resources
1280      * may be expected to be deleted by certain tests.
1281      */
1282
1283     @AfterClass(alwaysRun=true)
1284     public void cleanUp() {
1285         if (logger.isDebugEnabled()) {
1286             logger.debug("Cleaning up temporary resources created for testing ...");
1287         }
1288         // Clean up person resources.
1289         String personAuthorityResourceId;
1290         String personResourceId;
1291         for (Map.Entry<String, String> entry : allResourceItemIdsCreated.entrySet()) {
1292             personResourceId = entry.getKey();
1293             personAuthorityResourceId = entry.getValue();
1294             // FIXME Add cleanup of any contact resources created
1295             // for this item here, before cleaning up the item.
1296             // Note: Any non-success responses are ignored and not reported.
1297             ClientResponse<Response> res =
1298                 client.deleteItem(personAuthorityResourceId, personResourceId);
1299         }
1300         // Clean up personAuthority resources.
1301         for (String resourceId : allResourceIdsCreated) {
1302             // Note: Any non-success responses are ignored and not reported.
1303             ClientResponse<Response> res = client.delete(resourceId);
1304         }
1305     }
1306
1307     
1308     // ---------------------------------------------------------------
1309     // Utility methods used by tests above
1310     // ---------------------------------------------------------------
1311     @Override
1312     public String getServicePathComponent() {
1313         return SERVICE_PATH_COMPONENT;
1314     }
1315
1316     public String getItemServicePathComponent() {
1317         return ITEM_SERVICE_PATH_COMPONENT;
1318     }
1319
1320     /**
1321      * Returns the root URL for a service.
1322      *
1323      * This URL consists of a base URL for all services, followed by
1324      * a path component for the owning personAuthority, followed by the 
1325      * path component for the items.
1326      *
1327      * @return The root URL for a service.
1328      */
1329     protected String getItemServiceRootURL(String parentResourceIdentifier) {
1330         return getResourceURL(parentResourceIdentifier) + "/" + getItemServicePathComponent();
1331     }
1332
1333     /**
1334      * Returns the URL of a specific resource managed by a service, and
1335      * designated by an identifier (such as a universally unique ID, or UUID).
1336      *
1337      * @param  resourceIdentifier  An identifier (such as a UUID) for a resource.
1338      *
1339      * @return The URL of a specific resource managed by a service.
1340      */
1341     protected String getItemResourceURL(String parentResourceIdentifier, String resourceIdentifier) {
1342         return getItemServiceRootURL(parentResourceIdentifier) + "/" + resourceIdentifier;
1343     }
1344
1345 }