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