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.List;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
29 import org.collectionspace.services.client.ContactClient;
30 import org.collectionspace.services.contact.ContactsCommon;
31 import org.collectionspace.services.contact.ContactsCommonList;
33 import org.jboss.resteasy.client.ClientResponse;
35 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
36 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
37 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
38 import org.testng.Assert;
39 import org.testng.annotations.Test;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
45 * ContactServiceTest, carries out tests against a
46 * deployed and running Contact Service.
48 * $LastChangedRevision: 917 $
49 * $LastChangedDate: 2009-11-06 12:20:28 -0800 (Fri, 06 Nov 2009) $
51 public class ContactServiceTest extends AbstractServiceTest {
53 private final Logger logger =
54 LoggerFactory.getLogger(ContactServiceTest.class);
56 // Instance variables specific to this test.
57 private ContactClient client = new ContactClient();
58 final String SERVICE_PATH_COMPONENT = "contacts";
59 private String knownResourceId = null;
61 // ---------------------------------------------------------------
62 // CRUD tests : CREATE tests
63 // ---------------------------------------------------------------
66 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class)
67 public void create(String testName) throws Exception {
69 // Perform setup, such as initializing the type of service request
70 // (e.g. CREATE, DELETE), its valid and expected status codes, and
71 // its associated HTTP method name (e.g. POST, DELETE).
72 setupCreate(testName);
74 // Submit the request to the service and store the response.
75 String identifier = createIdentifier();
77 MultipartOutput multipart = createContactInstance(identifier);
78 ClientResponse<Response> res = client.create(multipart);
80 int statusCode = res.getStatus();
82 // Check the status code of the response: does it match
83 // the expected response(s)?
86 // Does it fall within the set of valid status codes?
87 // Does it exactly match the expected status code?
88 if(logger.isDebugEnabled()){
89 logger.debug(testName + ": status = " + statusCode);
91 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
92 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
93 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
95 // Store the ID returned from this create operation
96 // for additional tests below.
97 knownResourceId = extractId(res);
98 if(logger.isDebugEnabled()){
99 logger.debug(testName + ": knownResourceId=" + knownResourceId);
104 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
105 dependsOnMethods = {"create"})
106 public void createList(String testName) throws Exception {
107 for(int i = 0; i < 3; i++){
113 // Placeholders until the three tests below can be uncommented.
114 // See Issue CSPACE-401.
116 public void createWithEmptyEntityBody(String testName) throws Exception {
120 public void createWithMalformedXml(String testName) throws Exception {
124 public void createWithWrongXmlSchema(String testName) throws Exception {
129 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
130 dependsOnMethods = {"create", "testSubmitRequest"})
131 public void createWithEmptyEntityBody(String testName) throws Exception {
134 setupCreateWithEmptyEntityBody(testName);
136 // Submit the request to the service and store the response.
137 String method = REQUEST_TYPE.httpMethodName();
138 String url = getServiceRootURL();
139 String mediaType = MediaType.APPLICATION_XML;
140 final String entity = "";
141 int statusCode = submitRequest(method, url, mediaType, entity);
143 // Check the status code of the response: does it match
144 // the expected response(s)?
145 if(logger.isDebugEnabled()){
146 logger.debug("createWithEmptyEntityBody url=" + url +
147 " status=" + statusCode);
149 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
150 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
151 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
155 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
156 dependsOnMethods = {"create", "testSubmitRequest"})
157 public void createWithMalformedXml(String testName) throws Exception {
160 setupCreateWithMalformedXml(testName);
162 // Submit the request to the service and store the response.
163 String method = REQUEST_TYPE.httpMethodName();
164 String url = getServiceRootURL();
165 String mediaType = MediaType.APPLICATION_XML;
166 final String entity = MALFORMED_XML_DATA; // Constant from base class.
167 int statusCode = submitRequest(method, url, mediaType, entity);
169 // Check the status code of the response: does it match
170 // the expected response(s)?
171 if(logger.isDebugEnabled()){
172 logger.debug(testName + ": url=" + url +
173 " status=" + statusCode);
175 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
176 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
177 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
181 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
182 dependsOnMethods = {"create", "testSubmitRequest"})
183 public void createWithWrongXmlSchema(String testName) throws Exception {
186 setupCreateWithWrongXmlSchema(testName);
188 // Submit the request to the service and store the response.
189 String method = REQUEST_TYPE.httpMethodName();
190 String url = getServiceRootURL();
191 String mediaType = MediaType.APPLICATION_XML;
192 final String entity = WRONG_XML_SCHEMA_DATA;
193 int statusCode = submitRequest(method, url, mediaType, entity);
195 // Check the status code of the response: does it match
196 // the expected response(s)?
197 if(logger.isDebugEnabled()){
198 logger.debug(testName + ": url=" + url +
199 " status=" + statusCode);
201 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
202 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
203 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
207 // ---------------------------------------------------------------
208 // CRUD tests : READ tests
209 // ---------------------------------------------------------------
212 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
213 dependsOnMethods = {"create"})
214 public void read(String testName) throws Exception {
219 // Submit the request to the service and store the response.
220 ClientResponse<MultipartInput> res = client.read(knownResourceId);
221 int statusCode = res.getStatus();
223 // Check the status code of the response: does it match
224 // the expected response(s)?
225 if(logger.isDebugEnabled()){
226 logger.debug(testName + ": status = " + statusCode);
228 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
229 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
230 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
232 MultipartInput input = (MultipartInput) res.getEntity();
233 ContactsCommon contact = (ContactsCommon) extractPart(input,
234 client.getCommonPartName(), ContactsCommon.class);
235 Assert.assertNotNull(contact);
240 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
241 dependsOnMethods = {"read"})
242 public void readNonExistent(String testName) throws Exception {
245 setupReadNonExistent(testName);
247 // Submit the request to the service and store the response.
248 ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
249 int statusCode = res.getStatus();
251 // Check the status code of the response: does it match
252 // the expected response(s)?
253 if(logger.isDebugEnabled()){
254 logger.debug(testName + ": status = " + statusCode);
256 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
257 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
258 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
261 // ---------------------------------------------------------------
262 // CRUD tests : READ_LIST tests
263 // ---------------------------------------------------------------
266 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
267 dependsOnMethods = {"read"})
268 public void readList(String testName) throws Exception {
271 setupReadList(testName);
273 // Submit the request to the service and store the response.
274 ClientResponse<ContactsCommonList> res = client.readList();
275 ContactsCommonList list = res.getEntity();
276 int statusCode = res.getStatus();
278 // Check the status code of the response: does it match
279 // the expected response(s)?
280 if(logger.isDebugEnabled()){
281 logger.debug(testName + ": status = " + statusCode);
283 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
284 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
285 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
287 // Optionally output additional data about list members for debugging.
288 boolean iterateThroughList = false;
289 if(iterateThroughList && logger.isDebugEnabled()){
290 List<ContactsCommonList.ContactListItem> items =
291 list.getContactListItem();
293 for(ContactsCommonList.ContactListItem item : items){
294 logger.debug(testName + ": list-item[" + i + "] csid=" +
296 logger.debug(testName + ": list-item[" + i + "] objectNumber=" +
297 item.getAddressText());
298 logger.debug(testName + ": list-item[" + i + "] URI=" +
308 // ---------------------------------------------------------------
309 // CRUD tests : UPDATE tests
310 // ---------------------------------------------------------------
313 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
314 dependsOnMethods = {"read"})
315 public void update(String testName) throws Exception {
318 setupUpdate(testName);
320 ClientResponse<MultipartInput> res =
321 client.read(knownResourceId);
322 if(logger.isDebugEnabled()){
323 logger.debug(testName + ": read status = " + res.getStatus());
325 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
327 if(logger.isDebugEnabled()){
328 logger.debug("got object to update with ID: " + knownResourceId);
330 MultipartInput input = (MultipartInput) res.getEntity();
331 ContactsCommon contact = (ContactsCommon) extractPart(input,
332 client.getCommonPartName(), ContactsCommon.class);
333 Assert.assertNotNull(contact);
335 // Update the content of this resource.
336 contact.setAddressText("updated-" + contact.getAddressText());
337 contact.setPostcode("updated-" + contact.getPostcode());
338 if(logger.isDebugEnabled()){
339 logger.debug("to be updated object");
340 logger.debug(objectAsXmlString(contact, ContactsCommon.class));
342 // Submit the request to the service and store the response.
343 MultipartOutput output = new MultipartOutput();
344 OutputPart commonPart = output.addPart(contact, MediaType.APPLICATION_XML_TYPE);
345 commonPart.getHeaders().add("label", client.getCommonPartName());
347 res = client.update(knownResourceId, output);
348 int statusCode = res.getStatus();
349 // Check the status code of the response: does it match the expected response(s)?
350 if(logger.isDebugEnabled()){
351 logger.debug(testName + ": status = " + statusCode);
353 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
354 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
355 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
358 input = (MultipartInput) res.getEntity();
359 ContactsCommon updatedContact =
360 (ContactsCommon) extractPart(input,
361 client.getCommonPartName(), ContactsCommon.class);
362 Assert.assertNotNull(updatedContact);
364 Assert.assertEquals(updatedContact.getPostcode(),
365 contact.getPostcode(),
366 "Data in updated object did not match submitted data.");
371 // Placeholders until the three tests below can be uncommented.
372 // See Issue CSPACE-401.
374 public void updateWithEmptyEntityBody(String testName) throws Exception{
377 public void updateWithMalformedXml(String testName) throws Exception {
380 public void updateWithWrongXmlSchema(String testName) throws Exception {
385 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
386 dependsOnMethods = {"create", "update", "testSubmitRequest"})
387 public void updateWithEmptyEntityBody(String testName) throws Exception {
390 setupUpdateWithEmptyEntityBody(testName);
392 // Submit the request to the service and store the response.
393 String method = REQUEST_TYPE.httpMethodName();
394 String url = getResourceURL(knownResourceId);
395 String mediaType = MediaType.APPLICATION_XML;
396 final String entity = "";
397 int statusCode = submitRequest(method, url, mediaType, entity);
399 // Check the status code of the response: does it match
400 // the expected response(s)?
401 if(logger.isDebugEnabled()){
402 logger.debug(testName + ": url=" + url +
403 " status=" + statusCode);
405 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
406 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
407 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
411 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
412 dependsOnMethods = {"create", "update", "testSubmitRequest"})
413 public void updateWithMalformedXml(String testName) throws Exception {
416 setupUpdateWithMalformedXml(testName);
418 // Submit the request to the service and store the response.
419 String method = REQUEST_TYPE.httpMethodName();
420 String url = getResourceURL(knownResourceId);
421 String mediaType = MediaType.APPLICATION_XML;
422 final String entity = MALFORMED_XML_DATA;
423 int statusCode = submitRequest(method, url, mediaType, entity);
425 // Check the status code of the response: does it match
426 // the expected response(s)?
427 if(logger.isDebugEnabled()){
428 logger.debug(testName + ": url=" + url +
429 " status=" + statusCode);
431 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
432 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
433 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
437 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
438 dependsOnMethods = {"create", "update", "testSubmitRequest"})
439 public void updateWithWrongXmlSchema(String testName) throws Exception {
442 setupUpdateWithWrongXmlSchema(testName);
444 // Submit the request to the service and store the response.
445 String method = REQUEST_TYPE.httpMethodName();
446 String url = getResourceURL(knownResourceId);
447 String mediaType = MediaType.APPLICATION_XML;
448 final String entity = WRONG_XML_SCHEMA_DATA;
449 int statusCode = submitRequest(method, url, mediaType, entity);
451 // Check the status code of the response: does it match
452 // the expected response(s)?
453 if(logger.isDebugEnabled()){
454 logger.debug(testName + ": url=" + url +
455 " status=" + statusCode);
457 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
458 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
459 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
464 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
465 dependsOnMethods = {"update", "testSubmitRequest"})
466 public void updateNonExistent(String testName) throws Exception {
469 setupUpdateNonExistent(testName);
471 // Submit the request to the service and store the response.
472 // Note: The ID used in this 'create' call may be arbitrary.
473 // The only relevant ID may be the one used in update(), below.
475 // The only relevant ID may be the one used in update(), below.
476 MultipartOutput multipart = createContactInstance(NON_EXISTENT_ID);
477 ClientResponse<MultipartInput> res =
478 client.update(NON_EXISTENT_ID, multipart);
479 int statusCode = res.getStatus();
481 // Check the status code of the response: does it match
482 // the expected response(s)?
483 if(logger.isDebugEnabled()){
484 logger.debug(testName + ": status = " + statusCode);
486 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
487 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
488 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
491 // ---------------------------------------------------------------
492 // CRUD tests : DELETE tests
493 // ---------------------------------------------------------------
496 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
497 dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
498 public void delete(String testName) throws Exception {
501 setupDelete(testName);
503 // Submit the request to the service and store the response.
504 ClientResponse<Response> res = client.delete(knownResourceId);
505 int statusCode = res.getStatus();
507 // Check the status code of the response: does it match
508 // the expected response(s)?
509 if(logger.isDebugEnabled()){
510 logger.debug(testName + ": status = " + statusCode);
512 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
513 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
514 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
519 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
520 dependsOnMethods = {"delete"})
521 public void deleteNonExistent(String testName) throws Exception {
524 setupDeleteNonExistent(testName);
526 // Submit the request to the service and store the response.
527 ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
528 int statusCode = res.getStatus();
530 // Check the status code of the response: does it match
531 // the expected response(s)?
532 if(logger.isDebugEnabled()){
533 logger.debug(testName + ": status = " + statusCode);
535 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
536 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
537 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
540 // ---------------------------------------------------------------
541 // Utility tests : tests of code used in tests above
542 // ---------------------------------------------------------------
544 * Tests the code for manually submitting data that is used by several
545 * of the methods above.
547 @Test(dependsOnMethods = {"create", "read"})
548 public void testSubmitRequest() {
550 // Expected status code: 200 OK
551 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
553 // Submit the request to the service and store the response.
554 String method = ServiceRequestType.READ.httpMethodName();
555 String url = getResourceURL(knownResourceId);
556 int statusCode = submitRequest(method, url);
558 // Check the status code of the response: does it match
559 // the expected response(s)?
560 if(logger.isDebugEnabled()){
561 logger.debug("testSubmitRequest: url=" + url +
562 " status=" + statusCode);
564 Assert.assertEquals(statusCode, EXPECTED_STATUS);
568 // ---------------------------------------------------------------
569 // Utility methods used by tests above
570 // ---------------------------------------------------------------
572 public String getServicePathComponent() {
573 return SERVICE_PATH_COMPONENT;
576 private MultipartOutput createContactInstance(String identifier) {
577 return createContactInstance(
578 "addressText-" + identifier,
579 "postcode-" + identifier,
580 "addressType-" + identifier);
583 private MultipartOutput createContactInstance(String addressText,
584 String postcode, String addressType) {
585 ContactsCommon contact = new ContactsCommon();
586 contact.setAddressText(addressText);
587 contact.setPostcode(postcode);
588 contact.setAddressType(addressType);
589 MultipartOutput multipart = new MultipartOutput();
590 OutputPart commonPart =
591 multipart.addPart(contact, MediaType.APPLICATION_XML_TYPE);
592 commonPart.getHeaders().add("label", client.getCommonPartName());
594 if(logger.isDebugEnabled()){
595 logger.debug("to be created, contact common");
596 logger.debug(objectAsXmlString(contact, ContactsCommon.class));