]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
a6558eafc3538bccbee271e78c3e00c7a412f0d0
[tmp/jakarta-migration.git] /
1 /**
2  * This document is a part of the source code and related artifacts
3  * for CollectionSpace, an open source collections management system
4  * for museums and related institutions:
5  *
6  * http://www.collectionspace.org
7  * http://wiki.collectionspace.org
8  *
9  * Copyright (c)) 2009 Regents of the University of California
10  *
11  * Licensed under the Educational Community License (ECL), Version 2.0.
12  * You may not use this file except in compliance with this License.
13  *
14  * You may obtain a copy of the ECL 2.0 License at
15  * https://source.collectionspace.org/collection-space/LICENSE.txt
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 package org.collectionspace.services.client.test;
24
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import javax.ws.rs.core.Response;
30
31 import org.collectionspace.services.PersonJAXBSchema;
32 import org.collectionspace.services.client.CollectionSpaceClient;
33 import org.collectionspace.services.client.PersonAuthorityClient;
34 import org.collectionspace.services.client.PersonAuthorityClientUtils;
35 import org.collectionspace.services.jaxb.AbstractCommonList;
36 import org.collectionspace.services.person.PersonsCommonList;
37 import org.jboss.resteasy.client.ClientResponse;
38 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.testng.Assert;
42 import org.testng.annotations.AfterClass;
43 import org.testng.annotations.BeforeClass;
44 import org.testng.annotations.Test;
45
46 /**
47  * PersonAuthoritySearchTest, carries out search (e.g. partial
48  * term matching) tests against a deployed and running PersonAuthority Service.
49  *
50  * $LastChangedRevision: 753 $
51  * $LastChangedDate: 2009-09-23 11:03:36 -0700 (Wed, 23 Sep 2009) $
52  */
53 public class PersonAuthoritySearchTest extends BaseServiceTest {
54
55     private final String CLASS_NAME = PersonAuthoritySearchTest.class.getName();
56     private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
57     
58     /** The service path component. */
59     final String SERVICE_PATH_COMPONENT = "personauthorities";
60     
61     // Test name for partial term matching: Lech Walesa
62     //
63     // Forename
64     final String TEST_PARTIAL_TERM_FORE_NAME = "Lech";
65     //
66     // Surname (contains two non-USASCII range Unicode UTF-8 characters)
67     final String TEST_PARTIAL_TERM_SUR_NAME = "Wa" + "\u0142" + "\u0119" + "sa";
68     //
69     // Displayname
70     final String TEST_PARTIAL_TERM_DISPLAY_NAME =
71             TEST_PARTIAL_TERM_FORE_NAME + " " + TEST_PARTIAL_TERM_SUR_NAME;
72     //
73     // shortId
74     final String TEST_SHORT_ID = "lechWalesa";
75
76     // Non-existent partial term name (first letters of each of the words
77     // in a pangram for the English alphabet).
78     private static final String TEST_PARTIAL_TERM_NON_EXISTENT = "jlmbsoq";
79
80     /** The known resource id. */
81     private String knownResourceId = null;
82     
83     /** The known resource ref name. */
84     private String knownResourceRefName = null;
85     
86     /** The known item resource id. */
87     private String knownItemResourceId = null;
88
89     // The resource ID of an item resource used for partial term matching tests.
90     private String knownItemPartialTermResourceId = null;
91
92     private List<String> allResourceIdsCreated = new ArrayList<String>();
93     
94     /** The all item resource ids created. */
95     private Map<String, String> allItemResourceIdsCreated =
96         new HashMap<String, String>();
97
98     // The number of matches expected on each partial term.
99     final int NUM_MATCHES_EXPECTED = 1;
100
101     // The minimum number of characters that must be included
102     // a partial term, in order to permit matching to occur.
103     final int PARTIAL_TERM_MIN_LENGTH = 1;
104
105     /* (non-Javadoc)
106      * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
107      */
108     @Override
109     protected CollectionSpaceClient getClientInstance() {
110         return new PersonAuthorityClient();
111     }
112     
113     /* (non-Javadoc)
114      * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
115      */
116     @Override
117     protected AbstractCommonList getAbstractCommonList(
118                     ClientResponse<AbstractCommonList> response) {
119     return response.getEntity(PersonsCommonList.class);
120     }
121
122     private String getPartialTerm() {
123         return TEST_PARTIAL_TERM_FORE_NAME;
124     }
125
126     private String getPartialTermUtf8() {
127         return TEST_PARTIAL_TERM_SUR_NAME;
128     }
129
130     private String getPartialTermNonExistent() {
131         return TEST_PARTIAL_TERM_NON_EXISTENT;
132     }
133
134     private String getPartialTermMinimumLength() {
135         String partialTerm = getPartialTerm();
136         if (partialTerm == null || partialTerm.trim().isEmpty()) {
137             return partialTerm;
138         }
139         if (getPartialTerm().length() > PARTIAL_TERM_MIN_LENGTH) {
140             return partialTerm.substring(0, PARTIAL_TERM_MIN_LENGTH);
141         } else {
142           return partialTerm;
143         }
144     }
145
146     @BeforeClass
147     public void setup() {
148         try {
149             createAuthority();
150         } catch (Exception e) {
151             Assert.fail("Could not create new Authority for search tests.", e);
152         }
153         try {
154             createItemInAuthorityForPartialTermMatch(knownResourceId, knownResourceRefName);
155         } catch (Exception e) {
156             Assert.fail("Could not create new item in Authority for search tests.", e);
157         }
158     }
159  
160     // ---------------------------------------------------------------
161     // CRUD tests : READ_LIST tests by partial term match.
162     // ---------------------------------------------------------------
163
164     // Success outcomes
165
166     /**
167      * Reads an item list by partial term.
168      */
169     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
170         groups = {"readListByPartialTerm"})
171     public void partialTermMatch(String testName) {
172         if (logger.isDebugEnabled()) {
173             logger.debug(testBanner(testName, CLASS_NAME));
174         }
175         int numMatchesFound = 0;
176         String partialTerm = getPartialTerm();
177         if (logger.isDebugEnabled()) {
178             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
179         }
180         numMatchesFound = readItemListByPartialTerm(knownResourceId, partialTerm);
181         if (logger.isDebugEnabled()) {
182             logger.debug("Found " + numMatchesFound + " match(es), expected " +
183                 NUM_MATCHES_EXPECTED + " match(es).");
184         }
185         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
186     }
187
188     /**
189      * Reads an item list by partial term, with a partial term that consists
190      * of an all-lowercase variation of the expected match, to test case-insensitive
191      * matching.
192      */
193     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
194         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
195     public void partialTermMatchCaseInsensitiveLowerCase(String testName) {
196         if (logger.isDebugEnabled()) {
197             logger.debug(testBanner(testName, CLASS_NAME));
198         }
199         int numMatchesFound = 0;
200
201         final String partialTerm = getPartialTerm().toLowerCase();
202         if (logger.isDebugEnabled()) {
203             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
204         }
205         numMatchesFound =
206             readItemListByPartialTerm(knownResourceId, partialTerm);
207                 if (logger.isDebugEnabled()) {
208         logger.debug("Found " + numMatchesFound + " match(es), expected " +
209                 NUM_MATCHES_EXPECTED + " match(es).");
210         }
211         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
212     }
213
214     /**
215      * Reads an item list by partial term, with a partial term that consists
216      * of an all-uppercase variation of the expected match, to test case-insensitive
217      * matching.
218      */
219     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
220         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
221     public void partialTermMatchCaseInsensitiveUpperCase(String testName) {
222         if (logger.isDebugEnabled()) {
223             logger.debug(testBanner(testName, CLASS_NAME));
224         }
225         int numMatchesFound = 0;
226
227         final String partialTerm = getPartialTerm().toUpperCase();
228         if (logger.isDebugEnabled()) {
229             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
230         }
231         numMatchesFound =
232             readItemListByPartialTerm(knownResourceId, partialTerm);
233         if (logger.isDebugEnabled()) {
234             logger.debug("Found " + numMatchesFound + " match(es), expected " +
235                 NUM_MATCHES_EXPECTED + " match(es).");
236         }
237         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
238     }
239
240     /**
241      * Reads an item list by partial term, with a partial term that is of
242      * the minimum character length that may be expected to be matched.
243      */
244     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
245         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
246     public void partialTermMatchMinimumLength(String testName) {
247         if (logger.isDebugEnabled()) {
248             logger.debug(testBanner(testName, CLASS_NAME));
249         }
250         int numMatchesFound = 0;
251         String partialTerm = getPartialTermMinimumLength();
252         if (logger.isDebugEnabled()) {
253             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
254         }
255         numMatchesFound = readItemListByPartialTerm(knownResourceId, partialTerm);
256         // Zero matches are expected on a non-existent term.
257         if (logger.isDebugEnabled()) {
258             logger.debug("Found " + numMatchesFound + " match(es), expected " +
259                 NUM_MATCHES_EXPECTED + " match(es).");
260         }
261         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
262     }
263
264     /**
265      * Reads an item list by partial term, with a partial term that contains
266      * at least one Unicode UTF-8 character (outside the USASCII range).
267      */
268     // FIXME: Test currently fails with a true UTF-8 String - need to investigate why.
269     // Will be commented out for now until we get this working ...
270 /*
271     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
272         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
273     public void partialTermMatchUTF8(String testName) {
274         if (logger.isDebugEnabled()) {
275             logger.debug(testBanner(testName, CLASS_NAME));
276         }
277         int numMatchesFound = 0;
278         String partialTerm = getPartialTermUtf8();
279         if (logger.isDebugEnabled()) {
280             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
281         }
282         numMatchesFound =
283             readItemListByPartialTerm(knownResourceId, partialTerm);
284         if (logger.isDebugEnabled()) {
285             logger.debug("Found " + numMatchesFound + " match(es), expected " +
286                 NUM_MATCHES_EXPECTED + " match(es).");
287         }
288         Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
289     }
290 */
291     
292     // Failure outcomes
293
294     /**
295      * Reads an item list by partial term, with a partial term that is not
296      * expected to be matched by any term in any resource.
297      */
298     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
299         groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
300     public void partialTermMatchOnNonexistentTerm(String testName) {
301         if (logger.isDebugEnabled()) {
302             logger.debug(testBanner(testName, CLASS_NAME));
303         }
304         int numMatchesFound = 0;
305         int ZERO_MATCHES_EXPECTED = 0;
306         String partialTerm = getPartialTermNonExistent();
307         if (logger.isDebugEnabled()) {
308             logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
309         }
310         numMatchesFound = readItemListByPartialTerm(knownResourceId, partialTerm);
311         // Zero matches are expected on a non-existent term.
312         if (logger.isDebugEnabled()) {
313             logger.debug("Found " + numMatchesFound + " match(es), expected " +
314                 ZERO_MATCHES_EXPECTED + " match(es).");
315         }
316         Assert.assertEquals(numMatchesFound, ZERO_MATCHES_EXPECTED);
317     }
318
319     /**
320      * Reads an item list by partial term, given an authority and a term.
321      *
322      * @param authorityCsid The CSID of the authority within which partial term matching
323      *     will be performed.
324      * @param partialTerm A partial term to match item resources.
325      * @return The number of item resources matched by the partial term.
326      */
327     private int readItemListByPartialTerm(String authorityCsid, String partialTerm) {
328
329         String testName = "readItemListByPartialTerm";
330
331         // Perform setup.
332         int expectedStatusCode = Response.Status.OK.getStatusCode();
333         ServiceRequestType requestType = ServiceRequestType.READ_LIST;
334         testSetup(expectedStatusCode, requestType);
335
336         // Submit the request to the service and store the response.
337         PersonAuthorityClient client = new PersonAuthorityClient();
338         ClientResponse<PersonsCommonList> res = null;
339         if (authorityCsid != null) {
340             res = client.readItemList(authorityCsid, partialTerm);
341         } else {
342             Assert.fail("readItemListByPartialTerm passed null csid!");
343         }
344         PersonsCommonList list = null;
345         try {
346             int statusCode = res.getStatus();
347
348             // Check the status code of the response: does it match
349             // the expected response(s)?
350             if(logger.isDebugEnabled()){
351                 logger.debug(testName + ": status = " + statusCode);
352             }
353             Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
354                     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
355             Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
356
357             list = res.getEntity();
358         } finally {
359             res.releaseConnection();
360         }
361
362         List<PersonsCommonList.PersonListItem> items = list.getPersonListItem();
363         int nItemsReturned = items.size();
364
365         return nItemsReturned;
366     }
367     
368     // ---------------------------------------------------------------
369     // Cleanup of resources created during testing
370     // ---------------------------------------------------------------
371     
372     /**
373      * Deletes all resources created by tests, after all tests have been run.
374      *
375      * This cleanup method will always be run, even if one or more tests fail.
376      * For this reason, it attempts to remove all resources created
377      * at any point during testing, even if some of those resources
378      * may be expected to be deleted by certain tests.
379      */
380     @AfterClass(alwaysRun=true)
381     public void cleanUp() {
382         String noTest = System.getProperty("noTestCleanup");
383         if(Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
384             if (logger.isDebugEnabled()) {
385                 logger.debug("Skipping Cleanup phase ...");
386             }
387             return;
388         }
389         if (logger.isDebugEnabled()) {
390             logger.debug("Cleaning up temporary resources created for testing ...");
391         }
392         String parentResourceId;
393         String itemResourceId;
394         PersonAuthorityClient client = new PersonAuthorityClient();
395         parentResourceId = knownResourceId;
396         // Clean up item resources.
397         for (Map.Entry<String, String> entry : allItemResourceIdsCreated.entrySet()) {
398             itemResourceId = entry.getKey();
399             parentResourceId = entry.getValue();
400             // Note: Any non-success responses from the delete operation
401             // below are ignored and not reported.
402             ClientResponse<Response> res =
403                 client.deleteItem(parentResourceId, itemResourceId);
404             res.releaseConnection();
405         }
406         // Clean up authority resources.
407         for (String resourceId : allResourceIdsCreated) {
408             // Note: Any non-success responses are ignored and not reported.
409             client.delete(resourceId).releaseConnection();
410         }
411     }
412
413     // ---------------------------------------------------------------
414     // Utility methods used by tests above
415     // ---------------------------------------------------------------
416     /* (non-Javadoc)
417      * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
418      */
419     @Override
420     public String getServicePathComponent() {
421         return SERVICE_PATH_COMPONENT;
422     }
423
424
425     // ---------------------------------------------------------------
426     // Utilities: setup routines for search tests
427     // ---------------------------------------------------------------
428
429     public void createAuthority() throws Exception {
430
431         String testName = "createAuthority";
432
433         // Perform setup.
434         int expectedStatusCode = Response.Status.CREATED.getStatusCode();
435         ServiceRequestType requestType = ServiceRequestType.CREATE;
436         testSetup(expectedStatusCode, requestType);
437
438         // Submit the request to the service and store the response.
439         PersonAuthorityClient client = new PersonAuthorityClient();
440         String shortId = createIdentifier();
441         String displayName = "displayName-" + shortId;
442         String baseRefName = PersonAuthorityClientUtils.createPersonAuthRefName(shortId, null);
443         MultipartOutput multipart =
444             PersonAuthorityClientUtils.createPersonAuthorityInstance(
445             displayName, shortId, client.getCommonPartName());
446
447         String newID = null;
448         ClientResponse<Response> res = client.create(multipart);
449         try {
450             int statusCode = res.getStatus();
451             // Check the status code of the response: does it match
452             // the expected response(s)?
453             if(logger.isDebugEnabled()){
454                 logger.debug(testName + ": status = " + statusCode);
455             }
456             Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
457                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
458             Assert.assertEquals(statusCode, this.EXPECTED_STATUS_CODE);
459             newID = PersonAuthorityClientUtils.extractId(res);
460         } finally {
461             res.releaseConnection();
462         }
463         // Store the refname from the first resource created
464         // for additional tests below.
465         knownResourceRefName = baseRefName;
466         // Store the ID returned from the first resource created
467         // for additional tests below.
468         if (knownResourceId == null){
469             knownResourceId = newID;
470             knownResourceRefName = baseRefName;
471         }
472
473         // Store the IDs from every resource created by tests,
474         // so they can be deleted after tests have been run.
475         allResourceIdsCreated.add(newID);
476     }
477
478      /**
479      * Creates an item in the authority, used for partial term matching tests.
480      *
481      * @param authorityCsid The CSID of the Authority in which the term will be created.
482      * @param authRefName The refName of the Authority in which the term will be created.
483      */
484     private void createItemInAuthorityForPartialTermMatch(
485                 String authorityCsid, String authRefName)
486         throws Exception {
487             
488         String testName = "createItemInAuthorityForPartialTermMatch";
489
490         int expectedStatusCode = Response.Status.CREATED.getStatusCode();
491         ServiceRequestType requestType = ServiceRequestType.CREATE;
492         testSetup(expectedStatusCode, requestType);
493
494         // Submit the request to the service and store the response.
495         PersonAuthorityClient client = new PersonAuthorityClient();
496         Map<String, String> partialTermPersonMap = new HashMap<String,String>();
497         //
498         // Fill the property map
499         //
500         partialTermPersonMap.put(PersonJAXBSchema.SHORT_IDENTIFIER, TEST_SHORT_ID );
501         partialTermPersonMap.put(PersonJAXBSchema.DISPLAY_NAME_COMPUTED, "false");
502         partialTermPersonMap.put(PersonJAXBSchema.DISPLAY_NAME, TEST_PARTIAL_TERM_DISPLAY_NAME);
503         partialTermPersonMap.put(PersonJAXBSchema.FORE_NAME, TEST_PARTIAL_TERM_FORE_NAME);
504         partialTermPersonMap.put(PersonJAXBSchema.SUR_NAME, TEST_PARTIAL_TERM_SUR_NAME);
505         partialTermPersonMap.put(PersonJAXBSchema.GENDER, "male");
506         MultipartOutput multipart =
507             PersonAuthorityClientUtils.createPersonInstance(authorityCsid, authRefName, partialTermPersonMap,
508                 client.getItemCommonPartName() );
509
510         String newID = null;
511         ClientResponse<Response> res = client.createItem(authorityCsid, multipart);
512         try {
513             int statusCode = res.getStatus();
514             // Check the status code of the response: does it match
515             // the expected response(s)?
516             if(logger.isDebugEnabled()){
517                 logger.debug(testName + ": status = " + statusCode);
518             }
519             Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
520                     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
521             Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
522
523             newID = PersonAuthorityClientUtils.extractId(res);
524         } finally {
525             res.releaseConnection();
526         }
527
528         // Store the ID returned from the first item resource created
529         // for additional tests below.
530         if (knownItemResourceId == null){
531             knownItemResourceId = newID;
532             if (logger.isDebugEnabled()) {
533                 logger.debug(testName + ": knownItemPartialTermResourceId=" + knownItemPartialTermResourceId);
534             }
535         }
536
537         // Store the IDs from any item resources created
538         // by tests, along with the IDs of their parents, so these items
539         // can be deleted after all tests have been run.
540         allItemResourceIdsCreated.put(newID, authorityCsid);
541     }
542
543 }