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