]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
b4bd638dab945a770f92d99a8036d73403107900
[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.io.UnsupportedEncodingException;
26 import java.net.URLEncoder;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31
32 import javax.ws.rs.core.Response;
33
34 import org.collectionspace.services.PersonJAXBSchema;
35 import org.collectionspace.services.client.CollectionSpaceClient;
36 import org.collectionspace.services.client.PersonAuthorityClient;
37 import org.collectionspace.services.client.PersonAuthorityClientUtils;
38 import org.collectionspace.services.client.PoxPayloadOut;
39 import org.collectionspace.services.jaxb.AbstractCommonList;
40 import org.collectionspace.services.person.PersonTermGroup;
41
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.testng.Assert;
45 import org.testng.annotations.AfterClass;
46 import org.testng.annotations.BeforeClass;
47 import org.testng.annotations.Test;
48
49 /**
50  * PersonAuthoritySearchTest, carries out search (e.g. partial
51  * term matching) tests against a deployed and running PersonAuthority Service.
52  *
53  * $LastChangedRevision: 753 $
54  * $LastChangedDate: 2009-09-23 11:03:36 -0700 (Wed, 23 Sep 2009) $
55  */
56 public class PersonAuthoritySearchTest extends BaseServiceTest<AbstractCommonList> {
57
58     private final String CLASS_NAME = PersonAuthoritySearchTest.class.getName();
59     private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
60     
61         @Override
62         public String getServicePathComponent() {
63                 return PersonAuthorityClient.SERVICE_PATH_COMPONENT;
64         }
65
66         @Override
67         protected String getServiceName() {
68                 return PersonAuthorityClient.SERVICE_NAME;
69         }
70     
71     final String UTF8_CHARSET_NAME = "UTF-8";
72     
73     // Test name for partial term matching: Lech Wałęsa
74     //
75     // For details regarding the łę characters in the last name, see:
76     // http://en.wikipedia.org/wiki/L_with_stroke
77     // http://en.wikipedia.org/wiki/%C4%98
78     //
79     // Forename
80     final String TEST_PARTIAL_TERM_FORE_NAME = "Lech";
81     //
82     // Surname (contains single quote character)
83     final String TEST_PARTIAL_TERM_SUR_NAME_QUOTE = "O'Hara";
84     //
85     // Surname (contains two non-USASCII range Unicode UTF-8 characters)
86     final String TEST_PARTIAL_TERM_SUR_NAME_UNICODE = "Wałęsa";
87         // Wrong: "Wa" + "\u0142" + "\u0119" + "sa";
88         // Should also work: "Wa" + '\u0142' + '\u0119' + "sa";
89         // Should also work: "Wa\u0142\u0119sa";
90     //
91     //
92     // Displayname
93     final String TEST_PARTIAL_TERM_DISPLAY_NAME_UNICODE =
94             TEST_PARTIAL_TERM_FORE_NAME + " " + TEST_PARTIAL_TERM_SUR_NAME_UNICODE;
95     //
96     // Displayname
97     final String TEST_PARTIAL_TERM_DISPLAY_NAME_QUOTE =
98             TEST_PARTIAL_TERM_FORE_NAME + " " + TEST_PARTIAL_TERM_SUR_NAME_QUOTE;
99     //
100     // shortId
101     final String TEST_SHORT_ID_UNICODE = "lechWalesa";
102     //
103     // shortId
104     final String TEST_SHORT_ID_QUOTE = "lechOHara";
105     
106     final String TEST_KWD_BIRTH_PLACE = "Popowo, Poland";
107
108     final String TEST_KWD_UTF8_STYLE = "Appliqu"+'\u00e8'+"d Arts";
109     
110     final String TEST_KWD_BIO_NOTE_NO_QUOTES = 
111         "This is a silly bionote with no so-called quotes.";
112     
113     final String TEST_KWD_BIO_NOTE_DBL_QUOTES = 
114         "This is a silly \"bionote\" for testing so called quote_handling";
115
116     final String TEST_KWD_NO_MATCH = "Foobar";
117
118     // Non-existent partial term name (first letters of each of the words
119     // in a pangram for the English alphabet).
120     private static final String TEST_PARTIAL_TERM_NON_EXISTENT = "jlmbsoq";
121
122     /** The known resource id. */
123     private String knownResourceId = null;
124     
125     /** The known resource ref name. */
126     //private String knownResourceRefName = null;
127     
128     /** The known item resource id. */
129     private String knownItemResourceId = null;
130
131     // The resource ID of an item resource used for partial term matching tests.
132     private String knownItemPartialTermResourceId = null;
133
134     private List<String> allResourceIdsCreated = new ArrayList<String>();
135     
136     /** The all item resource ids created. */
137     private Map<String, String> allItemResourceIdsCreated =
138         new HashMap<String, String>();
139
140     // The number of matches expected on each partial term.
141     final int NUM_MATCHES_EXPECTED_COMMON = 2;
142     final int NUM_MATCHES_EXPECTED_SPECIFIC = 1;
143
144     // The minimum number of characters that must be included
145     // a partial term, in order to permit matching to occur.
146     final int PARTIAL_TERM_MIN_LENGTH = 1;
147
148     /* (non-Javadoc)
149      * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
150      */
151     @Override
152     protected CollectionSpaceClient getClientInstance() {
153         return new PersonAuthorityClient();
154     }
155
156         @Override
157         protected CollectionSpaceClient getClientInstance(String clientPropertiesFilename) {
158         return new PersonAuthorityClient(clientPropertiesFilename);
159         }
160
161     /* (non-Javadoc)
162      * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
163      */
164     @Override
165     protected AbstractCommonList getCommonList(Response response) {
166         return response.readEntity(AbstractCommonList.class);
167     }
168
169     private String getPartialTermCommon() {
170         return TEST_PARTIAL_TERM_FORE_NAME;
171     }
172
173     private String getPartialTermUtf8() {
174         return TEST_PARTIAL_TERM_SUR_NAME_UNICODE;
175     }
176
177     private String getPartialTermQuote() {
178         return TEST_PARTIAL_TERM_SUR_NAME_QUOTE;
179     }
180
181     private String getPartialTermNonExistent() {
182         return TEST_PARTIAL_TERM_NON_EXISTENT;
183     }
184
185     private String getPartialTermMinimumLength() {
186         String partialTerm = getPartialTermCommon();
187         if (partialTerm == null || partialTerm.trim().isEmpty()) {
188             return partialTerm;
189         }
190         if (partialTerm.length() > PARTIAL_TERM_MIN_LENGTH) {
191             return partialTerm.substring(0, PARTIAL_TERM_MIN_LENGTH);
192         } else {
193           return partialTerm;
194         }
195     }
196
197     private String getKwdTerm() {
198         return TEST_KWD_BIRTH_PLACE;
199     }
200
201     private String getKwdTermUTF8() {
202         return TEST_KWD_UTF8_STYLE;
203     }
204
205     private String getKwdTermNonExistent() {
206         return TEST_KWD_NO_MATCH;
207     }
208
209     @BeforeClass
210     public void setup() {
211         try {
212             createAuthority();
213         } catch (Exception e) {
214             Assert.fail("Could not create new Authority for search tests.", e);
215         }
216         try {
217             createItemsInAuthorityForPartialTermMatch(knownResourceId, null ); //knownResourceRefName);
218         } catch (Exception e) {
219             Assert.fail("Could not create new item in Authority for search tests.", e);
220         }
221     }
222  
223     // ---------------------------------------------------------------
224     // CRUD tests : READ_LIST tests by partial term match.
225     // ---------------------------------------------------------------
226
227     // Success outcomes
228
229     /**
230      * Reads an item list by partial term.
231      */
232     @Test(dataProvider="testName", groups = {"readListByPartialTerm"})
233     public void partialTermMatch(String testName) {
234         int numMatchesFound = 0;
235         String partialTerm = getPartialTermCommon();
236         if (logger.isDebugEnabled()) {
237             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
238         }
239         numMatchesFound = readItemListWithFilters(testName, knownResourceId, partialTerm, null);
240         if (logger.isDebugEnabled()) {
241             logger.debug("Found " + numMatchesFound + " match(es), expected " +
242                 NUM_MATCHES_EXPECTED_COMMON + " match(es).");
243         }
244         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED_COMMON);
245     }
246
247     /**
248      * Reads an item list by partial term, with a partial term that consists
249      * of an all-lowercase variation of the expected match, to test case-insensitive
250      * matching.
251      */
252     @Test(dataProvider="testName", groups = {"readListByPartialTerm"},
253                 dependsOnMethods = {"partialTermMatch"})
254     public void partialTermMatchCaseInsensitiveLowerCase(String testName) {
255         int numMatchesFound = 0;
256
257         final String partialTerm = getPartialTermCommon().toLowerCase();
258         if (logger.isDebugEnabled()) {
259             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
260         }
261         numMatchesFound =
262                 readItemListWithFilters(testName, knownResourceId, partialTerm, null);
263                 if (logger.isDebugEnabled()) {
264         logger.debug("Found " + numMatchesFound + " match(es), expected " +
265                         NUM_MATCHES_EXPECTED_COMMON + " match(es).");
266         }
267         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED_COMMON);
268     }
269
270     /**
271      * Reads an item list by partial term, with a partial term that consists
272      * of an all-uppercase variation of the expected match, to test case-insensitive
273      * matching.
274      */
275     @Test(dataProvider="testName",
276         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
277     public void partialTermMatchCaseInsensitiveUpperCase(String testName) {
278         int numMatchesFound = 0;
279
280         final String partialTerm = getPartialTermCommon().toUpperCase();
281         if (logger.isDebugEnabled()) {
282             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
283         }
284         numMatchesFound =
285                 readItemListWithFilters(testName, knownResourceId, partialTerm, null);
286         if (logger.isDebugEnabled()) {
287             logger.debug("Found " + numMatchesFound + " match(es), expected " +
288                         NUM_MATCHES_EXPECTED_COMMON + " match(es).");
289         }
290         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED_COMMON);
291     }
292
293     /**
294      * Reads an item list by partial term, with a partial term that is of
295      * the minimum character length that may be expected to be matched.
296      */
297     @Test(dataProvider="testName",
298         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
299     public void partialTermMatchMinimumLength(String testName) {
300         int numMatchesFound = 0;
301         String partialTerm = getPartialTermMinimumLength();
302         if (logger.isDebugEnabled()) {
303             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
304         }
305         numMatchesFound = readItemListWithFilters(testName, knownResourceId, partialTerm, null);
306         // Zero matches are expected on a non-existent term.
307         if (logger.isDebugEnabled()) {
308             logger.debug("Found " + numMatchesFound + " match(es), expected " +
309                         NUM_MATCHES_EXPECTED_COMMON + " match(es).");
310         }
311         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED_COMMON);
312     }
313
314     /**
315      * Reads an item list by partial term, with a partial term that contains
316      * at least one Unicode UTF-8 character (outside the USASCII range).
317      */
318     @Test(dataProvider="testName",
319         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
320     public void partialTermMatchUTF8(String testName) {
321         int numMatchesFound = 0;
322         String partialTerm = getPartialTermUtf8();
323         String ptEncoded;
324         try {
325                 ptEncoded = URLEncoder.encode(partialTerm, UTF8_CHARSET_NAME);
326         }
327         catch (UnsupportedEncodingException ex) {
328           throw new RuntimeException("Broken VM does not support UTF-8");
329         }
330         if (logger.isDebugEnabled()) {
331             logger.debug("Attempting match on partial term '" + partialTerm + "', Encoded:'"+ptEncoded+"' ...");
332         }
333         numMatchesFound =
334                 readItemListWithFilters(testName, knownResourceId, partialTerm, null);
335         if (logger.isDebugEnabled()) {
336             logger.debug("Found " + numMatchesFound + " match(es), expected " +
337                 NUM_MATCHES_EXPECTED_SPECIFIC + " match(es).");
338         }
339         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED_SPECIFIC);
340     }
341     
342     /**
343      * Reads an item list by partial term, with a partial term that contains
344      * at least one Unicode UTF-8 character (outside the USASCII range).
345      */
346     @Test(dataProvider="testName",
347         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
348     public void partialTermMatchQuote(String testName) {
349         int numMatchesFound = 0;
350         String partialTerm = getPartialTermQuote();
351         if (logger.isDebugEnabled()) {
352             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
353         }
354         numMatchesFound =
355                 readItemListWithFilters(testName, knownResourceId, partialTerm, null);
356         if (logger.isDebugEnabled()) {
357             logger.debug("Found " + numMatchesFound + " match(es), expected " +
358                 NUM_MATCHES_EXPECTED_SPECIFIC + " match(es).");
359         }
360         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED_SPECIFIC);
361     }
362
363     /**
364      * Finds terms by keywords.
365      */
366     @Test(dataProvider="testName", groups = {"readListByKwdTerm"})
367     public void keywordTermMatch(String testName) {
368         int numMatchesFound = 0;
369         String kwdTerm = getKwdTerm();
370         if (logger.isDebugEnabled()) {
371             logger.debug("Attempting match on kwd term '" + kwdTerm + "' ...");
372         }
373         numMatchesFound = readItemListWithFilters(testName, knownResourceId, null, kwdTerm);
374         if (logger.isDebugEnabled()) {
375             logger.debug("Found " + numMatchesFound + " match(es), expected " +
376                     NUM_MATCHES_EXPECTED_COMMON + " match(es).");
377         }
378         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED_COMMON);
379     }
380
381     /**
382      * Finds terms by keywords.
383      */
384     @Test(dataProvider="testName",
385         groups = {"readListByKwdTerm"}, dependsOnMethods = {"keywordTermMatch"})
386     public void keywordTermMatchUTF8(String testName) {
387         int numMatchesFound = 0;
388         String kwdTerm = getKwdTermUTF8();
389         if (logger.isDebugEnabled()) {
390             logger.debug("Attempting match on kwd term '" + kwdTerm + "' ...");
391         }
392         numMatchesFound = readItemListWithFilters(testName, knownResourceId, null, kwdTerm);
393         if (logger.isDebugEnabled()) {
394             logger.debug("Found " + numMatchesFound + " match(es), expected " +
395                 NUM_MATCHES_EXPECTED_COMMON + " match(es).");
396         }
397         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED_COMMON);
398     }
399
400     
401     
402     // Failure outcomes
403
404     /**
405      * Reads an item list by partial term, with a partial term that is not
406      * expected to be matched by any term in any resource.
407      */
408     @Test(dataProvider="testName",
409         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
410     public void partialTermMatchOnNonexistentTerm(String testName) {
411         int numMatchesFound = 0;
412         int ZERO_MATCHES_EXPECTED = 0;
413         String partialTerm = getPartialTermNonExistent();
414         if (logger.isDebugEnabled()) {
415             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
416         }
417         numMatchesFound = readItemListWithFilters(testName, knownResourceId, partialTerm, null);
418         // Zero matches are expected on a non-existent term.
419         if (logger.isDebugEnabled()) {
420             logger.debug("Found " + numMatchesFound + " match(es), expected " +
421                 ZERO_MATCHES_EXPECTED + " match(es).");
422         }
423         Assert.assertEquals(numMatchesFound, ZERO_MATCHES_EXPECTED);
424     }
425
426     /**
427      * Reads an item list by partial term, with a partial term that is not
428      * expected to be matched by any term in any resource.
429      */
430     @Test(dataProvider="testName", groups = {"readListByKwdTerm"},
431                 dependsOnMethods = {"keywordTermMatch"})
432     public void keywordTermMatchOnNonexistentTerm(String testName) {
433         int numMatchesFound = 0;
434         int ZERO_MATCHES_EXPECTED = 0;
435         String kwdTerm = getKwdTermNonExistent();
436         if (logger.isDebugEnabled()) {
437             logger.debug("Attempting match on kwd term '" + kwdTerm + "' ...");
438         }
439         numMatchesFound = readItemListWithFilters(testName, knownResourceId, null, kwdTerm);
440         // Zero matches are expected on a non-existent term.
441         if (logger.isDebugEnabled()) {
442             logger.debug("Found " + numMatchesFound + " match(es), expected " +
443                 ZERO_MATCHES_EXPECTED + " match(es).");
444         }
445         Assert.assertEquals(numMatchesFound, ZERO_MATCHES_EXPECTED);
446     }
447
448     /**
449      * Reads an item list by partial term or keywords, given an authority and a term.
450      * Only one of partialTerm or keywords should be specified. 
451      * If both are specified, keywords will be ignored.
452      * 
453      * @param testName Calling test name
454      * @param authorityCsid The CSID of the authority within which partial term matching
455      *     will be performed.
456      * @param partialTerm A partial term to match item resources.
457      * @param partialTerm A keyword list to match item resources.
458      * @return The number of item resources matched by the partial term.
459      */
460     private int readItemListWithFilters(String testName, 
461                 String authorityCsid, String partialTerm, String keywords) {
462
463         // Perform setup.
464         int expectedStatusCode = Response.Status.OK.getStatusCode();
465         ServiceRequestType requestType = ServiceRequestType.READ_LIST;
466         testSetup(expectedStatusCode, requestType);
467
468         // Submit the request to the service and store the response.
469         PersonAuthorityClient client = new PersonAuthorityClient();
470         Response res = null;
471         if (authorityCsid != null) {
472                 res = client.readItemList(authorityCsid, partialTerm, keywords);
473         } else {
474             Assert.fail("readItemListByPartialTerm passed null csid!");
475         }
476         AbstractCommonList list = null;
477         try {
478             assertStatusCode(res, testName);
479             list = res.readEntity(AbstractCommonList.class);
480         } finally {
481                 if (res != null) {
482                 res.close();
483             }
484         }
485
486         List<AbstractCommonList.ListItem> items = list.getListItem();
487         int nItemsReturned = items.size();
488
489         return nItemsReturned;
490     }
491     
492     // ---------------------------------------------------------------
493     // Cleanup of resources created during testing
494     // ---------------------------------------------------------------
495     
496     /**
497      * Deletes all resources created by tests, after all tests have been run.
498      *
499      * This cleanup method will always be run, even if one or more tests fail.
500      * For this reason, it attempts to remove all resources created
501      * at any point during testing, even if some of those resources
502      * may be expected to be deleted by certain tests.
503      */
504     @AfterClass(alwaysRun=true)
505     public void cleanUp() {
506         String noTest = System.getProperty("noTestCleanup");
507         if(Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
508             if (logger.isDebugEnabled()) {
509                 logger.debug("Skipping Cleanup phase ...");
510             }
511             return;
512         }
513         if (logger.isDebugEnabled()) {
514             logger.debug("Cleaning up temporary resources created for testing ...");
515         }
516         String parentResourceId;
517         String itemResourceId;
518         PersonAuthorityClient client = new PersonAuthorityClient();
519         parentResourceId = knownResourceId;
520         // Clean up item resources.
521         for (Map.Entry<String, String> entry : allItemResourceIdsCreated.entrySet()) {
522             itemResourceId = entry.getKey();
523             parentResourceId = entry.getValue();
524             // Note: Any non-success responses from the delete operation
525             // below are ignored and not reported.
526             Response res = client.deleteItem(parentResourceId, itemResourceId);
527             res.close();
528         }
529         // Clean up authority resources.
530         for (String resourceId : allResourceIdsCreated) {
531             // Note: Any non-success responses are ignored and not reported.
532             client.delete(resourceId).close();
533         }
534     }
535
536     // ---------------------------------------------------------------
537     // Utility methods used by tests above
538     // ---------------------------------------------------------------
539
540     // ---------------------------------------------------------------
541     // Utilities: setup routines for search tests
542     // ---------------------------------------------------------------
543
544     public void createAuthority() throws Exception {
545
546         String testName = "createAuthority";
547         if (logger.isDebugEnabled()) {
548             logger.debug(getTestBanner(testName, CLASS_NAME));
549         }
550
551         // Perform setup.
552         int expectedStatusCode = Response.Status.CREATED.getStatusCode();
553         ServiceRequestType requestType = ServiceRequestType.CREATE;
554         testSetup(expectedStatusCode, requestType);
555
556         // Submit the request to the service and store the response.
557         PersonAuthorityClient client = new PersonAuthorityClient();
558         String shortId = createIdentifier();
559         String displayName = "displayName-" + shortId;
560         //String baseRefName = PersonAuthorityClientUtils.createPersonAuthRefName(shortId, null);
561         PoxPayloadOut multipart =
562             PersonAuthorityClientUtils.createPersonAuthorityInstance(
563             displayName, shortId, client.getCommonPartName());
564
565         String newID = null;
566         Response res = client.create(multipart);
567         try {
568             assertStatusCode(res, testName);
569             newID = PersonAuthorityClientUtils.extractId(res);
570         } finally {
571                 if (res != null) {
572                 res.close();
573             }
574         }
575         // Store the refname from the first resource created
576         // for additional tests below.
577         //knownResourceRefName = baseRefName;
578         // Store the ID returned from the first resource created
579         // for additional tests below.
580         if (knownResourceId == null){
581             knownResourceId = newID;
582             //knownResourceRefName = baseRefName;
583         }
584
585         // Store the IDs from every resource created by tests,
586         // so they can be deleted after tests have been run.
587         allResourceIdsCreated.add(newID);
588     }
589
590      /**
591      * Creates an item in the authority, used for partial term matching tests.
592      *
593      * @param authorityCsid The CSID of the Authority in which the term will be created.
594      * @param authRefName The refName of the Authority in which the term will be created.
595      */
596     private void createItemsInAuthorityForPartialTermMatch(
597                 String authorityCsid, String authRefName)
598         throws Exception {
599             
600         String testName = "createItemsInAuthorityForPartialTermMatch";
601
602         int expectedStatusCode = Response.Status.CREATED.getStatusCode();
603         ServiceRequestType requestType = ServiceRequestType.CREATE;
604         testSetup(expectedStatusCode, requestType);
605
606         // Submit the request to the service and store the response.
607         PersonAuthorityClient client = new PersonAuthorityClient();
608         Map<String, String> partialTermPersonMap = new HashMap<String,String>();
609         //
610         // Fill values for the UNICODE item
611         //
612         partialTermPersonMap.put(PersonJAXBSchema.SHORT_IDENTIFIER, TEST_SHORT_ID_UNICODE );
613         partialTermPersonMap.put(PersonJAXBSchema.BIRTH_PLACE, TEST_KWD_BIRTH_PLACE);
614         partialTermPersonMap.put(PersonJAXBSchema.GENDER, "male");
615         partialTermPersonMap.put(PersonJAXBSchema.BIO_NOTE, TEST_KWD_BIO_NOTE_NO_QUOTES);
616         
617         List<PersonTermGroup> partialTerms = new ArrayList<PersonTermGroup>();
618         PersonTermGroup term = new PersonTermGroup();
619         term.setTermDisplayName(TEST_PARTIAL_TERM_DISPLAY_NAME_UNICODE);
620         term.setTermName(TEST_PARTIAL_TERM_DISPLAY_NAME_UNICODE);
621         term.setForeName(TEST_PARTIAL_TERM_FORE_NAME);
622         term.setSurName(TEST_PARTIAL_TERM_SUR_NAME_UNICODE);
623         partialTerms.add(term);
624
625         Map<String, List<String>> partialTermRepeatablesMap = new HashMap<String, List<String>>();
626         ArrayList<String> styles = new ArrayList<String>();
627         styles.add(TEST_KWD_UTF8_STYLE);
628         partialTermRepeatablesMap.put(PersonJAXBSchema.SCHOOLS_OR_STYLES, styles);
629
630         createItem(testName, authorityCsid, null /*authRefName*/, client, 
631                 partialTermPersonMap, partialTerms, partialTermRepeatablesMap);
632         //
633         // Adjust values for the QUOTE item
634         //
635         partialTermPersonMap.put(PersonJAXBSchema.SHORT_IDENTIFIER, TEST_SHORT_ID_QUOTE );
636         partialTermPersonMap.put(PersonJAXBSchema.BIO_NOTE, TEST_KWD_BIO_NOTE_DBL_QUOTES);
637         
638         partialTerms.get(0).setTermDisplayName(TEST_PARTIAL_TERM_DISPLAY_NAME_QUOTE);
639         partialTerms.get(0).setSurName(TEST_PARTIAL_TERM_SUR_NAME_QUOTE);
640
641         createItem(testName, authorityCsid, null /*authRefName*/, client, 
642                 partialTermPersonMap, partialTerms, partialTermRepeatablesMap);
643     }
644     
645     private void createItem(
646                 String testName, 
647                 String authorityCsid, 
648                 String authRefName,
649                 PersonAuthorityClient client,
650                 Map<String, String> partialTermPersonMap,
651                 List<PersonTermGroup> partialTerms,
652                 Map<String, List<String>> partialTermRepeatablesMap) throws Exception {
653         PoxPayloadOut multipart =
654             PersonAuthorityClientUtils.createPersonInstance(authorityCsid, null, //authRefName, 
655                 partialTermPersonMap, partialTerms, partialTermRepeatablesMap, client.getItemCommonPartName() );
656
657         String newID = null;
658         Response res = client.createItem(authorityCsid, multipart);
659         try {
660             newID = PersonAuthorityClientUtils.extractId(res);
661         } finally {
662                 if (res != null) {
663                 res.close();
664             }
665         }
666
667         // Store the ID returned from the first item resource created
668         // for additional tests below.
669         if (knownItemResourceId == null){
670             knownItemResourceId = newID;
671             if (logger.isDebugEnabled()) {
672                 logger.debug(testName + ": knownItemPartialTermResourceId=" + knownItemPartialTermResourceId);
673             }
674         }
675
676         // Store the IDs from any item resources created
677         // by tests, along with the IDs of their parents, so these items
678         // can be deleted after all tests have been run.
679         allItemResourceIdsCreated.put(newID, authorityCsid);
680     }
681 }