2 * This document is a part of the source code and related artifacts for
3 * CollectionSpace, an open source collections management system for museums and
4 * related institutions:
6 * http://www.collectionspace.org http://wiki.collectionspace.org
8 * Copyright (c)) 2009 Regents of the University of California
10 * Licensed under the Educational Community License (ECL), Version 2.0. You may
11 * not use this file except in compliance with this License.
13 * You may obtain a copy of the ECL 2.0 License at
14 * https://source.collectionspace.org/collection-space/LICENSE.txt
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19 * License for the specific language governing permissions and limitations under
22 package org.collectionspace.services.client.test;
24 import java.util.HashMap;
25 import java.util.List;
28 import org.collectionspace.services.TaxonJAXBSchema;
29 import org.collectionspace.services.client.AbstractCommonListUtils;
30 import org.collectionspace.services.client.AuthorityClient;
31 import org.collectionspace.services.client.CollectionSpaceClient;
32 import org.collectionspace.services.client.PayloadOutputPart;
33 import org.collectionspace.services.client.PoxPayloadIn;
34 import org.collectionspace.services.client.PoxPayloadOut;
35 import org.collectionspace.services.client.TaxonomyAuthorityClient;
36 import org.collectionspace.services.client.TaxonomyAuthorityClientUtils;
37 import org.collectionspace.services.client.TaxonomyAuthorityProxy;
38 import org.collectionspace.services.jaxb.AbstractCommonList;
39 import org.collectionspace.services.taxonomy.CommonNameGroupList;
40 import org.collectionspace.services.taxonomy.TaxonAuthorGroup;
41 import org.collectionspace.services.taxonomy.TaxonAuthorGroupList;
42 import org.collectionspace.services.taxonomy.TaxonCitationList;
43 import org.collectionspace.services.taxonomy.TaxonomyauthorityCommon;
44 import org.collectionspace.services.taxonomy.TaxonCommon;
46 import javax.ws.rs.core.Response;
47 import org.collectionspace.services.taxonomy.*;
48 import org.jboss.resteasy.client.ClientResponse;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
53 import org.testng.Assert;
54 import org.testng.annotations.AfterClass;
55 import org.testng.annotations.Test;
58 * TaxonomyAuthorityServiceTest, carries out tests against a deployed and
59 * running TaxonomyAuthority Service.
61 * $LastChangedRevision$ $LastChangedDate$
63 public class TaxonomyAuthorityServiceTest extends AbstractAuthorityServiceTest<TaxonomyauthorityCommon, TaxonCommon> {
68 private final String CLASS_NAME = TaxonomyAuthorityServiceTest.class.getName();
69 private final Logger logger = LoggerFactory.getLogger(TaxonomyAuthorityServiceTest.class);
70 private final String TEST_SHORTID = "CentauruspleurexanthemusGreen1832";
71 private final String TEST_TERM_STATUS = "accepted";
72 private final String TEST_TAXON_FULL_NAME = "Centaurus pleurexanthemus Green 1832";
73 // TODO Re-implement the Taxon Rank field so as to provide an orderable
74 // ranking value, as well as a display name.
75 private final String TEST_TAXON_RANK = "species";
76 private final String TEST_TAXON_AUTHOR = "J. Green";
77 private final String TEST_TAXON_AUTHOR_TYPE = "ascribed";
78 private final String TEST_TAXON_CITATION = "A Monograph of the Trilobites of North America";
79 private final String TEST_TAXON_CURRENCY = "current";
80 private final String TEST_TAXON_YEAR = "1832";
81 private final String TEST_TAXONOMIC_STATUS = "valid";
82 private final String TEST_TAXON_IS_NAMED_HYBRID = "false";
83 private final List<TaxonTermGroup> NULL_TAXON_TERMS_LIST = null;
84 private final TaxonAuthorGroupList NULL_TAXON_AUTHOR_GROUP_LIST = null;
85 private final TaxonCitationList NULL_TAXON_CITATION_LIST = null;
86 private final CommonNameGroupList NULL_COMMON_NAME_GROUP_LIST = null;
88 private String knownResourceShortIdentifer = null;
89 private String knownTaxonomyTypeRefName = null;
92 public String getServicePathComponent() {
93 return TaxonomyAuthorityClient.SERVICE_PATH_COMPONENT;
97 protected String getServiceName() {
98 return TaxonomyAuthorityClient.SERVICE_NAME;
101 public String getItemServicePathComponent() {
102 return AuthorityClient.ITEMS;
107 * org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
110 protected CollectionSpaceClient<AbstractCommonList, PoxPayloadOut, String, TaxonomyAuthorityProxy> getClientInstance() {
111 return new TaxonomyAuthorityClient();
115 * Creates the item in authority.
117 * @param vcsid the vcsid
118 * @param authRefName the auth ref name
121 private String createItemInAuthority(String vcsid, String authRefName) {
123 final String testName = "createItemInAuthority(" + vcsid + "," + authRefName + ")";
124 if (logger.isDebugEnabled()) {
125 logger.debug(getTestBanner(testName, CLASS_NAME));
128 // Submit the request to the service and store the response.
129 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
130 Map<String, String> taxonMap = new HashMap<String, String>();
132 // Fields present in all authority records.
133 taxonMap.put(TaxonJAXBSchema.SHORT_IDENTIFIER, TEST_SHORTID);
134 // TODO Make term status be controlled vocab.
135 taxonMap.put(TaxonJAXBSchema.TERM_STATUS, TEST_TERM_STATUS);
137 // Fields specific to this specific authority record type.
138 taxonMap.put(TaxonJAXBSchema.NAME, TEST_TAXON_FULL_NAME);
139 taxonMap.put(TaxonJAXBSchema.TAXON_RANK, TEST_TAXON_RANK);
140 taxonMap.put(TaxonJAXBSchema.TAXON_CURRENCY, TEST_TAXON_CURRENCY);
141 taxonMap.put(TaxonJAXBSchema.TAXON_YEAR, TEST_TAXON_YEAR);
142 taxonMap.put(TaxonJAXBSchema.TAXONOMIC_STATUS, TEST_TAXONOMIC_STATUS);
143 taxonMap.put(TaxonJAXBSchema.TAXON_IS_NAMED_HYBRID, TEST_TAXON_IS_NAMED_HYBRID);
145 TaxonCitationList taxonCitationList = new TaxonCitationList();
146 List<String> taxonCitations = taxonCitationList.getTaxonCitation();
147 taxonCitations.add(TEST_TAXON_CITATION);
149 TaxonAuthorGroupList taxonAuthorGroupList = new TaxonAuthorGroupList();
150 List<TaxonAuthorGroup> taxonAuthorGroups = taxonAuthorGroupList.getTaxonAuthorGroup();
151 TaxonAuthorGroup taxonAuthorGroup = new TaxonAuthorGroup();
152 taxonAuthorGroup.setTaxonAuthor(TEST_TAXON_AUTHOR);
153 taxonAuthorGroup.setTaxonAuthorType(TEST_TAXON_AUTHOR_TYPE);
154 taxonAuthorGroups.add(taxonAuthorGroup);
156 CommonNameGroupList commonNameGroupList = new CommonNameGroupList();
157 List<CommonNameGroup> commonNameGroups = commonNameGroupList.getCommonNameGroup();
158 CommonNameGroup commonNameGroup = new CommonNameGroup();
159 commonNameGroup.setCommonName(TEST_TAXON_FULL_NAME);
160 commonNameGroups.add(commonNameGroup);
162 // FIXME: Add additional fields in the Taxon record here,
163 // including at least one each of:
164 // * a Boolean field (when implemented)
165 // * an authref field (when implemented)
167 String newID = TaxonomyAuthorityClientUtils.createItemInAuthority(vcsid,
168 authRefName, taxonMap, NULL_TAXON_TERMS_LIST, taxonAuthorGroupList,
169 taxonCitationList, commonNameGroupList, client);
171 // Store the ID returned from the first item resource created
172 // for additional tests below.
173 if (knownItemResourceId == null) {
174 setKnownItemResource(newID, TEST_SHORTID);
175 if (logger.isDebugEnabled()) {
176 logger.debug(testName + ": knownItemResourceId=" + newID + " inAuthority=" + vcsid);
180 // Store the IDs from any item resources created
181 // by tests, along with the IDs of their parents, so these items
182 // can be deleted after all tests have been run.
183 allResourceItemIdsCreated.put(newID, vcsid);
189 * Verify illegal item display name.
191 * @param testName the test name
192 * @throws Exception the exception
194 @Test(dataProvider = "testName")
195 public void verifyIllegalItemDisplayName(String testName) throws Exception {
197 // First read in our known resource.
200 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
201 Response res = client.readItem(knownResourceId, knownItemResourceId);
202 TaxonCommon taxon = null;
204 assertStatusCode(res, testName);
205 // Check whether Taxonomy has expected displayName.
206 PoxPayloadIn input = new PoxPayloadIn((String)res.getEntity());
207 taxon = (TaxonCommon) extractPart(input,
208 client.getItemCommonPartName(), TaxonCommon.class);
209 Assert.assertNotNull(taxon);
216 // Make an invalid UPDATE request, without a display name
218 TaxonTermGroupList termList = taxon.getTaxonTermGroupList();
219 Assert.assertNotNull(termList);
220 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
221 Assert.assertNotNull(terms);
222 Assert.assertTrue(terms.size() > 0);
223 terms.get(0).setTermDisplayName(null);
224 terms.get(0).setTermName(null);
226 PoxPayloadOut output = new PoxPayloadOut(TaxonomyAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
227 PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), taxon);
228 setupUpdateWithInvalidBody(); // we expect a failure here
229 res = client.updateItem(knownResourceId, knownItemResourceId, output);
231 assertStatusCode(res, testName);
240 @Test(dataProvider = "testName", groups = {"readList"},
241 dependsOnMethods = {"readList"})
242 public void readItemList(String testName) {
243 readItemList(knownAuthorityWithItems, null);
247 * Read item list by authority name.
249 @Test(dataProvider = "testName", groups = {"readList"},
250 dependsOnMethods = {"readItemList"})
251 public void readItemListByAuthorityName(String testName) {
252 readItemList(null, READITEMS_SHORT_IDENTIFIER);
258 * @param vcsid the vcsid
259 * @param name the name
261 private void readItemList(String vcsid, String shortId) {
262 String testName = "readItemList";
267 // Submit the request to the service and store the response.
268 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
271 res = client.readItemList(vcsid, null, null);
272 } else if (shortId != null) {
273 res = client.readItemListForNamedAuthority(shortId, null, null);
275 Assert.fail("readItemList passed null csid and name!");
278 assertStatusCode(res, testName);
279 AbstractCommonList list = res.readEntity(AbstractCommonList.class);
280 int statusCode = res.getStatus();
282 // Check the status code of the response: does it match
283 // the expected response(s)?
284 if (logger.isDebugEnabled()) {
285 logger.debug(testName + ": status = " + statusCode);
287 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
288 invalidStatusCodeMessage(testRequestType, statusCode));
289 Assert.assertEquals(statusCode, testExpectedStatusCode);
291 List<AbstractCommonList.ListItem> items = list.getListItem();
292 int nItemsReturned = items.size();
293 // There will be 'nItemsToCreateInList'
294 // items created by the createItemList test,
295 // all associated with the same parent resource.
296 int nExpectedItems = nItemsToCreateInList;
297 if (logger.isDebugEnabled()) {
298 logger.debug(testName + ": Expected "
299 + nExpectedItems + " items; got: " + nItemsReturned);
301 Assert.assertEquals(nItemsReturned, nExpectedItems);
303 for (AbstractCommonList.ListItem item : items) {
305 AbstractCommonListUtils.ListItemGetElementValue(item, TaxonJAXBSchema.REF_NAME);
306 Assert.assertTrue((null != value), "Item refName is null!");
308 AbstractCommonListUtils.ListItemGetElementValue(item, TaxonJAXBSchema.TERM_DISPLAY_NAME);
309 Assert.assertTrue((null != value), "Item termDisplayName is null!");
311 if (logger.isTraceEnabled()) {
312 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
320 public void delete(String testName) throws Exception {
321 // Do nothing. See localDelete(). This ensure proper test order.
324 @Test(dataProvider = "testName", dependsOnMethods = {"localDeleteItem"})
325 public void localDelete(String testName) throws Exception {
326 super.delete(testName);
330 public void deleteItem(String testName) throws Exception {
331 // Do nothing. We need to wait until after the test "localDelete" gets run. When it does,
332 // its dependencies will get run first and then we can call the base class' delete method.
335 @Test(dataProvider = "testName", groups = {"delete"},
336 dependsOnMethods = {"verifyIllegalItemDisplayName"})
337 public void localDeleteItem(String testName) throws Exception {
338 super.deleteItem(testName);
341 // ---------------------------------------------------------------
342 // Cleanup of resources created during testing
343 // ---------------------------------------------------------------
345 * Deletes all resources created by tests, after all tests have been run.
347 * This cleanup method will always be run, even if one or more tests fail.
348 * For this reason, it attempts to remove all resources created at any point
349 * during testing, even if some of those resources may be expected to be
350 * deleted by certain tests.
352 @AfterClass(alwaysRun = true)
353 public void cleanUp() {
354 String noTest = System.getProperty("noTestCleanup");
355 if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
356 if (logger.isDebugEnabled()) {
357 logger.debug("Skipping Cleanup phase ...");
361 if (logger.isDebugEnabled()) {
362 logger.debug("Cleaning up temporary resources created for testing ...");
364 String parentResourceId;
365 String itemResourceId;
366 // Clean up contact resources.
367 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
368 parentResourceId = knownResourceId;
369 // Clean up item resources.
370 for (Map.Entry<String, String> entry : allResourceItemIdsCreated.entrySet()) {
371 itemResourceId = entry.getKey();
372 parentResourceId = entry.getValue();
373 // Note: Any non-success responses from the delete operation
374 // below are ignored and not reported.
375 client.deleteItem(parentResourceId, itemResourceId).close();
378 // Clean up parent resources.
379 for (String resourceId : allResourceIdsCreated) {
380 // Note: Any non-success responses from the delete operation
381 // below are ignored and not reported.
382 client.delete(resourceId).close();
386 // ---------------------------------------------------------------
387 // Utility methods used by tests above
388 // ---------------------------------------------------------------
391 * org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
394 * Returns the root URL for the item service.
396 * This URL consists of a base URL for all services, followed by a path
397 * component for the owning parent, followed by the path component for the
400 * @param parentResourceIdentifier An identifier (such as a UUID) for the
401 * parent authority resource of the relevant item resource.
403 * @return The root URL for the item service.
405 protected String getItemServiceRootURL(String parentResourceIdentifier) {
406 return getResourceURL(parentResourceIdentifier) + "/" + getItemServicePathComponent();
410 * Returns the URL of a specific item resource managed by a service, and
411 * designated by an identifier (such as a universally unique ID, or UUID).
413 * @param parentResourceIdentifier An identifier (such as a UUID) for the
414 * parent authority resource of the relevant item resource.
416 * @param itemResourceIdentifier An identifier (such as a UUID) for an item
419 * @return The URL of a specific item resource managed by a service.
421 protected String getItemResourceURL(String parentResourceIdentifier, String itemResourceIdentifier) {
422 return getItemServiceRootURL(parentResourceIdentifier) + "/" + itemResourceIdentifier;
426 public void authorityTests(String testName) {
427 // TODO Auto-generated method stub
431 // Taxonomy authority specific instances
434 protected PoxPayloadOut createInstance(String commonPartName,
436 String shortId = identifier;
437 String displayName = "displayName-" + shortId;
438 String baseRefName = TaxonomyAuthorityClientUtils.createTaxonomyAuthRefName(shortId, null);
439 PoxPayloadOut multipart = TaxonomyAuthorityClientUtils.createTaxonomyAuthorityInstance(
440 displayName, shortId, commonPartName);
445 protected PoxPayloadOut createNonExistenceInstance(String commonPartName, String identifier) {
446 String displayName = "displayName-NON_EXISTENT_ID";
447 PoxPayloadOut result = TaxonomyAuthorityClientUtils.createTaxonomyAuthorityInstance(
448 displayName, "nonEx", commonPartName);
453 protected TaxonomyauthorityCommon updateInstance(
454 TaxonomyauthorityCommon taxonomyAuthority) {
455 TaxonomyauthorityCommon result = new TaxonomyauthorityCommon();
457 result.setDisplayName("updated-" + taxonomyAuthority.getDisplayName());
458 result.setVocabType("updated-" + taxonomyAuthority.getVocabType());
464 protected void compareUpdatedInstances(TaxonomyauthorityCommon original,
465 TaxonomyauthorityCommon updated) throws Exception {
466 // Verify that the updated resource received the correct data.
467 Assert.assertEquals(updated.getDisplayName(),
468 original.getDisplayName(),
469 "Display name in updated object did not match submitted data.");
473 // Authority item specific overrides
476 protected String createItemInAuthority(String authorityId) {
477 return createItemInAuthority(authorityId, null /*
483 protected TaxonCommon updateItemInstance(TaxonCommon taxonCommon) {
484 TaxonCommon result = taxonCommon;
485 TaxonTermGroupList termList = taxonCommon.getTaxonTermGroupList();
486 Assert.assertNotNull(termList);
487 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
488 Assert.assertNotNull(terms);
489 Assert.assertTrue(terms.size() > 0);
490 terms.get(0).setTermDisplayName("updated-" + terms.get(0).getTermDisplayName());
491 terms.get(0).setTermName("updated-" + terms.get(0).getTermName());
492 result.setTaxonTermGroupList(termList);
497 protected void compareUpdatedItemInstances(TaxonCommon original,
498 TaxonCommon updated) throws Exception {
500 TaxonTermGroupList originalTermList = original.getTaxonTermGroupList();
501 Assert.assertNotNull(originalTermList);
502 List<TaxonTermGroup> originalTerms = originalTermList.getTaxonTermGroup();
503 Assert.assertNotNull(originalTerms);
504 Assert.assertTrue(originalTerms.size() > 0);
506 TaxonTermGroupList updatedTermList = updated.getTaxonTermGroupList();
507 Assert.assertNotNull(updatedTermList);
508 List<TaxonTermGroup> updatedTerms = updatedTermList.getTaxonTermGroup();
509 Assert.assertNotNull(updatedTerms);
510 Assert.assertTrue(updatedTerms.size() > 0);
512 Assert.assertEquals(updatedTerms.get(0).getTermDisplayName(),
513 originalTerms.get(0).getTermDisplayName(),
514 "Value in updated record did not match submitted data.");
518 protected void verifyReadItemInstance(TaxonCommon item) throws Exception {
520 TaxonTermGroupList termList = item.getTaxonTermGroupList();
521 Assert.assertNotNull(termList);
522 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
523 Assert.assertNotNull(terms);
524 Assert.assertTrue(terms.size() > 0);
526 String preferredTermName = terms.get(0).getTermName();
527 Assert.assertNotNull(preferredTermName, "Field value is unexpectedly null.");
528 Assert.assertEquals(preferredTermName, TEST_TAXON_FULL_NAME,
529 "Field value " + preferredTermName
530 + "does not match expected value " + TEST_TAXON_FULL_NAME);
534 protected PoxPayloadOut createNonExistenceItemInstance(
535 String commonPartName, String identifier) {
536 Map<String, String> nonexMap = new HashMap<String, String>();
537 nonexMap.put(TaxonJAXBSchema.NAME, TEST_TAXON_FULL_NAME);
538 nonexMap.put(TaxonJAXBSchema.SHORT_IDENTIFIER, "nonEx");
539 nonexMap.put(TaxonJAXBSchema.TERM_STATUS, TEST_TERM_STATUS);
540 final String EMPTY_REFNAME = "";
541 PoxPayloadOut result =
542 TaxonomyAuthorityClientUtils.createTaxonInstance(EMPTY_REFNAME,
543 nonexMap, NULL_TAXON_TERMS_LIST, NULL_TAXON_AUTHOR_GROUP_LIST, NULL_TAXON_CITATION_LIST,
544 NULL_COMMON_NAME_GROUP_LIST, commonPartName);