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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright (c)) 2009 Regents of the University of California
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
15 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
23 package org.collectionspace.services.client.test;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
29 import javax.ws.rs.core.Response;
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;
47 * PersonAuthoritySearchTest, carries out search (e.g. partial
48 * term matching) tests against a deployed and running PersonAuthority Service.
50 * $LastChangedRevision: 753 $
51 * $LastChangedDate: 2009-09-23 11:03:36 -0700 (Wed, 23 Sep 2009) $
53 public class PersonAuthoritySearchTest extends BaseServiceTest {
55 static final Logger logger = LoggerFactory.getLogger(PersonAuthoritySearchTest.class);
57 /** The service path component. */
58 final String SERVICE_PATH_COMPONENT = "personauthorities";
60 // Test name for partial term matching: Lech Walesa
63 final String TEST_PARTIAL_TERM_FORE_NAME = "Lech";
65 // Surname (contains two non-USASCII range Unicode UTF-8 characters)
66 final String TEST_PARTIAL_TERM_SUR_NAME = "Wa" + "\u0142" + "\u0119" + "sa";
69 final String TEST_PARTIAL_TERM_DISPLAY_NAME =
70 TEST_PARTIAL_TERM_FORE_NAME + " " + TEST_PARTIAL_TERM_SUR_NAME;
72 // Non-existent test name for partial term matching
73 private static final String TEST_PARTIAL_TERM_NON_EXISTENT = "jlmbsoq";
75 /** The known resource id. */
76 private String knownResourceId = null;
78 /** The known resource ref name. */
79 private String knownResourceRefName = null;
81 /** The known item resource id. */
82 private String knownItemResourceId = null;
84 // The resource ID of an item resource used for partial term matching tests.
85 private String knownItemPartialTermResourceId = null;
87 private List<String> allResourceIdsCreated = new ArrayList<String>();
89 /** The all item resource ids created. */
90 private Map<String, String> allItemResourceIdsCreated =
91 new HashMap<String, String>();
93 // The number of matches expected on each partial term.
94 final int NUM_MATCHES_EXPECTED = 1;
97 * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
100 protected CollectionSpaceClient getClientInstance() {
101 return new PersonAuthorityClient();
105 * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
108 protected AbstractCommonList getAbstractCommonList(
109 ClientResponse<AbstractCommonList> response) {
110 return response.getEntity(PersonsCommonList.class);
113 private String getPartialTerm() {
114 return TEST_PARTIAL_TERM_FORE_NAME;
117 private String getPartialTermUtf8() {
118 return TEST_PARTIAL_TERM_SUR_NAME;
121 private String getPartialTermNonExistent() {
122 return TEST_PARTIAL_TERM_NON_EXISTENT;
126 public void setup() {
129 } catch (Exception e) {
130 Assert.fail("Could not create new Authority for search tests.", e);
133 createItemInAuthorityForPartialTermMatch(knownResourceId, knownResourceRefName);
134 } catch (Exception e) {
135 Assert.fail("Could not create new item in Authority for search tests.", e);
139 // ---------------------------------------------------------------
140 // CRUD tests : READ_LIST tests by partial term match.
141 // ---------------------------------------------------------------
146 * Read item list by partial term.
148 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
149 groups = {"readListByPartialTerm"})
150 public void partialTermMatch(String testName) {
151 if (logger.isDebugEnabled()) {
152 logger.debug(testBanner(testName));
154 int numMatchesFound = 0;
155 String partialTerm = getPartialTerm();
156 if (logger.isDebugEnabled()) {
157 logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
159 numMatchesFound = readItemListByPartialTerm(knownResourceId, partialTerm);
160 if (logger.isDebugEnabled()) {
161 logger.debug("Found " + numMatchesFound + " match(es), expected " +
162 NUM_MATCHES_EXPECTED + " match(es).");
164 Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
168 * Read item list by partial term, where the match is case-insensitive.
169 * Tests by attempting a partial match on all-lowercase and all-uppercase
170 * variations of the partial term.
172 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
173 groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
174 public void partialTermMatchCaseInsensitive(String testName) {
175 if (logger.isDebugEnabled()) {
176 logger.debug(testBanner(testName));
178 int numMatchesFound = 0;
180 final String PARTIAL_TERM_LOWERCASE = getPartialTerm().toLowerCase();
181 if (logger.isDebugEnabled()) {
182 logger.debug("Attempting match on partial term '" + PARTIAL_TERM_LOWERCASE + "' ...");
185 readItemListByPartialTerm(knownResourceId, PARTIAL_TERM_LOWERCASE);
186 if (logger.isDebugEnabled()) {
187 logger.debug("Found " + numMatchesFound + " match(es), expected " +
188 NUM_MATCHES_EXPECTED + " match(es).");
190 Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
192 final String PARTIAL_TERM_UPPERCASE = getPartialTerm().toUpperCase();
193 if (logger.isDebugEnabled()) {
194 logger.debug("Attempting match on partial term '" + PARTIAL_TERM_UPPERCASE + "' ...");
197 readItemListByPartialTerm(knownResourceId, PARTIAL_TERM_UPPERCASE);
198 if (logger.isDebugEnabled()) {
199 logger.debug("Found " + numMatchesFound + " match(es), expected " +
200 NUM_MATCHES_EXPECTED + " match(es).");
202 Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
206 * Read item list by partial term, with at least one Unicode UTF-8 character
207 * (outside the USASCII range) in the partial term.
209 // FIXME: Test currently fails with a true UTF-8 String - need to investigate why.
210 // Will be commented out for now until we get this working ...
212 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
213 groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
214 public void partialTermMatchUTF8(String testName) {
215 if (logger.isDebugEnabled()) {
216 logger.debug(testBanner(testName));
218 int numMatchesFound = 0;
219 String partialTerm = getPartialTermUtf8();
220 if (logger.isDebugEnabled()) {
221 logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
224 readItemListByPartialTerm(knownResourceId, partialTerm);
225 if (logger.isDebugEnabled()) {
226 logger.debug("Found " + numMatchesFound + " match(es), expected " +
227 NUM_MATCHES_EXPECTED + " match(es).");
229 Assert.assertEquals(numMatchesFound, NUM_MATCHES_EXPECTED);
236 * Read item list by partial term, where the partial term is not
237 * expected to be matched by any term in any resource.
239 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
240 groups = {"readListByPartialTerm"}, dependsOnMethods = {"partialTermMatch"})
241 public void partialTermMatchOnNonexistentTerm(String testName) {
242 if (logger.isDebugEnabled()) {
243 logger.debug(testBanner(testName));
245 int numMatchesFound = 0;
246 int ZERO_MATCHES_EXPECTED = 0;
247 String partialTerm = getPartialTermNonExistent();
248 if (logger.isDebugEnabled()) {
249 logger.debug("Attempting match on partial term '" + partialTerm + "' ...");
251 numMatchesFound = readItemListByPartialTerm(knownResourceId, partialTerm);
252 // Zero matches are expected on a non-existent term.
253 if (logger.isDebugEnabled()) {
254 logger.debug("Found " + numMatchesFound + " match(es), expected " +
255 ZERO_MATCHES_EXPECTED + " match(es).");
257 Assert.assertEquals(numMatchesFound, ZERO_MATCHES_EXPECTED);
261 * Read item list by partial term.
263 * @param testName The name of the test which has invoked this method.
264 * @param authorityCsid The CSID of the authority within which partial term matching
266 * @param partialTerm A partial term to match item resources.
267 * @return The number of item resources matched by the partial term.
269 private int readItemListByPartialTerm( String authorityCsid, String partialTerm) {
272 int expectedStatusCode = Response.Status.OK.getStatusCode();
273 ServiceRequestType requestType = ServiceRequestType.READ_LIST;
274 String testName = "readItemListByPartialTerm";
275 testSetup(expectedStatusCode, requestType);
277 // Submit the request to the service and store the response.
278 PersonAuthorityClient client = new PersonAuthorityClient();
279 ClientResponse<PersonsCommonList> res = null;
280 if (authorityCsid != null) {
281 res = client.readItemList(authorityCsid, partialTerm);
283 Assert.fail("readItemListByPartialTerm passed null csid!");
285 PersonsCommonList list = null;
287 int statusCode = res.getStatus();
289 // Check the status code of the response: does it match
290 // the expected response(s)?
291 if(logger.isDebugEnabled()){
292 logger.debug(testName + ": status = " + statusCode);
294 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
295 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
296 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
298 list = res.getEntity();
300 res.releaseConnection();
303 List<PersonsCommonList.PersonListItem> items = list.getPersonListItem();
304 int nItemsReturned = items.size();
306 return nItemsReturned;
309 // ---------------------------------------------------------------
310 // Cleanup of resources created during testing
311 // ---------------------------------------------------------------
314 * Deletes all resources created by tests, after all tests have been run.
316 * This cleanup method will always be run, even if one or more tests fail.
317 * For this reason, it attempts to remove all resources created
318 * at any point during testing, even if some of those resources
319 * may be expected to be deleted by certain tests.
321 @AfterClass(alwaysRun=true)
322 public void cleanUp() {
323 String noTest = System.getProperty("noTestCleanup");
324 if(Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
325 if (logger.isDebugEnabled()) {
326 logger.debug("Skipping Cleanup phase ...");
330 if (logger.isDebugEnabled()) {
331 logger.debug("Cleaning up temporary resources created for testing ...");
333 String parentResourceId;
334 String itemResourceId;
335 PersonAuthorityClient client = new PersonAuthorityClient();
336 parentResourceId = knownResourceId;
337 // Clean up item resources.
338 for (Map.Entry<String, String> entry : allItemResourceIdsCreated.entrySet()) {
339 itemResourceId = entry.getKey();
340 parentResourceId = entry.getValue();
341 // Note: Any non-success responses from the delete operation
342 // below are ignored and not reported.
343 ClientResponse<Response> res =
344 client.deleteItem(parentResourceId, itemResourceId);
345 res.releaseConnection();
347 // Clean up authority resources.
348 for (String resourceId : allResourceIdsCreated) {
349 // Note: Any non-success responses are ignored and not reported.
350 client.delete(resourceId).releaseConnection();
354 // ---------------------------------------------------------------
355 // Utility methods used by tests above
356 // ---------------------------------------------------------------
358 * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
361 public String getServicePathComponent() {
362 return SERVICE_PATH_COMPONENT;
365 // ---------------------------------------------------------------
366 // Utilities: setup routines for search tests
367 // ---------------------------------------------------------------
369 public void createAuthority() throws Exception {
372 int expectedStatusCode = Response.Status.CREATED.getStatusCode();
373 ServiceRequestType requestType = ServiceRequestType.CREATE;
374 String testName = "createPersonAuthority";
375 testSetup(expectedStatusCode, requestType, testName);
377 // Submit the request to the service and store the response.
378 PersonAuthorityClient client = new PersonAuthorityClient();
379 String identifier = createIdentifier();
380 String displayName = "displayName-" + identifier;
381 String baseRefName = PersonAuthorityClientUtils.createPersonAuthRefName(displayName, false);
382 String fullRefName = PersonAuthorityClientUtils.createPersonAuthRefName(displayName, true);
383 MultipartOutput multipart =
384 PersonAuthorityClientUtils.createPersonAuthorityInstance(
385 displayName, fullRefName, client.getCommonPartName());
388 ClientResponse<Response> res = client.create(multipart);
390 int statusCode = res.getStatus();
391 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
392 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
393 Assert.assertEquals(statusCode, this.EXPECTED_STATUS_CODE);
394 newID = PersonAuthorityClientUtils.extractId(res);
396 res.releaseConnection();
398 // Store the refname from the first resource created
399 // for additional tests below.
400 knownResourceRefName = baseRefName;
401 // Store the ID returned from the first resource created
402 // for additional tests below.
403 if (knownResourceId == null){
404 knownResourceId = newID;
405 knownResourceRefName = baseRefName;
408 // Store the IDs from every resource created by tests,
409 // so they can be deleted after tests have been run.
410 allResourceIdsCreated.add(newID);
414 * Creates an item in the authority, used for partial term matching tests.
416 * @param authorityCsid The CSID of the Authority in which the term will be created.
417 * @param authRefName The refName of the Authority in which the term will be created.
419 private void createItemInAuthorityForPartialTermMatch(String authorityCsid, String authRefName)
422 int expectedStatusCode = Response.Status.CREATED.getStatusCode();
423 ServiceRequestType requestType = ServiceRequestType.CREATE;
424 String testName = "createItemInAuthorityForPartialTermMatch";
425 testSetup(expectedStatusCode, requestType, testName);
427 // Submit the request to the service and store the response.
428 PersonAuthorityClient client = new PersonAuthorityClient();
429 String refName = PersonAuthorityClientUtils.createPersonRefName(authRefName,
430 TEST_PARTIAL_TERM_DISPLAY_NAME, true);
431 Map<String, String> partialTermPersonMap = new HashMap<String,String>();
433 // Fill the property map
435 partialTermPersonMap.put(PersonJAXBSchema.DISPLAY_NAME_COMPUTED, "false");
436 partialTermPersonMap.put(PersonJAXBSchema.DISPLAY_NAME, TEST_PARTIAL_TERM_DISPLAY_NAME);
437 partialTermPersonMap.put(PersonJAXBSchema.FORE_NAME, TEST_PARTIAL_TERM_FORE_NAME);
438 partialTermPersonMap.put(PersonJAXBSchema.SUR_NAME, TEST_PARTIAL_TERM_SUR_NAME);
439 partialTermPersonMap.put(PersonJAXBSchema.GENDER, "male");
440 MultipartOutput multipart =
441 PersonAuthorityClientUtils.createPersonInstance(authorityCsid, refName, partialTermPersonMap,
442 client.getItemCommonPartName() );
445 ClientResponse<Response> res = client.createItem(authorityCsid, multipart);
447 int statusCode = res.getStatus();
448 // Check the status code of the response: does it match
449 // the expected response(s)?
450 if(logger.isDebugEnabled()){
451 logger.debug(testName + ": status = " + statusCode);
453 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
454 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
455 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
457 newID = PersonAuthorityClientUtils.extractId(res);
459 res.releaseConnection();
462 // Store the ID returned from the first item resource created
463 // for additional tests below.
464 if (knownItemResourceId == null){
465 knownItemResourceId = newID;
466 if (logger.isDebugEnabled()) {
467 logger.debug(testName + ": knownItemPartialTermResourceId=" + knownItemPartialTermResourceId);
471 // Store the IDs from any item resources created
472 // by tests, along with the IDs of their parents, so these items
473 // can be deleted after all tests have been run.
474 allItemResourceIdsCreated.put(newID, authorityCsid);