1 package org.collectionspace.services.client.test;
5 import javax.ws.rs.core.Response;
6 import org.jboss.resteasy.client.ClientResponse;
8 import org.collectionspace.services.client.AbstractCommonListUtils;
9 import org.collectionspace.services.client.AuthorityClient;
10 import org.collectionspace.services.client.AuthorityClientImpl;
11 import org.collectionspace.services.client.AuthorityProxy;
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(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 * Returns the root URL for a service.
67 * This URL consists of a base URL for all services, followed by
68 * a path component for the owning vocabulary, followed by the
69 * path component for the items.
71 * @return The root URL for a service.
73 protected String getItemServiceRootURL(String parentResourceIdentifier) {
74 return getResourceURL(parentResourceIdentifier) + "/" + getServicePathItemsComponent();
78 * Returns the URL of a specific resource managed by a service, and
79 * designated by an identifier (such as a universally unique ID, or UUID).
81 * @param resourceIdentifier An identifier (such as a UUID) for a resource.
83 * @return The URL of a specific resource managed by a service.
85 protected String getItemResourceURL(String parentResourceIdentifier, String resourceIdentifier) {
86 return getItemServiceRootURL(parentResourceIdentifier) + "/" + resourceIdentifier;
90 * For authorities we override this method so we can save the shortid.
93 protected String createWithIdentifier(String testName, String identifier) throws Exception {
94 String csid = createResource(testName, identifier);
95 // Store the ID returned from the first resource created
96 // for additional tests below.
97 if (getKnowResourceId() == null) {
98 setKnownResource(csid, identifier /*shortId*/, null /*refname*/ );
99 if (logger.isDebugEnabled()) {
100 logger.debug(testName + ": Setting knownResourceId=" + getKnowResourceId());
107 @Test(dependsOnMethods = {"readItem", "CRUDTests"})
108 public void testItemSubmitRequest() {
110 // Expected status code: 200 OK
111 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
113 // Submit the request to the service and store the response.
114 String method = ServiceRequestType.READ.httpMethodName();
115 String url = getItemResourceURL(knownResourceId, knownItemResourceId);
116 int statusCode = submitRequest(method, url);
118 // Check the status code of the response: does it match
119 // the expected response(s)?
120 if (logger.isDebugEnabled()) {
121 logger.debug("testItemSubmitRequest: url=" + url
122 + " status=" + statusCode);
124 Assert.assertEquals(statusCode, EXPECTED_STATUS);
128 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
129 dependsOnMethods = {"readItem"})
130 public void verifyIgnoredUpdateWithInAuthority(String testName) throws Exception {
134 // Submit the request to the service and store the response.
135 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client =
136 (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
137 ClientResponse<String> res = client.readItem(knownResourceId, knownItemResourceId);
138 int statusCode = res.getStatus();
140 // Check the status code of the response: does it match
141 // the expected response(s)?
142 if (logger.isDebugEnabled()) {
143 logger.debug(testName + " read authority:" + knownResourceId + "/Item:"
144 + knownItemResourceId + " status = " + statusCode);
146 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
147 invalidStatusCodeMessage(testRequestType, statusCode));
148 Assert.assertEquals(statusCode, Response.Status.OK.getStatusCode());
150 AUTHORITY_ITEM_TYPE vitem = extractItemCommonPartValue(res);
151 Assert.assertNotNull(vitem);
152 // Try to Update with new parent vocab (use self, for test).
153 Assert.assertEquals(client.getInAuthority(vitem), knownResourceId,
154 "VocabularyItem inAuthority does not match knownResourceId.");
155 client.setInAuthority(vitem, knownItemResourceId);
157 // Submit the updated resource to the service and store the response.
158 PoxPayloadOut output = this.createItemRequestTypeInstance(vitem);
159 res = client.updateItem(knownResourceId, knownItemResourceId, output);
160 statusCode = res.getStatus();
162 // Check the status code of the response: does it match the expected response(s)?
163 if (logger.isDebugEnabled()) {
164 logger.debug(testName + ": status = " + statusCode);
166 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
167 invalidStatusCodeMessage(testRequestType, statusCode));
168 Assert.assertEquals(statusCode, testExpectedStatusCode);
170 // Retrieve the updated resource and verify that the parent did not change
171 res = client.readItem(knownResourceId, knownItemResourceId);
172 AUTHORITY_ITEM_TYPE updatedVocabularyItem = extractItemCommonPartValue(res);
173 Assert.assertNotNull(updatedVocabularyItem);
175 // Verify that the updated resource received the correct data.
176 Assert.assertEquals(client.getInAuthority(updatedVocabularyItem),
178 "VocabularyItem allowed update to the parent (inAuthority).");
181 @Test(dataProvider = "testName",
182 dependsOnMethods = {"CRUDTests"})
183 public void createItem(String testName) {
187 String newID = createItemInAuthority(knownResourceId);
189 // Store the ID returned from the first item resource created
190 // for additional tests below.
191 if (knownItemResourceId == null) {
192 knownItemResourceId = newID;
193 if (null != testName && logger.isDebugEnabled()) {
194 logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
199 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
200 dependsOnMethods = {"createItem"})
201 public void createItemList(String testName) throws Exception {
202 knownAuthorityWithItems = createResource(testName, READITEMS_SHORT_IDENTIFIER);
203 for (int j = 0; j < nItemsToCreateInList; j++) {
204 createItemInAuthority(knownAuthorityWithItems);
211 * @param testName the test name
212 * @throws Exception the exception
214 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
215 dependsOnMethods = {"CRUDTests"})
216 public void readByName(String testName) throws Exception {
220 // Submit the request to the service and store the response.
221 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
222 ClientResponse<String> res = client.readByName(getKnowResourceIdentifier());
223 int statusCode = res.getStatus();
225 // Check the status code of the response: does it match
226 // the expected response(s)?
227 if (logger.isDebugEnabled()) {
228 logger.debug(testName + ": status = " + statusCode);
230 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
231 invalidStatusCodeMessage(testRequestType, statusCode));
232 Assert.assertEquals(statusCode, testExpectedStatusCode);
234 AUTHORITY_COMMON_TYPE commonPart = extractCommonPartValue(res);
235 Assert.assertNotNull(commonPart);
239 * Extracts the common part item from a service's item payload.
245 public AUTHORITY_ITEM_TYPE extractItemCommonPartValue(ClientResponse<String> res) throws Exception {
246 AUTHORITY_ITEM_TYPE result = null;
248 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
249 PayloadInputPart payloadInputPart = extractPart(res, client.getItemCommonPartName());
250 if (payloadInputPart != null) {
251 result = (AUTHORITY_ITEM_TYPE) payloadInputPart.getBody();
253 Assert.assertNotNull(result,
254 "Part or body of part " + client.getCommonPartName() + " was unexpectedly null.");
259 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
260 dependsOnMethods = {"readItem"})
261 public void readItemNonExistent(String testName) {
263 setupReadNonExistent();
265 // Submit the request to the service and store the response.
266 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
267 ClientResponse<String> res = client.readItem(knownResourceId, NON_EXISTENT_ID);
268 int statusCode = res.getStatus();
270 // Check the status code of the response: does it match
271 // the expected response(s)?
272 if (logger.isDebugEnabled()) {
273 logger.debug(testName + ": status = " + statusCode);
275 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
276 invalidStatusCodeMessage(testRequestType, statusCode));
277 Assert.assertEquals(statusCode, testExpectedStatusCode);
280 @Test(dataProvider = "testName",
281 dependsOnMethods = {"createItem"})
282 public void readItem(String testName) throws Exception {
286 // Submit the request to the service and store the response.
287 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
288 ClientResponse<String> res = client.readItem(knownResourceId, knownItemResourceId);
289 int statusCode = res.getStatus();
291 // Check the status code of the response: does it match
292 // the expected response(s)?
293 if (logger.isDebugEnabled()) {
294 logger.debug(testName + ": status = " + statusCode);
296 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
297 invalidStatusCodeMessage(testRequestType, statusCode));
298 Assert.assertEquals(statusCode, testExpectedStatusCode);
300 AUTHORITY_ITEM_TYPE itemCommonPart = extractItemCommonPartValue(res);
301 Assert.assertNotNull(itemCommonPart);
302 Assert.assertEquals(client.getInAuthority(itemCommonPart), knownResourceId);
303 verifyReadItemInstance(itemCommonPart);
306 protected abstract void verifyReadItemInstance(AUTHORITY_ITEM_TYPE item) throws Exception;
308 @Test(dataProvider = "testName",
309 dependsOnMethods = {"testItemSubmitRequest", "updateItem", "verifyIgnoredUpdateWithInAuthority"})
310 public void deleteItem(String testName) throws Exception {
314 // Submit the request to the service and store the response.
315 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
316 Response res = client.deleteItem(knownResourceId, knownItemResourceId);
319 statusCode = res.getStatus();
324 // Check the status code of the response: does it match
325 // the expected response(s)?
326 if (logger.isDebugEnabled()) {
327 logger.debug("delete: status = " + statusCode);
329 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
330 invalidStatusCodeMessage(testRequestType, statusCode));
331 Assert.assertEquals(statusCode, testExpectedStatusCode);
334 protected void readItemListInt(String vcsid, String shortId, String testName) {
338 // Submit the request to the service and store the response.
339 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
340 ClientResponse<AbstractCommonList> res = null;
342 res = client.readItemList(vcsid, null, null);
343 } else if (shortId != null) {
344 res = client.readItemListForNamedAuthority(shortId, null, null);
346 Assert.fail("Internal Error: readItemList both vcsid and shortId are null!");
348 int statusCode = res.getStatus();
350 // Check the status code of the response: does it match
351 // the expected response(s)?
352 if (logger.isDebugEnabled()) {
353 logger.debug(" " + testName + ": status = " + statusCode);
355 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
356 invalidStatusCodeMessage(testRequestType, statusCode));
357 Assert.assertEquals(statusCode, testExpectedStatusCode);
359 AbstractCommonList list = res.getEntity();
360 List<AbstractCommonList.ListItem> items = list.getListItem();
361 int nItemsReturned = items.size();
362 long nItemsTotal = list.getTotalItems();
363 if (logger.isDebugEnabled()) {
364 logger.debug(" " + testName + ": Expected "
365 + nItemsToCreateInList + " items; got: " + nItemsReturned + " of: " + nItemsTotal);
367 Assert.assertEquals(nItemsTotal, nItemsToCreateInList);
369 if(logger.isTraceEnabled()){
370 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
374 @Test(dataProvider = "testName",
375 dependsOnMethods = {"createItemList"})
376 public void readItemList(String testName) {
377 readItemListInt(knownAuthorityWithItems, null, testName);
380 @Test(dataProvider = "testName",
381 dependsOnMethods = {"readItem"})
382 public void readItemListByName(String testName) {
383 readItemListInt(null, READITEMS_SHORT_IDENTIFIER, testName);
386 @Test(dataProvider = "testName",
387 dependsOnMethods = {"deleteItem"})
388 public void deleteNonExistentItem(String testName) {
390 setupDeleteNonExistent();
392 // Submit the request to the service and store the response.
393 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
394 Response res = client.deleteItem(knownResourceId, NON_EXISTENT_ID);
397 statusCode = res.getStatus();
402 // Check the status code of the response: does it match
403 // the expected response(s)?
404 if (logger.isDebugEnabled()) {
405 logger.debug(testName + ": status = " + statusCode);
407 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
408 invalidStatusCodeMessage(testRequestType, statusCode));
409 Assert.assertEquals(statusCode, testExpectedStatusCode);
412 protected String getServicePathItemsComponent() {
413 return AuthorityClient.ITEMS;
416 public PoxPayloadOut createItemRequestTypeInstance(AUTHORITY_ITEM_TYPE itemTypeInstance) {
417 PoxPayloadOut result = null;
419 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client = (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
420 PoxPayloadOut payloadOut = new PoxPayloadOut(this.getServicePathItemsComponent());
421 PayloadOutputPart part = payloadOut.addPart(client.getItemCommonPartName(), itemTypeInstance);
428 * Update an Authority item.
433 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
434 dependsOnMethods = {"readItem", "CRUDTests", "verifyIgnoredUpdateWithInAuthority"})
435 public void updateItem(String testName) throws Exception {
438 AUTHORITY_ITEM_TYPE theUpdate = null;
440 // Retrieve the contents of a resource to update.
441 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client =
442 (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
443 ClientResponse<String> res =
444 client.readItem(knownResourceId, knownItemResourceId);
446 if (logger.isDebugEnabled()) {
447 logger.debug(testName + ": read status = " + res.getStatus());
449 Assert.assertEquals(res.getStatus(), testExpectedStatusCode);
451 if (logger.isDebugEnabled()) {
452 logger.debug("got Authority item to update with ID: "
453 + knownItemResourceId
454 + " in authority: " + knownResourceId);
456 AUTHORITY_ITEM_TYPE authorityItem = extractItemCommonPartValue(res);
457 Assert.assertNotNull(authorityItem);
459 // Update the contents of this resource.
460 theUpdate = updateItemInstance(authorityItem);
461 if (logger.isDebugEnabled()) {
462 logger.debug("\n\nTo be updated fields: CSID = " + knownItemResourceId + "\n"
463 + objectAsXmlString(theUpdate));
466 res.releaseConnection();
469 // Submit the updated resource to the service and store the response.
470 PoxPayloadOut output = this.createItemRequestTypeInstance(theUpdate);
471 res = client.updateItem(knownResourceId, knownItemResourceId, output);
473 int statusCode = res.getStatus();
475 // Check the status code of the response: does it match the expected response(s)?
476 if (logger.isDebugEnabled()) {
477 logger.debug("updateItem: status = " + statusCode);
479 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
480 invalidStatusCodeMessage(testRequestType, statusCode));
481 Assert.assertEquals(statusCode, testExpectedStatusCode);
483 // Retrieve the updated resource and verify that its contents exist.
484 AUTHORITY_ITEM_TYPE updatedVocabularyItem = extractItemCommonPartValue(res);
485 Assert.assertNotNull(updatedVocabularyItem);
487 compareUpdatedItemInstances(theUpdate, updatedVocabularyItem);
489 res.releaseConnection();
493 protected abstract PoxPayloadOut createNonExistenceItemInstance(String commonPartName, String identifier);
496 * @see org.collectionspace.services.client.test.ServiceTest#updateNonExistent(java.lang.String)
498 @Test(dataProvider = "testName",
499 dependsOnMethods = {"create", "update", "updateNonExistent"})
500 public void updateNonExistentItem(String testName) throws Exception {
502 setupUpdateNonExistent();
504 // Submit the request to the service and store the response.
505 // Note: The ID used in this 'create' call may be arbitrary.
506 // The only relevant ID may be the one used in update(), below.
507 AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy> client =
508 (AuthorityClientImpl<AUTHORITY_ITEM_TYPE, AuthorityProxy>)this.getClientInstance();
509 PoxPayloadOut multipart = createNonExistenceItemInstance(client.getItemCommonPartName(), NON_EXISTENT_ID);
510 ClientResponse<String> res =
511 client.updateItem(knownResourceId, NON_EXISTENT_ID, multipart);
513 int statusCode = res.getStatus();
515 // Check the status code of the response: does it match
516 // the expected response(s)?
517 if (logger.isDebugEnabled()) {
518 logger.debug(testName + ": status = " + statusCode);
520 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
521 invalidStatusCodeMessage(testRequestType, statusCode));
522 Assert.assertEquals(statusCode, testExpectedStatusCode);
524 res.releaseConnection();
529 // Methods to persuade TestNG to follow the correct test dependency path
532 @Test(dataProvider = "testName",
533 dependsOnMethods = {"createItem"})
534 public void baseAuthorityTests(String testName) {
535 // Do nothing. Here just to setup a test dependency chain.
539 * For convenience and terseness, this test method is the base of the test execution dependency chain. Other test methods may
540 * refer to this method in their @Test annotation declarations.
543 @Test(dataProvider = "testName",
545 "org.collectionspace.services.client.test.AbstractServiceTestImpl.baseCRUDTests"})
546 public void CRUDTests(String testName) {
547 // TODO Auto-generated method stub