2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright © 2009 Regents of the University of California
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
15 * https://source.collectionspace.org/collection-space/LICENSE.txt
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
23 package org.collectionspace.services.client.test;
25 import java.util.ArrayList;
26 import java.util.List;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
30 import org.collectionspace.services.client.LoanoutClient;
31 import org.collectionspace.services.loanout.LoansoutCommon;
32 import org.collectionspace.services.loanout.LoansoutCommonList;
34 import org.jboss.resteasy.client.ClientResponse;
36 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
37 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
38 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
39 import org.testng.Assert;
40 import org.testng.annotations.AfterClass;
41 import org.testng.annotations.Test;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * LoanoutServiceTest, carries out tests against a
48 * deployed and running Loanout (aka Loans Out) Service.
50 * $LastChangedRevision: 1327 $
51 * $LastChangedDate: 2010-02-12 10:35:11 -0800 (Fri, 12 Feb 2010) $
53 public class LoanoutServiceTest extends AbstractServiceTestImpl {
55 private final Logger logger =
56 LoggerFactory.getLogger(LoanoutServiceTest.class);
58 // Instance variables specific to this test.
59 final String SERVICE_PATH_COMPONENT = "loansout";
60 private String knownResourceId = null;
61 private List<String> allResourceIdsCreated = new ArrayList();
63 // ---------------------------------------------------------------
64 // CRUD tests : CREATE tests
65 // ---------------------------------------------------------------
68 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class)
69 public void create(String testName) throws Exception {
71 // Perform setup, such as initializing the type of service request
72 // (e.g. CREATE, DELETE), its valid and expected status codes, and
73 // its associated HTTP method name (e.g. POST, DELETE).
74 setupCreate(testName);
76 // Submit the request to the service and store the response.
77 LoanoutClient client = new LoanoutClient();
78 String identifier = createIdentifier();
79 MultipartOutput multipart = createLoanoutInstance(identifier);
80 ClientResponse<Response> res = client.create(multipart);
82 int statusCode = res.getStatus();
84 // Check the status code of the response: does it match
85 // the expected response(s)?
88 // Does it fall within the set of valid status codes?
89 // Does it exactly match the expected status code?
90 if(logger.isDebugEnabled()){
91 logger.debug(testName + ": status = " + statusCode);
93 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
94 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
95 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
97 // Store the ID returned from the first resource created
98 // for additional tests below.
99 if (knownResourceId == null){
100 knownResourceId = extractId(res);
101 if (logger.isDebugEnabled()) {
102 logger.debug(testName + ": knownResourceId=" + knownResourceId);
106 // Store the IDs from every resource created by tests,
107 // so they can be deleted after tests have been run.
108 allResourceIdsCreated.add(extractId(res));
112 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
113 dependsOnMethods = {"create"})
114 public void createList(String testName) throws Exception {
115 for(int i = 0; i < 3; i++){
121 // Placeholders until the three tests below can be uncommented.
122 // See Issue CSPACE-401.
124 public void createWithEmptyEntityBody(String testName) throws Exception {
128 public void createWithMalformedXml(String testName) throws Exception {
132 public void createWithWrongXmlSchema(String testName) throws Exception {
137 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
138 dependsOnMethods = {"create", "testSubmitRequest"})
139 public void createWithEmptyEntityBody(String testName) throws Exception {
142 setupCreateWithEmptyEntityBody(testName);
144 // Submit the request to the service and store the response.
145 String method = REQUEST_TYPE.httpMethodName();
146 String url = getServiceRootURL();
147 String mediaType = MediaType.APPLICATION_XML;
148 final String entity = "";
149 int statusCode = submitRequest(method, url, mediaType, entity);
151 // Check the status code of the response: does it match
152 // the expected response(s)?
153 if(logger.isDebugEnabled()){
154 logger.debug("createWithEmptyEntityBody url=" + url +
155 " status=" + statusCode);
157 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
158 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
159 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
163 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
164 dependsOnMethods = {"create", "testSubmitRequest"})
165 public void createWithMalformedXml(String testName) throws Exception {
168 setupCreateWithMalformedXml(testName);
170 // Submit the request to the service and store the response.
171 String method = REQUEST_TYPE.httpMethodName();
172 String url = getServiceRootURL();
173 String mediaType = MediaType.APPLICATION_XML;
174 final String entity = MALFORMED_XML_DATA; // Constant from base class.
175 int statusCode = submitRequest(method, url, mediaType, entity);
177 // Check the status code of the response: does it match
178 // the expected response(s)?
179 if(logger.isDebugEnabled()){
180 logger.debug(testName + ": url=" + url +
181 " status=" + statusCode);
183 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
184 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
185 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
189 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
190 dependsOnMethods = {"create", "testSubmitRequest"})
191 public void createWithWrongXmlSchema(String testName) throws Exception {
194 setupCreateWithWrongXmlSchema(testName);
196 // Submit the request to the service and store the response.
197 String method = REQUEST_TYPE.httpMethodName();
198 String url = getServiceRootURL();
199 String mediaType = MediaType.APPLICATION_XML;
200 final String entity = WRONG_XML_SCHEMA_DATA;
201 int statusCode = submitRequest(method, url, mediaType, entity);
203 // Check the status code of the response: does it match
204 // the expected response(s)?
205 if(logger.isDebugEnabled()){
206 logger.debug(testName + ": url=" + url +
207 " status=" + statusCode);
209 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
210 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
211 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
215 // ---------------------------------------------------------------
216 // CRUD tests : READ tests
217 // ---------------------------------------------------------------
220 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
221 dependsOnMethods = {"create"})
222 public void read(String testName) throws Exception {
227 // Submit the request to the service and store the response.
228 LoanoutClient client = new LoanoutClient();
229 ClientResponse<MultipartInput> res = client.read(knownResourceId);
230 int statusCode = res.getStatus();
232 // Check the status code of the response: does it match
233 // the expected response(s)?
234 if(logger.isDebugEnabled()){
235 logger.debug(testName + ": status = " + statusCode);
237 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
238 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
239 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
241 MultipartInput input = (MultipartInput) res.getEntity();
242 LoansoutCommon loanout = (LoansoutCommon) extractPart(input,
243 client.getCommonPartName(), LoansoutCommon.class);
244 Assert.assertNotNull(loanout);
249 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
250 dependsOnMethods = {"read"})
251 public void readNonExistent(String testName) throws Exception {
254 setupReadNonExistent(testName);
256 // Submit the request to the service and store the response.
257 LoanoutClient client = new LoanoutClient();
258 ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
259 int statusCode = res.getStatus();
261 // Check the status code of the response: does it match
262 // the expected response(s)?
263 if(logger.isDebugEnabled()){
264 logger.debug(testName + ": status = " + statusCode);
266 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
267 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
268 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
271 // ---------------------------------------------------------------
272 // CRUD tests : READ_LIST tests
273 // ---------------------------------------------------------------
276 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
277 dependsOnMethods = {"createList", "read"})
278 public void readList(String testName) throws Exception {
281 setupReadList(testName);
283 // Submit the request to the service and store the response.
284 LoanoutClient client = new LoanoutClient();
285 ClientResponse<LoansoutCommonList> res = client.readList();
286 LoansoutCommonList list = res.getEntity();
287 int statusCode = res.getStatus();
289 // Check the status code of the response: does it match
290 // the expected response(s)?
291 if(logger.isDebugEnabled()){
292 logger.debug(testName + ": status = " + statusCode);
294 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
295 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
296 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
298 // Optionally output additional data about list members for debugging.
299 boolean iterateThroughList = false;
300 if(iterateThroughList && logger.isDebugEnabled()){
301 List<LoansoutCommonList.LoanoutListItem> items =
302 list.getLoanoutListItem();
304 for(LoansoutCommonList.LoanoutListItem item : items){
305 logger.debug(testName + ": list-item[" + i + "] csid=" +
307 logger.debug(testName + ": list-item[" + i + "] loanOutNumber=" +
308 item.getLoanOutNumber());
309 logger.debug(testName + ": list-item[" + i + "] URI=" +
319 // ---------------------------------------------------------------
320 // CRUD tests : UPDATE tests
321 // ---------------------------------------------------------------
324 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
325 dependsOnMethods = {"read"})
326 public void update(String testName) throws Exception {
329 setupUpdate(testName);
331 // Retrieve the contents of a resource to update.
332 LoanoutClient client = new LoanoutClient();
333 ClientResponse<MultipartInput> res =
334 client.read(knownResourceId);
335 if(logger.isDebugEnabled()){
336 logger.debug(testName + ": read status = " + res.getStatus());
338 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
340 if(logger.isDebugEnabled()){
341 logger.debug("got object to update with ID: " + knownResourceId);
343 MultipartInput input = (MultipartInput) res.getEntity();
344 LoansoutCommon loanout = (LoansoutCommon) extractPart(input,
345 client.getCommonPartName(), LoansoutCommon.class);
346 Assert.assertNotNull(loanout);
348 // Update the content of this resource.
349 loanout.setLoanOutNumber("updated-" + loanout.getLoanOutNumber());
350 loanout.setLoanReturnDate("updated-" + loanout.getLoanReturnDate());
351 if(logger.isDebugEnabled()){
352 logger.debug("to be updated object");
353 logger.debug(objectAsXmlString(loanout, LoansoutCommon.class));
355 // Submit the request to the service and store the response.
356 MultipartOutput output = new MultipartOutput();
357 OutputPart commonPart = output.addPart(loanout, MediaType.APPLICATION_XML_TYPE);
358 commonPart.getHeaders().add("label", client.getCommonPartName());
360 res = client.update(knownResourceId, output);
361 int statusCode = res.getStatus();
362 // Check the status code of the response: does it match the expected response(s)?
363 if(logger.isDebugEnabled()){
364 logger.debug(testName + ": status = " + statusCode);
366 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
367 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
368 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
371 input = (MultipartInput) res.getEntity();
372 LoansoutCommon updatedLoanout =
373 (LoansoutCommon) extractPart(input,
374 client.getCommonPartName(), LoansoutCommon.class);
375 Assert.assertNotNull(updatedLoanout);
377 Assert.assertEquals(updatedLoanout.getLoanReturnDate(),
378 loanout.getLoanReturnDate(),
379 "Data in updated object did not match submitted data.");
384 // Placeholders until the three tests below can be uncommented.
385 // See Issue CSPACE-401.
387 public void updateWithEmptyEntityBody(String testName) throws Exception{
390 public void updateWithMalformedXml(String testName) throws Exception {
393 public void updateWithWrongXmlSchema(String testName) throws Exception {
398 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
399 dependsOnMethods = {"create", "update", "testSubmitRequest"})
400 public void updateWithEmptyEntityBody(String testName) throws Exception {
403 setupUpdateWithEmptyEntityBody(testName);
405 // Submit the request to the service and store the response.
406 String method = REQUEST_TYPE.httpMethodName();
407 String url = getResourceURL(knownResourceId);
408 String mediaType = MediaType.APPLICATION_XML;
409 final String entity = "";
410 int statusCode = submitRequest(method, url, mediaType, entity);
412 // Check the status code of the response: does it match
413 // the expected response(s)?
414 if(logger.isDebugEnabled()){
415 logger.debug(testName + ": url=" + url +
416 " status=" + statusCode);
418 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
419 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
420 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
424 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
425 dependsOnMethods = {"create", "update", "testSubmitRequest"})
426 public void updateWithMalformedXml(String testName) throws Exception {
429 setupUpdateWithMalformedXml(testName);
431 // Submit the request to the service and store the response.
432 String method = REQUEST_TYPE.httpMethodName();
433 String url = getResourceURL(knownResourceId);
434 String mediaType = MediaType.APPLICATION_XML;
435 final String entity = MALFORMED_XML_DATA;
436 int statusCode = submitRequest(method, url, mediaType, entity);
438 // Check the status code of the response: does it match
439 // the expected response(s)?
440 if(logger.isDebugEnabled()){
441 logger.debug(testName + ": url=" + url +
442 " status=" + statusCode);
444 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
445 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
446 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
450 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
451 dependsOnMethods = {"create", "update", "testSubmitRequest"})
452 public void updateWithWrongXmlSchema(String testName) throws Exception {
455 setupUpdateWithWrongXmlSchema(testName);
457 // Submit the request to the service and store the response.
458 String method = REQUEST_TYPE.httpMethodName();
459 String url = getResourceURL(knownResourceId);
460 String mediaType = MediaType.APPLICATION_XML;
461 final String entity = WRONG_XML_SCHEMA_DATA;
462 int statusCode = submitRequest(method, url, mediaType, entity);
464 // Check the status code of the response: does it match
465 // the expected response(s)?
466 if(logger.isDebugEnabled()){
467 logger.debug(testName + ": url=" + url +
468 " status=" + statusCode);
470 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
471 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
472 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
477 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
478 dependsOnMethods = {"update", "testSubmitRequest"})
479 public void updateNonExistent(String testName) throws Exception {
482 setupUpdateNonExistent(testName);
484 // Submit the request to the service and store the response.
485 // Note: The ID used in this 'create' call may be arbitrary.
486 // The only relevant ID may be the one used in update(), below.
487 LoanoutClient client = new LoanoutClient();
488 MultipartOutput multipart = createLoanoutInstance(NON_EXISTENT_ID);
489 ClientResponse<MultipartInput> res =
490 client.update(NON_EXISTENT_ID, multipart);
491 int statusCode = res.getStatus();
493 // Check the status code of the response: does it match
494 // the expected response(s)?
495 if(logger.isDebugEnabled()){
496 logger.debug(testName + ": status = " + statusCode);
498 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
499 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
500 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
503 // ---------------------------------------------------------------
504 // CRUD tests : DELETE tests
505 // ---------------------------------------------------------------
508 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
509 dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
510 public void delete(String testName) throws Exception {
513 setupDelete(testName);
515 // Submit the request to the service and store the response.
516 LoanoutClient client = new LoanoutClient();
517 ClientResponse<Response> res = client.delete(knownResourceId);
518 int statusCode = res.getStatus();
520 // Check the status code of the response: does it match
521 // the expected response(s)?
522 if(logger.isDebugEnabled()){
523 logger.debug(testName + ": status = " + statusCode);
525 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
526 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
527 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
532 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
533 dependsOnMethods = {"delete"})
534 public void deleteNonExistent(String testName) throws Exception {
537 setupDeleteNonExistent(testName);
539 // Submit the request to the service and store the response.
540 LoanoutClient client = new LoanoutClient();
541 ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
542 int statusCode = res.getStatus();
544 // Check the status code of the response: does it match
545 // the expected response(s)?
546 if(logger.isDebugEnabled()){
547 logger.debug(testName + ": status = " + statusCode);
549 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
550 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
551 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
554 // ---------------------------------------------------------------
555 // Utility tests : tests of code used in tests above
556 // ---------------------------------------------------------------
558 * Tests the code for manually submitting data that is used by several
559 * of the methods above.
561 @Test(dependsOnMethods = {"create", "read"})
562 public void testSubmitRequest() {
564 // Expected status code: 200 OK
565 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
567 // Submit the request to the service and store the response.
568 String method = ServiceRequestType.READ.httpMethodName();
569 String url = getResourceURL(knownResourceId);
570 int statusCode = submitRequest(method, url);
572 // Check the status code of the response: does it match
573 // the expected response(s)?
574 if(logger.isDebugEnabled()){
575 logger.debug("testSubmitRequest: url=" + url +
576 " status=" + statusCode);
578 Assert.assertEquals(statusCode, EXPECTED_STATUS);
582 // ---------------------------------------------------------------
583 // Cleanup of resources created during testing
584 // ---------------------------------------------------------------
587 * Deletes all resources created by tests, after all tests have been run.
589 * This cleanup method will always be run, even if one or more tests fail.
590 * For this reason, it attempts to remove all resources created
591 * at any point during testing, even if some of those resources
592 * may be expected to be deleted by certain tests.
594 @AfterClass(alwaysRun=true)
595 public void cleanUp() {
596 if (logger.isDebugEnabled()) {
597 logger.debug("Cleaning up temporary resources created for testing ...");
599 LoanoutClient client = new LoanoutClient();
600 for (String resourceId : allResourceIdsCreated) {
601 // Note: Any non-success responses are ignored and not reported.
602 ClientResponse<Response> res = client.delete(resourceId);
606 // ---------------------------------------------------------------
607 // Utility methods used by tests above
608 // ---------------------------------------------------------------
610 public String getServicePathComponent() {
611 return SERVICE_PATH_COMPONENT;
614 private MultipartOutput createLoanoutInstance(String identifier) {
615 return createLoanoutInstance(
616 "loanoutNumber-" + identifier,
617 "returnDate-" + identifier);
620 private MultipartOutput createLoanoutInstance(String loanOutNumber,
622 LoansoutCommon loanout = new LoansoutCommon();
623 loanout.setLoanOutNumber(loanOutNumber);
624 loanout.setLoanReturnDate(returnDate);
626 "urn:cspace:org.collectionspace.demo:orgauthority:name(TestOrgAuth):organization:name(Northern Climes Museum)'Northern Climes Museum'");
627 loanout.setBorrowersContact(
628 "urn:cspace:org.collectionspace.demo:personauthority:name(TestPersonAuth):person:name(Chris Contact)'Chris Contact'");
629 loanout.setLoanPurpose("Allow people in cold climes to share the magic of Surfboards of the 1960s.");
630 MultipartOutput multipart = new MultipartOutput();
631 OutputPart commonPart =
632 multipart.addPart(loanout, MediaType.APPLICATION_XML_TYPE);
633 commonPart.getHeaders().add("label", new LoanoutClient().getCommonPartName());
635 if(logger.isDebugEnabled()){
636 logger.debug("to be created, loanout common");
637 logger.debug(objectAsXmlString(loanout, LoansoutCommon.class));