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;
48 import org.collectionspace.services.taxonomy.*;
49 import org.jboss.resteasy.client.ClientResponse;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52 import org.testng.Assert;
53 import org.testng.annotations.AfterClass;
54 import org.testng.annotations.Test;
57 * TaxonomyAuthorityServiceTest, carries out tests against a deployed and
58 * running TaxonomyAuthority Service.
60 * $LastChangedRevision$ $LastChangedDate$
62 public class TaxonomyAuthorityServiceTest extends AbstractAuthorityServiceTest<TaxonomyauthorityCommon, TaxonCommon> {
67 private final String CLASS_NAME = TaxonomyAuthorityServiceTest.class.getName();
68 private final Logger logger = LoggerFactory.getLogger(TaxonomyAuthorityServiceTest.class);
69 private final String TEST_SHORTID = "CentauruspleurexanthemusGreen1832";
70 private final String TEST_TERM_STATUS = "accepted";
71 private final String TEST_TAXON_FULL_NAME = "Centaurus pleurexanthemus Green 1832";
72 // TODO Re-implement the Taxon Rank field so as to provide an orderable
73 // ranking value, as well as a display name.
74 private final String TEST_TAXON_RANK = "species";
75 private final String TEST_TAXON_AUTHOR = "J. Green";
76 private final String TEST_TAXON_AUTHOR_TYPE = "ascribed";
77 private final String TEST_TAXON_CITATION = "A Monograph of the Trilobites of North America";
78 private final String TEST_TAXON_CURRENCY = "current";
79 private final String TEST_TAXON_YEAR = "1832";
80 private final String TEST_TAXONOMIC_STATUS = "valid";
81 private final String TEST_TAXON_IS_NAMED_HYBRID = "false";
82 private final List<TaxonTermGroup> NULL_TAXON_TERMS_LIST = null;
83 private final TaxonAuthorGroupList NULL_TAXON_AUTHOR_GROUP_LIST = null;
84 private final TaxonCitationList NULL_TAXON_CITATION_LIST = null;
85 private final CommonNameGroupList NULL_COMMON_NAME_GROUP_LIST = null;
87 private String knownResourceShortIdentifer = null;
88 private String knownTaxonomyTypeRefName = null;
91 public String getServicePathComponent() {
92 return TaxonomyAuthorityClient.SERVICE_PATH_COMPONENT;
96 protected String getServiceName() {
97 return TaxonomyAuthorityClient.SERVICE_NAME;
100 public String getItemServicePathComponent() {
101 return AuthorityClient.ITEMS;
106 * org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
109 protected CollectionSpaceClient<AbstractCommonList, PoxPayloadOut, String, TaxonomyAuthorityProxy> getClientInstance() {
110 return new TaxonomyAuthorityClient();
114 protected CollectionSpaceClient<AbstractCommonList, PoxPayloadOut, String, TaxonomyAuthorityProxy> getClientInstance(String clientPropertiesFilename) {
115 return new TaxonomyAuthorityClient(clientPropertiesFilename);
119 * Creates the item in authority.
121 * @param vcsid the vcsid
122 * @param authRefName the auth ref name
125 private String createItemInAuthority(AuthorityClient client, String vcsid, String authRefName) {
127 final String testName = "createItemInAuthority(" + vcsid + "," + authRefName + ")";
128 if (logger.isDebugEnabled()) {
129 logger.debug(getTestBanner(testName, CLASS_NAME));
132 // Submit the request to the service and store the response.
133 Map<String, String> taxonMap = new HashMap<String, String>();
135 // Fields present in all authority records.
136 taxonMap.put(TaxonJAXBSchema.SHORT_IDENTIFIER, TEST_SHORTID);
137 // TODO Make term status be controlled vocab.
138 taxonMap.put(TaxonJAXBSchema.TERM_STATUS, TEST_TERM_STATUS);
140 // Fields specific to this specific authority record type.
141 taxonMap.put(TaxonJAXBSchema.NAME, TEST_TAXON_FULL_NAME);
142 taxonMap.put(TaxonJAXBSchema.TAXON_RANK, TEST_TAXON_RANK);
143 taxonMap.put(TaxonJAXBSchema.TAXON_CURRENCY, TEST_TAXON_CURRENCY);
144 taxonMap.put(TaxonJAXBSchema.TAXON_YEAR, TEST_TAXON_YEAR);
145 taxonMap.put(TaxonJAXBSchema.TAXONOMIC_STATUS, TEST_TAXONOMIC_STATUS);
146 taxonMap.put(TaxonJAXBSchema.TAXON_IS_NAMED_HYBRID, TEST_TAXON_IS_NAMED_HYBRID);
148 TaxonCitationList taxonCitationList = new TaxonCitationList();
149 List<String> taxonCitations = taxonCitationList.getTaxonCitation();
150 taxonCitations.add(TEST_TAXON_CITATION);
152 TaxonAuthorGroupList taxonAuthorGroupList = new TaxonAuthorGroupList();
153 List<TaxonAuthorGroup> taxonAuthorGroups = taxonAuthorGroupList.getTaxonAuthorGroup();
154 TaxonAuthorGroup taxonAuthorGroup = new TaxonAuthorGroup();
155 taxonAuthorGroup.setTaxonAuthor(TEST_TAXON_AUTHOR);
156 taxonAuthorGroup.setTaxonAuthorType(TEST_TAXON_AUTHOR_TYPE);
157 taxonAuthorGroups.add(taxonAuthorGroup);
159 CommonNameGroupList commonNameGroupList = new CommonNameGroupList();
160 List<CommonNameGroup> commonNameGroups = commonNameGroupList.getCommonNameGroup();
161 CommonNameGroup commonNameGroup = new CommonNameGroup();
162 commonNameGroup.setCommonName(TEST_TAXON_FULL_NAME);
163 commonNameGroups.add(commonNameGroup);
165 // FIXME: Add additional fields in the Taxon record here,
166 // including at least one each of:
167 // * a Boolean field (when implemented)
168 // * an authref field (when implemented)
170 String newID = TaxonomyAuthorityClientUtils.createItemInAuthority(vcsid,
171 authRefName, taxonMap, NULL_TAXON_TERMS_LIST, taxonAuthorGroupList,
172 taxonCitationList, commonNameGroupList, (TaxonomyAuthorityClient)client);
174 // Store the ID returned from the first item resource created
175 // for additional tests below.
176 if (knownItemResourceId == null) {
177 setKnownItemResource(newID, TEST_SHORTID);
178 if (logger.isDebugEnabled()) {
179 logger.debug(testName + ": knownItemResourceId=" + newID + " inAuthority=" + vcsid);
183 // Store the IDs from any item resources created
184 // by tests, along with the IDs of their parents, so these items
185 // can be deleted after all tests have been run.
186 allResourceItemIdsCreated.put(newID, vcsid);
192 * Verify illegal item display name.
194 * @param testName the test name
195 * @throws Exception the exception
197 @Test(dataProvider = "testName")
198 public void verifyIllegalItemDisplayName(String testName) throws Exception {
200 // First read in our known resource.
203 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
204 Response res = client.readItem(knownResourceId, knownItemResourceId);
205 TaxonCommon taxon = null;
207 assertStatusCode(res, testName);
208 // Check whether Taxonomy has expected displayName.
209 PoxPayloadIn input = new PoxPayloadIn(res.readEntity(String.class));
210 taxon = (TaxonCommon) extractPart(input,
211 client.getItemCommonPartName(), TaxonCommon.class);
212 Assert.assertNotNull(taxon);
219 // Make an invalid UPDATE request, without a display name
221 TaxonTermGroupList termList = taxon.getTaxonTermGroupList();
222 Assert.assertNotNull(termList);
223 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
224 Assert.assertNotNull(terms);
225 Assert.assertTrue(terms.size() > 0);
226 terms.get(0).setTermDisplayName(null);
227 terms.get(0).setTermName(null);
229 PoxPayloadOut output = new PoxPayloadOut(TaxonomyAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
230 PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), taxon);
231 setupUpdateWithInvalidBody(); // we expect a failure here
232 res = client.updateItem(knownResourceId, knownItemResourceId, output);
234 assertStatusCode(res, testName);
243 @Test(dataProvider = "testName", groups = {"readList"},
244 dependsOnMethods = {"readList"})
245 public void readItemList(String testName) {
246 readItemList(knownAuthorityWithItems, null);
250 * Read item list by authority name.
252 @Test(dataProvider = "testName", groups = {"readList"},
253 dependsOnMethods = {"readItemList"})
254 public void readItemListByAuthorityName(String testName) {
255 readItemList(null, READITEMS_SHORT_IDENTIFIER);
261 * @param vcsid the vcsid
262 * @param name the name
264 private void readItemList(String vcsid, String shortId) {
265 String testName = "readItemList";
270 // Submit the request to the service and store the response.
271 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
274 res = client.readItemList(vcsid, null, null);
275 } else if (shortId != null) {
276 res = client.readItemListForNamedAuthority(shortId, null, null);
278 Assert.fail("readItemList passed null csid and name!");
281 assertStatusCode(res, testName);
282 AbstractCommonList list = res.readEntity(AbstractCommonList.class);
283 int statusCode = res.getStatus();
285 // Check the status code of the response: does it match
286 // the expected response(s)?
287 if (logger.isDebugEnabled()) {
288 logger.debug(testName + ": status = " + statusCode);
290 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
291 invalidStatusCodeMessage(testRequestType, statusCode));
292 Assert.assertEquals(statusCode, testExpectedStatusCode);
294 List<AbstractCommonList.ListItem> items = list.getListItem();
295 int nItemsReturned = items.size();
296 // There will be 'nItemsToCreateInList'
297 // items created by the createItemList test,
298 // all associated with the same parent resource.
299 int nExpectedItems = nItemsToCreateInList;
300 if (logger.isDebugEnabled()) {
301 logger.debug(testName + ": Expected "
302 + nExpectedItems + " items; got: " + nItemsReturned);
304 Assert.assertEquals(nItemsReturned, nExpectedItems);
306 for (AbstractCommonList.ListItem item : items) {
308 AbstractCommonListUtils.ListItemGetElementValue(item, TaxonJAXBSchema.REF_NAME);
309 Assert.assertTrue((null != value), "Item refName is null!");
311 AbstractCommonListUtils.ListItemGetElementValue(item, TaxonJAXBSchema.TERM_DISPLAY_NAME);
312 Assert.assertTrue((null != value), "Item termDisplayName is null!");
314 if (logger.isTraceEnabled()) {
315 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
323 public void delete(String testName) throws Exception {
324 // Do nothing. See localDelete(). This ensure proper test order.
327 @Test(dataProvider = "testName", dependsOnMethods = {"localDeleteItem"})
328 public void localDelete(String testName) throws Exception {
329 super.delete(testName);
333 public void deleteItem(String testName) throws Exception {
334 // Do nothing. We need to wait until after the test "localDelete" gets run. When it does,
335 // its dependencies will get run first and then we can call the base class' delete method.
338 @Test(dataProvider = "testName", groups = {"delete"},
339 dependsOnMethods = {"verifyIllegalItemDisplayName"})
340 public void localDeleteItem(String testName) throws Exception {
341 super.deleteItem(testName);
344 // ---------------------------------------------------------------
345 // Cleanup of resources created during testing
346 // ---------------------------------------------------------------
348 * Deletes all resources created by tests, after all tests have been run.
350 * This cleanup method will always be run, even if one or more tests fail.
351 * For this reason, it attempts to remove all resources created at any point
352 * during testing, even if some of those resources may be expected to be
353 * deleted by certain tests.
355 @AfterClass(alwaysRun = true)
356 public void cleanUp() {
357 String noTest = System.getProperty("noTestCleanup");
358 if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
359 if (logger.isDebugEnabled()) {
360 logger.debug("Skipping Cleanup phase ...");
364 if (logger.isDebugEnabled()) {
365 logger.debug("Cleaning up temporary resources created for testing ...");
367 String parentResourceId;
368 String itemResourceId;
369 // Clean up contact resources.
370 TaxonomyAuthorityClient client = new TaxonomyAuthorityClient();
371 parentResourceId = knownResourceId;
372 // Clean up item resources.
373 for (Map.Entry<String, String> entry : allResourceItemIdsCreated.entrySet()) {
374 itemResourceId = entry.getKey();
375 parentResourceId = entry.getValue();
376 // Note: Any non-success responses from the delete operation
377 // below are ignored and not reported.
378 client.deleteItem(parentResourceId, itemResourceId).close();
381 // Clean up parent resources.
382 for (String resourceId : allResourceIdsCreated) {
383 // Note: Any non-success responses from the delete operation
384 // below are ignored and not reported.
385 client.delete(resourceId).close();
389 // ---------------------------------------------------------------
390 // Utility methods used by tests above
391 // ---------------------------------------------------------------
394 * org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
397 * Returns the root URL for the item service.
399 * This URL consists of a base URL for all services, followed by a path
400 * component for the owning parent, followed by the path component for the
403 * @param parentResourceIdentifier An identifier (such as a UUID) for the
404 * parent authority resource of the relevant item resource.
406 * @return The root URL for the item service.
408 protected String getItemServiceRootURL(String parentResourceIdentifier) {
409 return getResourceURL(parentResourceIdentifier) + "/" + getItemServicePathComponent();
413 * Returns the URL of a specific item resource managed by a service, and
414 * designated by an identifier (such as a universally unique ID, or UUID).
416 * @param parentResourceIdentifier An identifier (such as a UUID) for the
417 * parent authority resource of the relevant item resource.
419 * @param itemResourceIdentifier An identifier (such as a UUID) for an item
422 * @return The URL of a specific item resource managed by a service.
424 protected String getItemResourceURL(String parentResourceIdentifier, String itemResourceIdentifier) {
425 return getItemServiceRootURL(parentResourceIdentifier) + "/" + itemResourceIdentifier;
429 public void authorityTests(String testName) {
430 // TODO Auto-generated method stub
434 // Taxonomy authority specific instances
437 protected PoxPayloadOut createInstance(String commonPartName,
439 String shortId = identifier;
440 String displayName = "displayName-" + shortId;
441 String baseRefName = TaxonomyAuthorityClientUtils.createTaxonomyAuthRefName(shortId, null);
442 PoxPayloadOut multipart = TaxonomyAuthorityClientUtils.createTaxonomyAuthorityInstance(
443 displayName, shortId, commonPartName);
448 protected PoxPayloadOut createNonExistenceInstance(String commonPartName, String identifier) {
449 String displayName = "displayName-NON_EXISTENT_ID";
450 PoxPayloadOut result = TaxonomyAuthorityClientUtils.createTaxonomyAuthorityInstance(
451 displayName, "nonEx", commonPartName);
456 protected TaxonomyauthorityCommon updateInstance(
457 TaxonomyauthorityCommon taxonomyAuthority) {
458 TaxonomyauthorityCommon result = new TaxonomyauthorityCommon();
460 result.setDisplayName("updated-" + taxonomyAuthority.getDisplayName());
461 result.setVocabType("updated-" + taxonomyAuthority.getVocabType());
467 protected void compareUpdatedInstances(TaxonomyauthorityCommon original,
468 TaxonomyauthorityCommon updated) throws Exception {
469 // Verify that the updated resource received the correct data.
470 Assert.assertEquals(updated.getDisplayName(),
471 original.getDisplayName(),
472 "Display name in updated object did not match submitted data.");
476 // Authority item specific overrides
479 protected String createItemInAuthority(AuthorityClient client, String authorityId) {
480 return createItemInAuthority(client, authorityId, null /** refname */);
484 protected TaxonCommon updateItemInstance(TaxonCommon taxonCommon) {
485 TaxonCommon result = taxonCommon;
486 TaxonTermGroupList termList = taxonCommon.getTaxonTermGroupList();
487 Assert.assertNotNull(termList);
488 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
489 Assert.assertNotNull(terms);
490 Assert.assertTrue(terms.size() > 0);
491 terms.get(0).setTermDisplayName("updated-" + terms.get(0).getTermDisplayName());
492 terms.get(0).setTermName("updated-" + terms.get(0).getTermName());
493 result.setTaxonTermGroupList(termList);
498 protected void compareUpdatedItemInstances(TaxonCommon original,
499 TaxonCommon updated) throws Exception {
501 TaxonTermGroupList originalTermList = original.getTaxonTermGroupList();
502 Assert.assertNotNull(originalTermList);
503 List<TaxonTermGroup> originalTerms = originalTermList.getTaxonTermGroup();
504 Assert.assertNotNull(originalTerms);
505 Assert.assertTrue(originalTerms.size() > 0);
507 TaxonTermGroupList updatedTermList = updated.getTaxonTermGroupList();
508 Assert.assertNotNull(updatedTermList);
509 List<TaxonTermGroup> updatedTerms = updatedTermList.getTaxonTermGroup();
510 Assert.assertNotNull(updatedTerms);
511 Assert.assertTrue(updatedTerms.size() > 0);
513 Assert.assertEquals(updatedTerms.get(0).getTermDisplayName(),
514 originalTerms.get(0).getTermDisplayName(),
515 "Value in updated record did not match submitted data.");
519 protected void verifyReadItemInstance(TaxonCommon item) throws Exception {
521 TaxonTermGroupList termList = item.getTaxonTermGroupList();
522 Assert.assertNotNull(termList);
523 List<TaxonTermGroup> terms = termList.getTaxonTermGroup();
524 Assert.assertNotNull(terms);
525 Assert.assertTrue(terms.size() > 0);
527 String preferredTermName = terms.get(0).getTermName();
528 Assert.assertNotNull(preferredTermName, "Field value is unexpectedly null.");
529 Assert.assertEquals(preferredTermName, TEST_TAXON_FULL_NAME,
530 "Field value " + preferredTermName
531 + "does not match expected value " + TEST_TAXON_FULL_NAME);
535 protected PoxPayloadOut createNonExistenceItemInstance(
536 String commonPartName, String identifier) {
537 Map<String, String> nonexMap = new HashMap<String, String>();
538 nonexMap.put(TaxonJAXBSchema.NAME, TEST_TAXON_FULL_NAME);
539 nonexMap.put(TaxonJAXBSchema.SHORT_IDENTIFIER, "nonEx");
540 nonexMap.put(TaxonJAXBSchema.TERM_STATUS, TEST_TERM_STATUS);
541 final String EMPTY_REFNAME = "";
542 PoxPayloadOut result =
543 TaxonomyAuthorityClientUtils.createTaxonInstance(EMPTY_REFNAME,
544 nonexMap, NULL_TAXON_TERMS_LIST, NULL_TAXON_AUTHOR_GROUP_LIST, NULL_TAXON_CITATION_LIST,
545 NULL_COMMON_NAME_GROUP_LIST, commonPartName);