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.Response;
29 import org.collectionspace.services.client.AbstractCommonListUtils;
30 import org.collectionspace.services.client.CollectionSpaceClient;
31 import org.collectionspace.services.client.LoaninClient;
32 import org.collectionspace.services.client.PayloadInputPart;
33 import org.collectionspace.services.client.PayloadOutputPart;
34 import org.collectionspace.services.client.PoxPayloadIn;
35 import org.collectionspace.services.client.PoxPayloadOut;
36 import org.collectionspace.services.common.api.GregorianCalendarDateTimeUtils;
37 import org.collectionspace.services.jaxb.AbstractCommonList;
38 import org.collectionspace.services.loanin.LenderGroup;
39 import org.collectionspace.services.loanin.LenderGroupList;
40 import org.collectionspace.services.loanin.LoansinCommon;
42 import org.jboss.resteasy.client.ClientResponse;
43 import org.testng.Assert;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
49 * LoaninServiceTest, carries out tests against a
50 * deployed and running Loanin (aka Loans In) Service.
52 * $LastChangedRevision$
55 public class LoaninServiceTest extends AbstractPoxServiceTestImpl<AbstractCommonList, LoansinCommon> {
58 private final String CLASS_NAME = LoaninServiceTest.class.getName();
59 private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
60 // Instance variables specific to this test.
61 /** The service path component. */
62 final String SERVICE_NAME = "loansin";
63 final String SERVICE_PATH_COMPONENT = "loansin";
64 private String LENDER_REF_NAME =
65 "urn:cspace:org.collectionspace.demo:personauthorities:name(TestPersonAuth):item:name(HarryLender)'Harry Lender'";
66 private final static String CURRENT_DATE_UTC =
67 GregorianCalendarDateTimeUtils.currentDateUTC();
70 * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
73 protected CollectionSpaceClient getClientInstance() {
74 return new LoaninClient();
78 * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
81 protected AbstractCommonList getCommonList(
82 ClientResponse<AbstractCommonList> response) {
83 return response.getEntity(AbstractCommonList.class);
86 // ---------------------------------------------------------------
87 // CRUD tests : CREATE tests
88 // ---------------------------------------------------------------
93 * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String)
96 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
97 public void create(String testName) throws Exception {
98 // Perform setup, such as initializing the type of service request
99 // (e.g. CREATE, DELETE), its valid and expected status codes, and
100 // its associated HTTP method name (e.g. POST, DELETE).
103 // Submit the request to the service and store the response.
104 LoaninClient client = new LoaninClient();
105 String identifier = createIdentifier();
106 PoxPayloadOut multipart = createLoaninInstance(identifier);
108 ClientResponse<Response> res = client.create(multipart);
110 int statusCode = res.getStatus();
112 // Check the status code of the response: does it match
113 // the expected response(s)?
116 // Does it fall within the set of valid status codes?
117 // Does it exactly match the expected status code?
118 if (logger.isDebugEnabled()) {
119 logger.debug(testName + ": status = " + statusCode);
121 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
122 invalidStatusCodeMessage(testRequestType, statusCode));
123 Assert.assertEquals(statusCode, testExpectedStatusCode);
125 newID = extractId(res);
128 res.releaseConnection();
132 // Store the ID returned from the first resource created
133 // for additional tests below.
134 if (knownResourceId == null) {
135 knownResourceId = newID;
136 if (logger.isDebugEnabled()) {
137 logger.debug(testName + ": knownResourceId=" + knownResourceId);
141 // Store the IDs from every resource created by tests,
142 // so they can be deleted after tests have been run.
143 allResourceIdsCreated.add(newID);
147 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createList(java.lang.String)
150 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
151 // dependsOnMethods = {"create"})
152 public void createList(String testName) throws Exception {
153 for (int i = 0; i < 3; i++) {
161 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
162 dependsOnMethods = {"create", "testSubmitRequest"})
163 public void createWithEmptyEntityBody(String testName) throws Exception {
165 if (logger.isDebugEnabled()) {
166 logger.debug(testBanner(testName, CLASS_NAME));
169 setupCreateWithEmptyEntityBody();
171 // Submit the request to the service and store the response.
172 String method = REQUEST_TYPE.httpMethodName();
173 String url = getServiceRootURL();
174 String mediaType = MediaType.APPLICATION_XML;
175 final String entity = "";
176 int statusCode = submitRequest(method, url, mediaType, entity);
178 // Check the status code of the response: does it match
179 // the expected response(s)?
180 if(logger.isDebugEnabled()){
181 logger.debug("createWithEmptyEntityBody url=" + url +
182 " status=" + statusCode);
184 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
185 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
186 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
190 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
191 dependsOnMethods = {"create", "testSubmitRequest"})
192 public void createWithMalformedXml(String testName) throws Exception {
194 if (logger.isDebugEnabled()) {
195 logger.debug(testBanner(testName, CLASS_NAME));
198 setupCreateWithMalformedXml(testName, logger);
200 // Submit the request to the service and store the response.
201 String method = REQUEST_TYPE.httpMethodName();
202 String url = getServiceRootURL();
203 String mediaType = MediaType.APPLICATION_XML;
204 final String entity = MALFORMED_XML_DATA; // Constant from base class.
205 int statusCode = submitRequest(method, url, mediaType, entity);
207 // Check the status code of the response: does it match
208 // the expected response(s)?
209 if(logger.isDebugEnabled()){
210 logger.debug(testName + ": url=" + url +
211 " status=" + statusCode);
213 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
214 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
215 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
219 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
220 dependsOnMethods = {"create", "testSubmitRequest"})
221 public void createWithWrongXmlSchema(String testName) throws Exception {
223 if (logger.isDebugEnabled()) {
224 logger.debug(testBanner(testName, CLASS_NAME));
227 setupCreateWithWrongXmlSchema(testName, logger);
229 // Submit the request to the service and store the response.
230 String method = REQUEST_TYPE.httpMethodName();
231 String url = getServiceRootURL();
232 String mediaType = MediaType.APPLICATION_XML;
233 final String entity = WRONG_XML_SCHEMA_DATA;
234 int statusCode = submitRequest(method, url, mediaType, entity);
236 // Check the status code of the response: does it match
237 // the expected response(s)?
238 if(logger.isDebugEnabled()){
239 logger.debug(testName + ": url=" + url +
240 " status=" + statusCode);
242 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
243 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
244 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
248 // ---------------------------------------------------------------
249 // CRUD tests : READ tests
250 // ---------------------------------------------------------------
255 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String)
258 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
259 // dependsOnMethods = {"create"})
260 public void read(String testName) throws Exception {
264 // Submit the request to the service and store the response.
265 LoaninClient client = new LoaninClient();
266 ClientResponse<String> res = client.read(knownResourceId);
267 PoxPayloadIn input = null;
269 assertStatusCode(res, testName);
270 input = new PoxPayloadIn(res.getEntity());
273 res.releaseConnection();
277 // Get the common part of the response and verify that it is not null.
278 PayloadInputPart payloadInputPart = input.getPart(client.getCommonPartName());
279 LoansinCommon loaninCommon = null;
280 if (payloadInputPart != null) {
281 loaninCommon = (LoansinCommon) payloadInputPart.getBody();
283 Assert.assertNotNull(loaninCommon);
285 // Check selected fields.
286 LenderGroupList lenderGroupList = loaninCommon.getLenderGroupList();
287 Assert.assertNotNull(lenderGroupList);
288 List<LenderGroup> lenderGroups = lenderGroupList.getLenderGroup();
289 Assert.assertNotNull(lenderGroups);
290 Assert.assertTrue(lenderGroups.size() > 0);
291 String lender = lenderGroups.get(0).getLender();
292 Assert.assertEquals(lender, LENDER_REF_NAME);
294 if (logger.isDebugEnabled()) {
295 logger.debug("UTF-8 data sent=" + getUTF8DataFragment() + "\n"
296 + "UTF-8 data received=" + loaninCommon.getLoanInNote());
299 Assert.assertEquals(loaninCommon.getLoanInNote(), getUTF8DataFragment(),
300 "UTF-8 data retrieved '" + loaninCommon.getLoanInNote()
301 + "' does not match expected data '" + getUTF8DataFragment());
307 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readNonExistent(java.lang.String)
310 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
311 // dependsOnMethods = {"read"})
312 public void readNonExistent(String testName) throws Exception {
314 setupReadNonExistent();
316 // Submit the request to the service and store the response.
317 LoaninClient client = new LoaninClient();
318 ClientResponse<String> res = client.read(NON_EXISTENT_ID);
320 int statusCode = res.getStatus();
322 // Check the status code of the response: does it match
323 // the expected response(s)?
324 if (logger.isDebugEnabled()) {
325 logger.debug(testName + ": status = " + statusCode);
327 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
328 invalidStatusCodeMessage(testRequestType, statusCode));
329 Assert.assertEquals(statusCode, testExpectedStatusCode);
332 res.releaseConnection();
337 // ---------------------------------------------------------------
338 // CRUD tests : READ_LIST tests
339 // ---------------------------------------------------------------
344 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readList(java.lang.String)
347 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
348 // dependsOnMethods = {"createList", "read"})
349 public void readList(String testName) throws Exception {
353 // Submit the request to the service and store the response.
354 AbstractCommonList list = null;
355 LoaninClient client = new LoaninClient();
356 ClientResponse<AbstractCommonList> res = client.readList();
357 assertStatusCode(res, testName);
359 int statusCode = res.getStatus();
361 // Check the status code of the response: does it match
362 // the expected response(s)?
363 if (logger.isDebugEnabled()) {
364 logger.debug(testName + ": status = " + statusCode);
366 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
367 invalidStatusCodeMessage(testRequestType, statusCode));
368 Assert.assertEquals(statusCode, testExpectedStatusCode);
370 list = res.getEntity();
373 res.releaseConnection();
377 // Optionally output additional data about list members for debugging.
378 boolean iterateThroughList = true;
379 if(iterateThroughList && logger.isDebugEnabled()){
380 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
388 // ---------------------------------------------------------------
389 // CRUD tests : UPDATE tests
390 // ---------------------------------------------------------------
395 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String)
398 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
399 // dependsOnMethods = {"read"})
400 public void update(String testName) throws Exception {
404 // Retrieve the contents of a resource to update.
405 LoaninClient client = new LoaninClient();
406 ClientResponse<String> res = client.read(knownResourceId);
407 PoxPayloadIn input = null;
409 assertStatusCode(res, testName);
410 input = new PoxPayloadIn(res.getEntity());
411 if (logger.isDebugEnabled()) {
412 logger.debug("got object to update with ID: " + knownResourceId);
416 res.releaseConnection();
420 // Extract the common part from the response.
421 PayloadInputPart payloadInputPart = input.getPart(client.getCommonPartName());
422 LoansinCommon loaninCommon = null;
423 if (payloadInputPart != null) {
424 loaninCommon = (LoansinCommon) payloadInputPart.getBody();
426 Assert.assertNotNull(loaninCommon);
428 // Update the content of this resource.
429 loaninCommon.setLoanInNumber("updated-" + loaninCommon.getLoanInNumber());
430 loaninCommon.setLoanInNote("updated-" + loaninCommon.getLoanInNote());
431 if (logger.isDebugEnabled()) {
432 logger.debug("to be updated object");
433 logger.debug(objectAsXmlString(loaninCommon, LoansinCommon.class));
438 // Submit the updated common part in an update request to the service
439 // and store the response.
440 PoxPayloadOut output = new PoxPayloadOut(this.getServicePathComponent());
441 PayloadOutputPart commonPart = output.addPart(client.getCommonPartName(), loaninCommon);
442 res = client.update(knownResourceId, output);
444 assertStatusCode(res, testName);
445 int statusCode = res.getStatus();
446 // Check the status code of the response: does it match the expected response(s)?
447 if (logger.isDebugEnabled()) {
448 logger.debug(testName + ": status = " + statusCode);
450 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
451 invalidStatusCodeMessage(testRequestType, statusCode));
452 Assert.assertEquals(statusCode, testExpectedStatusCode);
453 input = new PoxPayloadIn(res.getEntity());
456 res.releaseConnection();
460 // Extract the updated common part from the response.
461 payloadInputPart = input.getPart(client.getCommonPartName());
462 LoansinCommon updatedLoaninCommon = null;
463 if (payloadInputPart != null) {
464 updatedLoaninCommon = (LoansinCommon) payloadInputPart.getBody();
466 Assert.assertNotNull(updatedLoaninCommon);
468 // Check selected fields in the updated common part.
469 Assert.assertEquals(updatedLoaninCommon.getLoanInNumber(),
470 loaninCommon.getLoanInNumber(),
471 "Data in updated object did not match submitted data.");
473 if (logger.isDebugEnabled()) {
474 logger.debug("UTF-8 data sent=" + loaninCommon.getLoanInNote() + "\n"
475 + "UTF-8 data received=" + updatedLoaninCommon.getLoanInNote());
477 Assert.assertTrue(updatedLoaninCommon.getLoanInNote().contains(getUTF8DataFragment()),
478 "UTF-8 data retrieved '" + updatedLoaninCommon.getLoanInNote()
479 + "' does not contain expected data '" + getUTF8DataFragment());
480 Assert.assertEquals(updatedLoaninCommon.getLoanInNote(),
481 loaninCommon.getLoanInNote(),
482 "Data in updated object did not match submitted data.");
486 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
487 // dependsOnMethods = {"update", "testSubmitRequest"})
488 public void updateNonExistent(String testName) throws Exception {
490 setupUpdateNonExistent();
492 // Submit the request to the service and store the response.
493 // Note: The ID used in this 'create' call may be arbitrary.
494 // The only relevant ID may be the one used in update(), below.
495 LoaninClient client = new LoaninClient();
496 PoxPayloadOut multipart = createLoaninInstance(NON_EXISTENT_ID);
497 ClientResponse<String> res = client.update(NON_EXISTENT_ID, multipart);
499 int statusCode = res.getStatus();
501 // Check the status code of the response: does it match
502 // the expected response(s)?
503 if (logger.isDebugEnabled()) {
504 logger.debug(testName + ": status = " + statusCode);
506 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
507 invalidStatusCodeMessage(testRequestType, statusCode));
508 Assert.assertEquals(statusCode, testExpectedStatusCode);
511 res.releaseConnection();
516 // ---------------------------------------------------------------
517 // CRUD tests : DELETE tests
518 // ---------------------------------------------------------------
523 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String)
526 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
527 // dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
528 public void delete(String testName) throws Exception {
532 // Submit the request to the service and store the response.
533 LoaninClient client = new LoaninClient();
534 ClientResponse<Response> res = client.delete(knownResourceId);
536 int statusCode = res.getStatus();
538 // Check the status code of the response: does it match
539 // the expected response(s)?
540 if (logger.isDebugEnabled()) {
541 logger.debug(testName + ": status = " + statusCode);
543 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
544 invalidStatusCodeMessage(testRequestType, statusCode));
545 Assert.assertEquals(statusCode, testExpectedStatusCode);
548 res.releaseConnection();
556 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String)
559 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
560 // dependsOnMethods = {"delete"})
561 public void deleteNonExistent(String testName) throws Exception {
563 setupDeleteNonExistent();
565 // Submit the request to the service and store the response.
566 LoaninClient client = new LoaninClient();
567 ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
569 int statusCode = res.getStatus();
571 // Check the status code of the response: does it match
572 // the expected response(s)?
573 if (logger.isDebugEnabled()) {
574 logger.debug(testName + ": status = " + statusCode);
576 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
577 invalidStatusCodeMessage(testRequestType, statusCode));
578 Assert.assertEquals(statusCode, testExpectedStatusCode);
581 res.releaseConnection();
586 // ---------------------------------------------------------------
587 // Utility tests : tests of code used in tests above
588 // ---------------------------------------------------------------
591 * Tests the code for manually submitting data that is used by several
592 * of the methods above.
594 // @Test(dependsOnMethods = {"create", "read"})
595 public void testSubmitRequest() {
597 // Expected status code: 200 OK
598 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
600 // Submit the request to the service and store the response.
601 String method = ServiceRequestType.READ.httpMethodName();
602 String url = getResourceURL(knownResourceId);
603 int statusCode = submitRequest(method, url);
605 // Check the status code of the response: does it match
606 // the expected response(s)?
607 if (logger.isDebugEnabled()) {
608 logger.debug("testSubmitRequest: url=" + url
609 + " status=" + statusCode);
611 Assert.assertEquals(statusCode, EXPECTED_STATUS);
615 // ---------------------------------------------------------------
616 // Utility methods used by tests above
617 // ---------------------------------------------------------------
620 public String getServiceName() {
625 * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
628 public String getServicePathComponent() {
629 return SERVICE_PATH_COMPONENT;
633 protected PoxPayloadOut createInstance(String identifier) {
634 return createLoaninInstance(identifier);
638 * Creates the loanin instance.
640 * @param identifier the identifier
641 * @return the multipart output
643 private PoxPayloadOut createLoaninInstance(String identifier) {
644 return createLoaninInstance(
645 "loaninNumber-" + identifier,
646 "returnDate-" + identifier);
650 * Creates the loanin instance.
652 * @param loaninNumber the loanin number
653 * @param returnDate the return date
654 * @return the multipart output
656 private PoxPayloadOut createLoaninInstance(String loaninNumber,
659 LoansinCommon loaninCommon = new LoansinCommon();
660 loaninCommon.setLoanInNumber(loaninNumber);
661 loaninCommon.setLoanReturnDate(CURRENT_DATE_UTC);
662 LenderGroupList lenderGroupList = new LenderGroupList();
663 LenderGroup lenderGroup = new LenderGroup();
664 lenderGroup.setLender(LENDER_REF_NAME);
665 lenderGroupList.getLenderGroup().add(lenderGroup);
666 loaninCommon.setLenderGroupList(lenderGroupList);
667 loaninCommon.setLoanPurpose("For Surfboards of the 1960s exhibition.");
668 loaninCommon.setLoanInNote(getUTF8DataFragment());
670 PoxPayloadOut multipart = new PoxPayloadOut(this.getServicePathComponent());
671 PayloadOutputPart commonPart =
672 multipart.addPart(new LoaninClient().getCommonPartName(), loaninCommon);
674 if (logger.isDebugEnabled()) {
675 logger.debug("to be created, loanin common");
676 logger.debug(objectAsXmlString(loaninCommon, LoansinCommon.class));
683 public void CRUDTests(String testName) {
684 // TODO Auto-generated method stub
689 protected PoxPayloadOut createInstance(String commonPartName,
691 PoxPayloadOut result = createLoaninInstance(identifier);
696 protected LoansinCommon updateInstance(LoansinCommon commonPartObject) {
697 // TODO Auto-generated method stub
702 protected void compareUpdatedInstances(LoansinCommon original,
703 LoansinCommon updated) throws Exception {
704 // TODO Auto-generated method stub