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;
40 import org.collectionspace.services.taxonomy.CommonNameGroup;
41 import org.collectionspace.services.taxonomy.CommonNameGroupList;
42 import org.collectionspace.services.taxonomy.TaxonAuthorGroup;
43 import org.collectionspace.services.taxonomy.TaxonAuthorGroupList;
44 import org.collectionspace.services.taxonomy.TaxonCitationList;
45 import org.collectionspace.services.taxonomy.TaxonCommon;
46 import org.collectionspace.services.taxonomy.TaxonTermGroup;
47 import org.collectionspace.services.taxonomy.TaxonTermGroupList;
48 import org.collectionspace.services.taxonomy.TaxonomyauthorityCommon;
50 import javax.ws.rs.core.Response;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.testng.Assert;
55 import org.testng.annotations.AfterClass;
56 import org.testng.annotations.Test;
59 * TaxonomyAuthorityServiceTest, carries out tests against a deployed and
60 * running TaxonomyAuthority Service.
62 * $LastChangedRevision$ $LastChangedDate$
64 public class TaxonomyAuthorityServiceTest extends AbstractAuthorityServiceTest<TaxonomyauthorityCommon, TaxonCommon> {
67 * Default constructor. Used to set the short ID for all tests authority items
69 public TaxonomyAuthorityServiceTest() {
71 TEST_SHORTID = "CentauruspleurexanthemusGreen1832";
77 private final String CLASS_NAME = TaxonomyAuthorityServiceTest.class.getName();
78 private final Logger logger = LoggerFactory.getLogger(TaxonomyAuthorityServiceTest.class);
79 private final String TEST_TERM_STATUS = "accepted";
80 private final String TEST_TAXON_FULL_NAME = "Centaurus pleurexanthemus Green 1832";
81 // TODO Re-implement the Taxon Rank field so as to provide an orderable
82 // ranking value, as well as a display name.
83 private final String TEST_TAXON_RANK = "species";
84 private final String TEST_TAXON_AUTHOR = "J. Green";
85 private final String TEST_TAXON_AUTHOR_TYPE = "ascribed";
86 private final String TEST_TAXON_CITATION = "A Monograph of the Trilobites of North America";
87 private final String TEST_TAXON_CURRENCY = "current";
88 private final String TEST_TAXON_YEAR = "1832";
89 private final String TEST_TAXONOMIC_STATUS = "valid";
90 private final String TEST_TAXON_IS_NAMED_HYBRID = "false";
91 private final List<TaxonTermGroup> NULL_TAXON_TERMS_LIST = null;
92 private final TaxonAuthorGroupList NULL_TAXON_AUTHOR_GROUP_LIST = null;
93 private final TaxonCitationList NULL_TAXON_CITATION_LIST = null;
94 private final CommonNameGroupList NULL_COMMON_NAME_GROUP_LIST = null;
97 public String getServicePathComponent() {
98 return TaxonomyAuthorityClient.SERVICE_PATH_COMPONENT;
102 protected String getServiceName() {
103 return TaxonomyAuthorityClient.SERVICE_NAME;
106 public String getItemServicePathComponent() {
107 return AuthorityClient.ITEMS;
112 * org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
115 protected CollectionSpaceClient<AbstractCommonList, PoxPayloadOut, String, TaxonomyAuthorityProxy> getClientInstance() {
116 return new TaxonomyAuthorityClient();
120 protected CollectionSpaceClient<AbstractCommonList, PoxPayloadOut, String, TaxonomyAuthorityProxy> getClientInstance(String clientPropertiesFilename) {
121 return new TaxonomyAuthorityClient(clientPropertiesFilename);
125 protected String createItemInAuthority(AuthorityClient client, String authorityId, String shortId) {
126 return createItemInAuthority(client, authorityId, shortId, null /** refname */);
130 * Creates the item in authority.
132 * @param vcsid the vcsid
133 * @param authRefName the auth ref name
136 private String createItemInAuthority(AuthorityClient client, String vcsid, String shortId, String authRefName) {
138 final String testName = "createItemInAuthority(" + vcsid + "," + authRefName + ")";
139 if (logger.isDebugEnabled()) {
140 logger.debug(getTestBanner(testName, CLASS_NAME));
143 // Submit the request to the service and store the response.
144 Map<String, String> taxonMap = new HashMap<String, String>();
146 // Fields present in all authority records.
147 taxonMap.put(TaxonJAXBSchema.SHORT_IDENTIFIER, shortId);
148 // TODO Make term status be controlled vocab.
149 taxonMap.put(TaxonJAXBSchema.TERM_STATUS, TEST_TERM_STATUS);
151 // Fields specific to this specific authority record type.
152 taxonMap.put(TaxonJAXBSchema.NAME, TEST_TAXON_FULL_NAME);
153 taxonMap.put(TaxonJAXBSchema.TAXON_RANK, TEST_TAXON_RANK);
154 taxonMap.put(TaxonJAXBSchema.TAXON_CURRENCY, TEST_TAXON_CURRENCY);
155 taxonMap.put(TaxonJAXBSchema.TAXON_YEAR, TEST_TAXON_YEAR);
156 taxonMap.put(TaxonJAXBSchema.TAXONOMIC_STATUS, TEST_TAXONOMIC_STATUS);
157 taxonMap.put(TaxonJAXBSchema.TAXON_IS_NAMED_HYBRID, TEST_TAXON_IS_NAMED_HYBRID);
159 TaxonCitationList taxonCitationList = new TaxonCitationList();
160 List<String> taxonCitations = taxonCitationList.getTaxonCitation();
161 taxonCitations.add(TEST_TAXON_CITATION);
163 TaxonAuthorGroupList taxonAuthorGroupList = new TaxonAuthorGroupList();
164 List<TaxonAuthorGroup> taxonAuthorGroups = taxonAuthorGroupList.getTaxonAuthorGroup();
165 TaxonAuthorGroup taxonAuthorGroup = new TaxonAuthorGroup();
166 taxonAuthorGroup.setTaxonAuthor(TEST_TAXON_AUTHOR);
167 taxonAuthorGroup.setTaxonAuthorType(TEST_TAXON_AUTHOR_TYPE);
168 taxonAuthorGroups.add(taxonAuthorGroup);
170 CommonNameGroupList commonNameGroupList = new CommonNameGroupList();
171 List<CommonNameGroup> commonNameGroups = commonNameGroupList.getCommonNameGroup();
172 CommonNameGroup commonNameGroup = new CommonNameGroup();
173 commonNameGroup.setCommonName(TEST_TAXON_FULL_NAME);
174 commonNameGroups.add(commonNameGroup);
176 // FIXME: Add additional fields in the Taxon record here,
177 // including at least one each of:
178 // * a Boolean field (when implemented)
179 // * an authref field (when implemented)
181 String newID = TaxonomyAuthorityClientUtils.createItemInAuthority(vcsid,
182 authRefName, taxonMap, NULL_TAXON_TERMS_LIST, taxonAuthorGroupList,
183 taxonCitationList, commonNameGroupList, (TaxonomyAuthorityClient)client);
185 // Store the ID returned from the first item resource created
186 // for additional tests below.
187 if (knownItemResourceId == null) {
188 setKnownItemResource(newID, shortId);
189 if (logger.isDebugEnabled()) {
190 logger.debug(testName + ": knownItemResourceId=" + newID + " inAuthority=" + vcsid);
194 // Store the IDs from any item resources created
195 // by tests, along with the IDs of their parents, so these items
196 // can be deleted after all tests have been run.
197 allResourceItemIdsCreated.put(newID, vcsid);
203 * Verify illegal item display name.
205 * @param testName the test name
206 * @throws Exception the exception
208 @Test(dataProvider = "testName")
209 public void verifyIllegalItemDisplayName(String testName) throws Exception {
211 // First read in our known resource.
214 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
215 Response res = client.readItem(knownResourceId, knownItemResourceId);
216 TaxonCommon taxon = null;
218 assertStatusCode(res, testName);
219 // Check whether Taxonomy has expected displayName.
220 PoxPayloadIn input = new PoxPayloadIn(res.readEntity(String.class));
221 taxon = (TaxonCommon) extractPart(input,
222 client.getItemCommonPartName(), TaxonCommon.class);
223 Assert.assertNotNull(taxon);
230 // Make an invalid UPDATE request, without a display name
232 TaxonTermGroupList termList = taxon.getTaxonTermGroupList();
233 Assert.assertNotNull(termList);
234 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
235 Assert.assertNotNull(terms);
236 Assert.assertTrue(terms.size() > 0);
237 terms.get(0).setTermDisplayName(null);
238 terms.get(0).setTermName(null);
240 PoxPayloadOut output = new PoxPayloadOut(TaxonomyAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
241 PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), taxon);
242 setupUpdateWithInvalidBody(); // we expect a failure here
243 res = client.updateItem(knownResourceId, knownItemResourceId, output);
245 assertStatusCode(res, testName);
254 @Test(dataProvider = "testName", groups = {"readList"},
255 dependsOnMethods = {"readList"})
256 public void readItemList(String testName) {
257 readItemList(knownAuthorityWithItems, null);
261 * Read item list by authority name.
263 @Test(dataProvider = "testName", groups = {"readList"},
264 dependsOnMethods = {"readItemList"})
265 public void readItemListByAuthorityName(String testName) {
266 readItemList(null, READITEMS_SHORT_IDENTIFIER);
272 * @param vcsid the vcsid
273 * @param name the name
275 private void readItemList(String vcsid, String shortId) {
276 String testName = "readItemList";
281 // Submit the request to the service and store the response.
282 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
285 res = client.readItemList(vcsid, null, null);
286 } else if (shortId != null) {
287 res = client.readItemListForNamedAuthority(shortId, null, null);
289 Assert.fail("readItemList passed null csid and name!");
292 assertStatusCode(res, testName);
293 AbstractCommonList list = res.readEntity(AbstractCommonList.class);
294 int statusCode = res.getStatus();
296 // Check the status code of the response: does it match
297 // the expected response(s)?
298 if (logger.isDebugEnabled()) {
299 logger.debug(testName + ": status = " + statusCode);
301 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
302 invalidStatusCodeMessage(testRequestType, statusCode));
303 Assert.assertEquals(statusCode, testExpectedStatusCode);
305 List<AbstractCommonList.ListItem> items = list.getListItem();
306 int nItemsReturned = items.size();
307 // There will be 'nItemsToCreateInList'
308 // items created by the createItemList test,
309 // all associated with the same parent resource.
310 int nExpectedItems = nItemsToCreateInList;
311 if (logger.isDebugEnabled()) {
312 logger.debug(testName + ": Expected "
313 + nExpectedItems + " items; got: " + nItemsReturned);
315 Assert.assertEquals(nItemsReturned, nExpectedItems);
317 for (AbstractCommonList.ListItem item : items) {
319 AbstractCommonListUtils.ListItemGetElementValue(item, TaxonJAXBSchema.REF_NAME);
320 Assert.assertTrue((null != value), "Item refName is null!");
322 AbstractCommonListUtils.ListItemGetElementValue(item, TaxonJAXBSchema.TERM_DISPLAY_NAME);
323 Assert.assertTrue((null != value), "Item termDisplayName is null!");
325 if (logger.isTraceEnabled()) {
326 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
334 public void delete(String testName) throws Exception {
335 // Do nothing. See localDelete(). This ensure proper test order.
338 @Test(dataProvider = "testName", dependsOnMethods = {"localDeleteItem"})
339 public void localDelete(String testName) throws Exception {
340 super.delete(testName);
344 public void deleteItem(String testName) throws Exception {
345 // Do nothing. We need to wait until after the test "localDelete" gets run. When it does,
346 // its dependencies will get run first and then we can call the base class' delete method.
349 @Test(dataProvider = "testName", groups = {"delete"},
350 dependsOnMethods = {"verifyIllegalItemDisplayName"})
351 public void localDeleteItem(String testName) throws Exception {
352 super.deleteItem(testName);
355 // ---------------------------------------------------------------
356 // Cleanup of resources created during testing
357 // ---------------------------------------------------------------
359 * Deletes all resources created by tests, after all tests have been run.
361 * This cleanup method will always be run, even if one or more tests fail.
362 * For this reason, it attempts to remove all resources created at any point
363 * during testing, even if some of those resources may be expected to be
364 * deleted by certain tests.
366 @AfterClass(alwaysRun = true)
367 public void cleanUp() {
368 String noTest = System.getProperty("noTestCleanup");
369 if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
370 if (logger.isDebugEnabled()) {
371 logger.debug("Skipping Cleanup phase ...");
375 if (logger.isDebugEnabled()) {
376 logger.debug("Cleaning up temporary resources created for testing ...");
378 String parentResourceId;
379 String itemResourceId;
380 // Clean up contact resources.
381 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
382 parentResourceId = knownResourceId;
383 // Clean up item resources.
384 for (Map.Entry<String, String> entry : allResourceItemIdsCreated.entrySet()) {
385 itemResourceId = entry.getKey();
386 parentResourceId = entry.getValue();
387 // Note: Any non-success responses from the delete operation
388 // below are ignored and not reported.
389 client.deleteItem(parentResourceId, itemResourceId).close();
392 // Clean up parent resources.
393 for (String resourceId : allResourceIdsCreated) {
394 // Note: Any non-success responses from the delete operation
395 // below are ignored and not reported.
396 client.delete(resourceId).close();
400 // ---------------------------------------------------------------
401 // Utility methods used by tests above
402 // ---------------------------------------------------------------
405 * org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
408 * Returns the root URL for the item service.
410 * This URL consists of a base URL for all services, followed by a path
411 * component for the owning parent, followed by the path component for the
414 * @param parentResourceIdentifier An identifier (such as a UUID) for the
415 * parent authority resource of the relevant item resource.
417 * @return The root URL for the item service.
419 protected String getItemServiceRootURL(String parentResourceIdentifier) {
420 return getResourceURL(parentResourceIdentifier) + "/" + getItemServicePathComponent();
424 * Returns the URL of a specific item resource managed by a service, and
425 * designated by an identifier (such as a universally unique ID, or UUID).
427 * @param parentResourceIdentifier An identifier (such as a UUID) for the
428 * parent authority resource of the relevant item resource.
430 * @param itemResourceIdentifier An identifier (such as a UUID) for an item
433 * @return The URL of a specific item resource managed by a service.
435 protected String getItemResourceURL(String parentResourceIdentifier, String itemResourceIdentifier) {
436 return getItemServiceRootURL(parentResourceIdentifier) + "/" + itemResourceIdentifier;
440 public void authorityTests(String testName) {
441 // TODO Auto-generated method stub
445 // Taxonomy authority specific instances
448 protected PoxPayloadOut createInstance(String commonPartName,
450 String shortId = identifier;
451 String displayName = "displayName-" + shortId;
452 PoxPayloadOut multipart = TaxonomyAuthorityClientUtils.createTaxonomyAuthorityInstance(
453 displayName, shortId, commonPartName);
458 protected PoxPayloadOut createNonExistenceInstance(String commonPartName, String identifier) {
459 String displayName = "displayName-NON_EXISTENT_ID";
460 PoxPayloadOut result = TaxonomyAuthorityClientUtils.createTaxonomyAuthorityInstance(
461 displayName, "nonEx", commonPartName);
466 protected TaxonomyauthorityCommon updateInstance(
467 TaxonomyauthorityCommon taxonomyAuthority) {
468 TaxonomyauthorityCommon result = new TaxonomyauthorityCommon();
470 result.setDisplayName("updated-" + taxonomyAuthority.getDisplayName());
471 result.setVocabType("updated-" + taxonomyAuthority.getVocabType());
477 protected void compareUpdatedInstances(TaxonomyauthorityCommon original,
478 TaxonomyauthorityCommon updated) throws Exception {
479 // Verify that the updated resource received the correct data.
480 Assert.assertEquals(updated.getDisplayName(),
481 original.getDisplayName(),
482 "Display name in updated object did not match submitted data.");
486 // Authority item specific overrides
489 protected TaxonCommon updateItemInstance(TaxonCommon taxonCommon) {
490 TaxonCommon result = taxonCommon;
491 TaxonTermGroupList termList = taxonCommon.getTaxonTermGroupList();
492 Assert.assertNotNull(termList);
493 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
494 Assert.assertNotNull(terms);
495 Assert.assertTrue(terms.size() > 0);
496 terms.get(0).setTermDisplayName("updated-" + terms.get(0).getTermDisplayName());
497 terms.get(0).setTermName("updated-" + terms.get(0).getTermName());
498 result.setTaxonTermGroupList(termList);
503 protected void compareUpdatedItemInstances(TaxonCommon original,
504 TaxonCommon updated) throws Exception {
506 TaxonTermGroupList originalTermList = original.getTaxonTermGroupList();
507 Assert.assertNotNull(originalTermList);
508 List<TaxonTermGroup> originalTerms = originalTermList.getTaxonTermGroup();
509 Assert.assertNotNull(originalTerms);
510 Assert.assertTrue(originalTerms.size() > 0);
512 TaxonTermGroupList updatedTermList = updated.getTaxonTermGroupList();
513 Assert.assertNotNull(updatedTermList);
514 List<TaxonTermGroup> updatedTerms = updatedTermList.getTaxonTermGroup();
515 Assert.assertNotNull(updatedTerms);
516 Assert.assertTrue(updatedTerms.size() > 0);
518 Assert.assertEquals(updatedTerms.get(0).getTermDisplayName(),
519 originalTerms.get(0).getTermDisplayName(),
520 "Value in updated record did not match submitted data.");
524 protected void verifyReadItemInstance(TaxonCommon item) throws Exception {
526 TaxonTermGroupList termList = item.getTaxonTermGroupList();
527 Assert.assertNotNull(termList);
528 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
529 Assert.assertNotNull(terms);
530 Assert.assertTrue(terms.size() > 0);
532 String preferredTermName = terms.get(0).getTermName();
533 Assert.assertNotNull(preferredTermName, "Field value is unexpectedly null.");
534 Assert.assertEquals(preferredTermName, TEST_TAXON_FULL_NAME,
535 "Field value " + preferredTermName
536 + "does not match expected value " + TEST_TAXON_FULL_NAME);
540 protected PoxPayloadOut createNonExistenceItemInstance(
541 String commonPartName, String identifier) {
542 Map<String, String> nonexMap = new HashMap<String, String>();
543 nonexMap.put(TaxonJAXBSchema.NAME, TEST_TAXON_FULL_NAME);
544 nonexMap.put(TaxonJAXBSchema.SHORT_IDENTIFIER, "nonEx");
545 nonexMap.put(TaxonJAXBSchema.TERM_STATUS, TEST_TERM_STATUS);
546 final String EMPTY_REFNAME = "";
547 PoxPayloadOut result =
548 TaxonomyAuthorityClientUtils.createTaxonInstance(EMPTY_REFNAME,
549 nonexMap, NULL_TAXON_TERMS_LIST, NULL_TAXON_AUTHOR_GROUP_LIST, NULL_TAXON_CITATION_LIST,
550 NULL_COMMON_NAME_GROUP_LIST, commonPartName);