1 package org.collectionspace.services.client.test;
5 import javax.ws.rs.core.Response;
7 import org.collectionspace.services.client.AbstractCommonListUtils;
8 import org.collectionspace.services.client.AuthorityClient;
9 import org.collectionspace.services.client.AuthorityClientImpl;
10 import org.collectionspace.services.client.AuthorityProxy;
11 import org.collectionspace.services.client.CollectionSpaceClient;
12 import org.collectionspace.services.client.PayloadInputPart;
13 import org.collectionspace.services.client.PayloadOutputPart;
14 import org.collectionspace.services.client.PoxPayloadOut;
15 import org.collectionspace.services.jaxb.AbstractCommonList;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19 import org.testng.Assert;
20 import org.testng.annotations.Test;
26 * @param <AUTHORITY_COMMON_TYPE>
27 * @param <AUTHORITY_ITEM_TYPE>
29 * All CRUD related authority test classes should extend this class.
32 public abstract class AbstractAuthorityServiceTest<AUTHORITY_COMMON_TYPE, AUTHORITY_ITEM_TYPE>
33 extends AbstractPoxServiceTestImpl<AbstractCommonList, AUTHORITY_COMMON_TYPE> {
35 private final Logger logger = LoggerFactory.getLogger(AbstractAuthorityServiceTest.class);
37 protected String knownResourceShortIdentifer = null;
38 protected static final String READITEMS_SHORT_IDENTIFIER = "resourceWithItems";
39 protected String knownAuthorityWithItems = null;
41 protected String knownResourceRefName = null;
42 protected String knownItemResourceId = null;
43 protected String knownItemResourceShortIdentifer = null;
44 protected int nItemsToCreateInList = 5;
46 public abstract void authorityTests(String testName);
47 protected abstract String createItemInAuthority(AuthorityClient client, String authorityId);
49 protected abstract AUTHORITY_ITEM_TYPE updateItemInstance(final AUTHORITY_ITEM_TYPE authorityItem);
50 protected abstract void compareUpdatedItemInstances(AUTHORITY_ITEM_TYPE original, AUTHORITY_ITEM_TYPE updated) throws Exception;
52 protected void setKnownItemResource(String id, String shortIdentifer ) {
53 knownItemResourceId = id;
54 knownItemResourceShortIdentifer = shortIdentifer;
57 protected void setKnownResource(String id, String shortIdentifer,
60 knownResourceShortIdentifer = shortIdentifer;
61 knownResourceRefName = refName;
65 * Gets a client to the SAS (Shared Authority Server)
69 protected AuthorityClient getSASClientInstance() {
70 return (AuthorityClient) this.getClientInstance(CollectionSpaceClient.SAS_CLIENT_PROPERTIES_FILENAME);
74 * Returns the root URL for a service.
76 * This URL consists of a base URL for all services, followed by
77 * a path component for the owning vocabulary, followed by the
78 * path component for the items.
80 * @return The root URL for a service.
82 protected String getItemServiceRootURL(String parentResourceIdentifier) {
83 return getResourceURL(parentResourceIdentifier) + "/" + getServicePathItemsComponent();
87 * Returns the URL of a specific resource managed by a service, and
88 * designated by an identifier (such as a universally unique ID, or UUID).
90 * @param resourceIdentifier An identifier (such as a UUID) for a resource.
92 * @return The URL of a specific resource managed by a service.
94 protected String getItemResourceURL(String parentResourceIdentifier, String resourceIdentifier) {
95 return getItemServiceRootURL(parentResourceIdentifier) + "/" + resourceIdentifier;
99 * For authorities we override this method so we can save the shortid.
102 protected String createWithIdentifier(String testName, String identifier) throws Exception {
103 String csid = createResource(testName, identifier);
104 // Store the ID returned from the first resource created
105 // for additional tests below.
106 if (getKnowResourceId() == null) {
107 setKnownResource(csid, identifier /*shortId*/, null /*refname*/ );
108 if (logger.isDebugEnabled()) {
109 logger.debug(testName + ": Setting knownResourceId=" + getKnowResourceId());
116 @Test(dependsOnMethods = {"readItem", "CRUDTests"})
117 public void testItemSubmitRequest() {
119 // Expected status code: 200 OK
120 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
122 // Submit the request to the service and store the response.
123 String method = ServiceRequestType.READ.httpMethodName();
124 String url = getItemResourceURL(knownResourceId, knownItemResourceId);
125 int statusCode = submitRequest(method, url);
127 // Check the status code of the response: does it match
128 // the expected response(s)?
129 if (logger.isDebugEnabled()) {
130 logger.debug("testItemSubmitRequest: url=" + url
131 + " status=" + statusCode);
133 Assert.assertEquals(statusCode, EXPECTED_STATUS);
137 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
138 dependsOnMethods = {"readItem"})
139 public void verifyIgnoredUpdateWithInAuthority(String testName) throws Exception {
143 // Submit the request to the service and store the response.
144 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client =
145 (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
146 Response res = client.readItem(knownResourceId, knownItemResourceId);
147 AUTHORITY_ITEM_TYPE vitem = null;
149 int statusCode = res.getStatus();
151 // Check the status code of the response: does it match
152 // the expected response(s)?
153 if (logger.isDebugEnabled()) {
154 logger.debug(testName + " read authority:" + knownResourceId + "/Item:"
155 + knownItemResourceId + " status = " + statusCode);
157 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
158 invalidStatusCodeMessage(testRequestType, statusCode));
159 Assert.assertEquals(statusCode, Response.Status.OK.getStatusCode());
161 vitem = extractItemCommonPartValue(res);
162 Assert.assertNotNull(vitem);
163 // Try to Update with new parent vocab (use self, for test).
164 Assert.assertEquals(client.getInAuthority(vitem), knownResourceId,
165 "VocabularyItem inAuthority does not match knownResourceId.");
166 client.setInAuthority(vitem, knownItemResourceId);
172 // Submit the updated resource to the service and store the response.
173 PoxPayloadOut output = this.createItemRequestTypeInstance(vitem);
174 res = client.updateItem(knownResourceId, knownItemResourceId, output);
176 int statusCode = res.getStatus();
178 // Check the status code of the response: does it match the expected response(s)?
179 if (logger.isDebugEnabled()) {
180 logger.debug(testName + ": status = " + statusCode);
182 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
183 invalidStatusCodeMessage(testRequestType, statusCode));
184 Assert.assertEquals(statusCode, testExpectedStatusCode);
189 res = client.readItem(knownResourceId, knownItemResourceId);
191 // Retrieve the updated resource and verify that the parent did not change
192 AUTHORITY_ITEM_TYPE updatedVocabularyItem = extractItemCommonPartValue(res);
193 Assert.assertNotNull(updatedVocabularyItem);
195 // Verify that the updated resource received the correct data.
196 Assert.assertEquals(client.getInAuthority(updatedVocabularyItem),
198 "VocabularyItem allowed update to the parent (inAuthority).");
204 @Test(dataProvider = "testName",
205 dependsOnMethods = {"CRUDTests"})
206 public void createItem(String testName) {
210 String newID = createItemInAuthority((AuthorityClient) getClientInstance(), knownResourceId);
212 // Store the ID returned from the first item resource created
213 // for additional tests below.
214 if (knownItemResourceId == null) {
215 knownItemResourceId = newID;
216 if (null != testName && logger.isDebugEnabled()) {
217 logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
223 * SAS - Create an item on the SAS server.
226 @Test(dataProvider = "testName",
227 dependsOnMethods = {"CRUDTests"})
228 public void createSASItem(String testName) {
232 String newID = createItemInAuthority(getSASClientInstance(), knownResourceId);
234 // Store the ID returned from the first item resource created
235 // for additional tests below.
236 if (knownItemResourceId == null) {
237 knownItemResourceId = newID;
238 if (null != testName && logger.isDebugEnabled()) {
239 logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
244 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
245 dependsOnMethods = {"createItem"})
246 public void createItemList(String testName) throws Exception {
247 knownAuthorityWithItems = createResource(testName, READITEMS_SHORT_IDENTIFIER);
248 for (int j = 0; j < nItemsToCreateInList; j++) {
249 createItemInAuthority((AuthorityClient) getClientInstance(), knownAuthorityWithItems);
256 * @param testName the test name
257 * @throws Exception the exception
259 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
260 dependsOnMethods = {"CRUDTests"})
261 public void readByName(String testName) throws Exception {
265 // Submit the request to the service and store the response.
266 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client =
267 (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
268 Response res = client.readByName(getKnowResourceIdentifier());
270 int statusCode = res.getStatus();
272 // Check the status code of the response: does it match
273 // the expected response(s)?
274 if (logger.isDebugEnabled()) {
275 logger.debug(testName + ": status = " + statusCode);
277 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
278 invalidStatusCodeMessage(testRequestType, statusCode));
279 Assert.assertEquals(statusCode, testExpectedStatusCode);
281 AUTHORITY_COMMON_TYPE commonPart = extractCommonPartValue(res);
282 Assert.assertNotNull(commonPart);
289 * Extracts the common part item from a service's item payload.
295 public AUTHORITY_ITEM_TYPE extractItemCommonPartValue(Response res) throws Exception {
296 AUTHORITY_ITEM_TYPE result = null;
298 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)
299 this.getClientInstance();
300 PayloadInputPart payloadInputPart = extractPart(res, client.getItemCommonPartName());
301 if (payloadInputPart != null) {
302 result = (AUTHORITY_ITEM_TYPE) payloadInputPart.getBody();
304 Assert.assertNotNull(result,
305 "Part or body of part " + client.getCommonPartName() + " was unexpectedly null.");
310 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
311 dependsOnMethods = {"readItem"})
312 public void readItemNonExistent(String testName) {
314 setupReadNonExistent();
316 // Submit the request to the service and store the response.
317 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)
318 this.getClientInstance();
319 Response res = client.readItem(knownResourceId, NON_EXISTENT_ID);
321 int statusCode = res.getStatus();
323 // Check the status code of the response: does it match
324 // the expected response(s)?
325 if (logger.isDebugEnabled()) {
326 logger.debug(testName + ": status = " + statusCode);
328 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
329 invalidStatusCodeMessage(testRequestType, statusCode));
330 Assert.assertEquals(statusCode, testExpectedStatusCode);
336 @Test(dataProvider = "testName",
337 dependsOnMethods = {"createItem"})
338 public void readItem(String testName) throws Exception {
342 // Submit the request to the service and store the response.
343 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
344 Response res = client.readItem(knownResourceId, knownItemResourceId);
346 int statusCode = res.getStatus();
348 // Check the status code of the response: does it match
349 // the expected response(s)?
350 if (logger.isDebugEnabled()) {
351 logger.debug(testName + ": status = " + statusCode);
353 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
354 invalidStatusCodeMessage(testRequestType, statusCode));
355 Assert.assertEquals(statusCode, testExpectedStatusCode);
357 AUTHORITY_ITEM_TYPE itemCommonPart = extractItemCommonPartValue(res);
358 Assert.assertNotNull(itemCommonPart);
359 Assert.assertEquals(client.getInAuthority(itemCommonPart), knownResourceId);
360 verifyReadItemInstance(itemCommonPart);
366 protected abstract void verifyReadItemInstance(AUTHORITY_ITEM_TYPE item) throws Exception;
368 @Test(dataProvider = "testName",
369 dependsOnMethods = {"testItemSubmitRequest", "updateItem", "verifyIgnoredUpdateWithInAuthority"})
370 public void deleteItem(String testName) throws Exception {
374 // Submit the request to the service and store the response.
375 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)
376 this.getClientInstance();
377 Response res = client.deleteItem(knownResourceId, knownItemResourceId);
380 statusCode = res.getStatus();
385 // Check the status code of the response: does it match
386 // the expected response(s)?
387 if (logger.isDebugEnabled()) {
388 logger.debug("delete: status = " + statusCode);
390 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
391 invalidStatusCodeMessage(testRequestType, statusCode));
392 Assert.assertEquals(statusCode, testExpectedStatusCode);
395 protected void readItemListInt(String vcsid, String shortId, String testName) {
399 // Submit the request to the service and store the response.
400 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
403 res = client.readItemList(vcsid, null, null);
404 } else if (shortId != null) {
405 res = client.readItemListForNamedAuthority(shortId, null, null);
407 Assert.fail("Internal Error: readItemList both vcsid and shortId are null!");
410 int statusCode = res.getStatus();
412 // Check the status code of the response: does it match
413 // the expected response(s)?
414 if (logger.isDebugEnabled()) {
415 logger.debug(" " + testName + ": status = " + statusCode);
417 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
418 invalidStatusCodeMessage(testRequestType, statusCode));
419 Assert.assertEquals(statusCode, testExpectedStatusCode);
421 AbstractCommonList list = res.readEntity(AbstractCommonList.class);
422 List<AbstractCommonList.ListItem> items = list.getListItem();
423 int nItemsReturned = items.size();
424 long nItemsTotal = list.getTotalItems();
425 if (logger.isDebugEnabled()) {
426 logger.debug(" " + testName + ": Expected "
427 + nItemsToCreateInList + " items; got: " + nItemsReturned + " of: " + nItemsTotal);
429 Assert.assertEquals(nItemsTotal, nItemsToCreateInList);
431 if(logger.isTraceEnabled()){
432 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
439 @Test(dataProvider = "testName",
440 dependsOnMethods = {"createItemList"})
441 public void readItemList(String testName) {
442 readItemListInt(knownAuthorityWithItems, null, testName);
445 @Test(dataProvider = "testName",
446 dependsOnMethods = {"readItem"})
447 public void readItemListByName(String testName) {
448 readItemListInt(null, READITEMS_SHORT_IDENTIFIER, testName);
451 @Test(dataProvider = "testName",
452 dependsOnMethods = {"deleteItem"})
453 public void deleteNonExistentItem(String testName) {
455 setupDeleteNonExistent();
457 // Submit the request to the service and store the response.
458 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
459 Response res = client.deleteItem(knownResourceId, NON_EXISTENT_ID);
462 statusCode = res.getStatus();
467 // Check the status code of the response: does it match
468 // the expected response(s)?
469 if (logger.isDebugEnabled()) {
470 logger.debug(testName + ": status = " + statusCode);
472 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
473 invalidStatusCodeMessage(testRequestType, statusCode));
474 Assert.assertEquals(statusCode, testExpectedStatusCode);
477 protected String getServicePathItemsComponent() {
478 return AuthorityClient.ITEMS;
481 public PoxPayloadOut createItemRequestTypeInstance(AUTHORITY_ITEM_TYPE itemTypeInstance) {
482 PoxPayloadOut result = null;
484 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
485 PoxPayloadOut payloadOut = new PoxPayloadOut(this.getServicePathItemsComponent());
486 PayloadOutputPart part = payloadOut.addPart(client.getItemCommonPartName(), itemTypeInstance);
493 * Update an Authority item.
498 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
499 dependsOnMethods = {"readItem", "CRUDTests", "verifyIgnoredUpdateWithInAuthority"})
500 public void updateItem(String testName) throws Exception {
503 AUTHORITY_ITEM_TYPE theUpdate = null;
505 // Retrieve the contents of a resource to update.
506 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client =
507 (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
508 Response res = client.readItem(knownResourceId, knownItemResourceId);
510 if (logger.isDebugEnabled()) {
511 logger.debug(testName + ": read status = " + res.getStatus());
513 Assert.assertEquals(res.getStatus(), testExpectedStatusCode);
515 if (logger.isDebugEnabled()) {
516 logger.debug("got Authority item to update with ID: "
517 + knownItemResourceId
518 + " in authority: " + knownResourceId);
520 AUTHORITY_ITEM_TYPE authorityItem = extractItemCommonPartValue(res);
521 Assert.assertNotNull(authorityItem);
523 // Update the contents of this resource.
524 theUpdate = updateItemInstance(authorityItem);
525 if (logger.isDebugEnabled()) {
526 logger.debug("\n\nTo be updated fields: CSID = " + knownItemResourceId + "\n"
527 + objectAsXmlString(theUpdate));
533 // Submit the updated resource to the service and store the response.
534 PoxPayloadOut output = this.createItemRequestTypeInstance(theUpdate);
535 res = client.updateItem(knownResourceId, knownItemResourceId, output);
537 int statusCode = res.getStatus();
539 // Check the status code of the response: does it match the expected response(s)?
540 if (logger.isDebugEnabled()) {
541 logger.debug("updateItem: status = " + statusCode);
543 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
544 invalidStatusCodeMessage(testRequestType, statusCode));
545 Assert.assertEquals(statusCode, testExpectedStatusCode);
547 // Retrieve the updated resource and verify that its contents exist.
548 AUTHORITY_ITEM_TYPE updatedVocabularyItem = extractItemCommonPartValue(res);
549 Assert.assertNotNull(updatedVocabularyItem);
551 compareUpdatedItemInstances(theUpdate, updatedVocabularyItem);
557 protected abstract PoxPayloadOut createNonExistenceItemInstance(String commonPartName, String identifier);
560 * @see org.collectionspace.services.client.test.ServiceTest#updateNonExistent(java.lang.String)
562 @Test(dataProvider = "testName",
563 dependsOnMethods = {"create", "update", "updateNonExistent"})
564 public void updateNonExistentItem(String testName) throws Exception {
566 setupUpdateNonExistent();
568 // Submit the request to the service and store the response.
569 // Note: The ID used in this 'create' call may be arbitrary.
570 // The only relevant ID may be the one used in update(), below.
571 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client =
572 (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
573 PoxPayloadOut multipart = createNonExistenceItemInstance(client.getItemCommonPartName(), NON_EXISTENT_ID);
574 Response res = client.updateItem(knownResourceId, NON_EXISTENT_ID, multipart);
576 int statusCode = res.getStatus();
578 // Check the status code of the response: does it match
579 // the expected response(s)?
580 if (logger.isDebugEnabled()) {
581 logger.debug(testName + ": status = " + statusCode);
583 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
584 invalidStatusCodeMessage(testRequestType, statusCode));
585 Assert.assertEquals(statusCode, testExpectedStatusCode);
592 // Methods to persuade TestNG to follow the correct test dependency path
595 @Test(dataProvider = "testName",
596 dependsOnMethods = {"createItem"})
597 public void baseAuthorityTests(String testName) {
598 // Do nothing. Here just to setup a test dependency chain.
602 * For convenience and terseness, this test method is the base of the test execution dependency chain. Other test methods may
603 * refer to this method in their @Test annotation declarations.
606 @Test(dataProvider = "testName",
608 "org.collectionspace.services.client.test.AbstractServiceTestImpl.baseCRUDTests"})
609 public void CRUDTests(String testName) {
610 // TODO Auto-generated method stub