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.RelationClient;
30 import org.collectionspace.services.relation.RelationsCommon;
31 import org.collectionspace.services.relation.RelationsCommonList;
32 import org.collectionspace.services.relation.RelationshipType;
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.Test;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
46 * RelationServiceTest, carries out tests against a
47 * deployed and running Relation Service.
49 * $LastChangedRevision$
52 public class RelationServiceTest extends AbstractServiceTest {
54 private final Logger logger =
55 LoggerFactory.getLogger(RelationServiceTest.class);
57 private RelationClient client = new RelationClient();
58 final String SERVICE_PATH_COMPONENT = "relations";
59 private String knownResourceId = null;
61 // ---------------------------------------------------------------
62 // CRUD tests : CREATE tests
63 // ---------------------------------------------------------------
67 public void create() 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).
74 // Submit the request to the service and store the response.
75 String identifier = createIdentifier();
76 MultipartOutput multipart = createRelationInstance(identifier);
77 ClientResponse<Response> res = client.create(multipart);
78 int statusCode = res.getStatus();
80 // Check the status code of the response: does it match
81 // the expected response(s)?
83 // Does it fall within the set of valid status codes?
84 // Does it exactly match the expected status code?
85 if(logger.isDebugEnabled()){
86 logger.debug("create: status = " + statusCode);
88 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
89 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
90 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
92 // Store the ID returned from this create operation for
93 // additional tests below.
94 knownResourceId = extractId(res);
95 if(logger.isDebugEnabled()){
96 logger.debug("create: knownResourceId=" + knownResourceId);
101 @Test(dependsOnMethods = {"create"})
102 public void createList() throws Exception {
103 for(int i = 0; i < 3; i++){
109 // Placeholders until the three tests below can be uncommented.
110 // See Issue CSPACE-401.
111 public void createWithEmptyEntityBody() throws Exception {
114 public void createWithMalformedXml() throws Exception {
117 public void createWithWrongXmlSchema() throws Exception {
122 @Test(dependsOnMethods = {"create", "testSubmitRequest"})
123 public void createWithEmptyEntityBody() throws Exception {
126 setupCreateWithEmptyEntityBody();
128 // Submit the request to the service and store the response.
129 String method = REQUEST_TYPE.httpMethodName();
130 String url = getServiceRootURL();
131 String mediaType = MediaType.APPLICATION_XML;
132 final String entity = "";
133 int statusCode = submitRequest(method, url, mediaType, entity);
135 // Check the status code of the response: does it match
136 // the expected response(s)?
137 if(logger.isDebugEnabled()){
138 logger.debug("createWithEmptyEntityBody url=" + url +
139 " status=" + statusCode);
141 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
142 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
143 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
147 @Test(dependsOnMethods = {"create", "testSubmitRequest"})
148 public void createWithMalformedXml() throws Exception {
151 setupCreateWithMalformedXml();
153 // Submit the request to the service and store the response.
154 String method = REQUEST_TYPE.httpMethodName();
155 String url = getServiceRootURL();
156 String mediaType = MediaType.APPLICATION_XML;
157 final String entity = MALFORMED_XML_DATA; // Constant from base class.
158 int statusCode = submitRequest(method, url, mediaType, entity);
160 // Check the status code of the response: does it match
161 // the expected response(s)?
162 if(logger.isDebugEnabled()){
163 logger.debug("createWithMalformedXml url=" + url +
164 " status=" + statusCode);
166 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
167 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
168 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
172 @Test(dependsOnMethods = {"create", "testSubmitRequest"})
173 public void createWithWrongXmlSchema()n throws Exception {
176 setupCreateWithWrongXmlSchema();
178 // Submit the request to the service and store the response.
179 String method = REQUEST_TYPE.httpMethodName();
180 String url = getServiceRootURL();
181 String mediaType = MediaType.APPLICATION_XML;
182 final String entity = WRONG_XML_SCHEMA_DATA;
183 int statusCode = submitRequest(method, url, mediaType, entity);
185 // Check the status code of the response: does it match
186 // the expected response(s)?
187 if(logger.isDebugEnabled()){
188 logger.debug("createWithWrongSchema url=" + url +
189 " status=" + statusCode);
191 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
192 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
193 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
197 // ---------------------------------------------------------------
198 // CRUD tests : READ tests
199 // ---------------------------------------------------------------
202 @Test(dependsOnMethods = {"create"})
203 public void read() throws Exception {
208 // Submit the request to the service and store the response.
209 ClientResponse<MultipartInput> res = client.read(knownResourceId);
210 int statusCode = res.getStatus();
212 // Check the status code of the response: does it match
213 // the expected response(s)?
214 if(logger.isDebugEnabled()){
215 logger.debug("read: status = " + statusCode);
217 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
218 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
219 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
221 // Verify that the resource identifier ...
222 MultipartInput input = (MultipartInput) res.getEntity();
223 RelationsCommon relation = (RelationsCommon) extractPart(input,
224 client.getCommonPartName(), RelationsCommon.class);
225 Assert.assertNotNull(relation);
231 @Test(dependsOnMethods = {"read"})
232 public void readNonExistent() throws Exception {
235 setupReadNonExistent();
237 // Submit the request to the service and store the response.
238 ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
239 int statusCode = res.getStatus();
241 // Check the status code of the response: does it match
242 // the expected response(s)?
243 if(logger.isDebugEnabled()){
244 logger.debug("readNonExistent: status = " + res.getStatus());
246 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
247 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
248 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
251 // ---------------------------------------------------------------
252 // CRUD tests : READ_LIST tests
253 // ---------------------------------------------------------------
256 @Test(dependsOnMethods = {"createList", "read"})
257 public void readList() throws Exception {
262 // Submit the request to the service and store the response.
263 ClientResponse<RelationsCommonList> res = client.readList();
264 RelationsCommonList list = res.getEntity();
265 int statusCode = res.getStatus();
267 // Check the status code of the response: does it match
268 // the expected response(s)?
269 if(logger.isDebugEnabled()){
270 logger.debug("readList: status = " + res.getStatus());
272 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
273 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
274 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
276 // Optionally output additional data about list members for debugging.
277 boolean iterateThroughList = false;
278 if(iterateThroughList && logger.isDebugEnabled()){
279 List<RelationsCommonList.RelationListItem> items =
280 list.getRelationListItem();
282 for(RelationsCommonList.RelationListItem item : items){
283 logger.debug("readList: list-item[" + i + "] csid=" +
285 logger.debug("readList: list-item[" + i + "] URI=" +
296 // ---------------------------------------------------------------
297 // CRUD tests : UPDATE tests
298 // ---------------------------------------------------------------
302 @Test(dependsOnMethods = {"read"})
303 public void update() throws Exception {
308 // Retrieve an existing resource that we can update.
309 ClientResponse<MultipartInput> res =
310 client.read(knownResourceId);
311 if(logger.isDebugEnabled()){
312 logger.debug("update: read status = " + res.getStatus());
314 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
315 if(logger.isDebugEnabled()){
316 logger.debug("Got object to update with ID: " + knownResourceId);
318 MultipartInput input = (MultipartInput) res.getEntity();
319 RelationsCommon relation = (RelationsCommon) extractPart(input,
320 client.getCommonPartName(), RelationsCommon.class);
321 Assert.assertNotNull(relation);
323 // Update the content of this resource.
324 relation.setDocumentId1("updated-" + relation.getDocumentId1());
325 relation.setDocumentType1("updated-" + relation.getDocumentType1());
326 relation.setDocumentId2("updated-" + relation.getDocumentId2());
327 relation.setDocumentType2("updated-" + relation.getDocumentType2());
328 if(logger.isDebugEnabled()){
329 verbose("updated object", relation, RelationsCommon.class);
332 // Submit the request to the service and store the response.
333 MultipartOutput output = new MultipartOutput();
334 OutputPart commonPart = output.addPart(relation, MediaType.APPLICATION_XML_TYPE);
335 commonPart.getHeaders().add("label", client.getCommonPartName());
336 res = client.update(knownResourceId, output);
337 int statusCode = res.getStatus();
338 // Check the status code of the response: does it match the expected response(s)?
339 if(logger.isDebugEnabled()){
340 logger.debug("update: status = " + res.getStatus());
342 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
343 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
344 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
346 input = (MultipartInput) res.getEntity();
347 RelationsCommon updatedObject = (RelationsCommon) extractPart(
348 input, client.getCommonPartName(),
349 RelationsCommon.class);
350 Assert.assertNotNull(updatedObject);
353 "Data in updated object did not match submitted data.";
355 updatedObject.getDocumentId1(), relation.getDocumentId1(), msg);
357 updatedObject.getDocumentType1(), relation.getDocumentType1(), msg);
359 updatedObject.getDocumentId2(), relation.getDocumentId2(), msg);
361 updatedObject.getDocumentType2(), relation.getDocumentType2(), msg);
366 // Placeholders until the three tests below can be uncommented.
367 // See Issue CSPACE-401.
368 public void updateWithEmptyEntityBody() throws Exception {
371 public void updateWithMalformedXml() throws Exception {
374 public void updateWithWrongXmlSchema() throws Exception {
379 @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
380 public void updateWithEmptyEntityBody() throws Exception {
383 setupUpdateWithEmptyEntityBody();
385 // Submit the request to the service and store the response.
386 String method = REQUEST_TYPE.httpMethodName();
387 String url = getResourceURL(knownResourceId);
388 String mediaType = MediaType.APPLICATION_XML;
389 final String entity = "";
390 int statusCode = submitRequest(method, url, mediaType, entity);
392 // Check the status code of the response: does it match
393 // the expected response(s)?
394 if(logger.isDebugEnabled()){
395 logger.debug("updateWithEmptyEntityBody url=" + url +
396 " status=" + statusCode);
398 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
399 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
400 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
404 @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
405 public void updateWithMalformedXml() throws Exception {
408 setupUpdateWithMalformedXml();
410 // Submit the request to the service and store the response.
411 String method = REQUEST_TYPE.httpMethodName();
412 String url = getResourceURL(knownResourceId);
413 String mediaType = MediaType.APPLICATION_XML;
414 final String entity = MALFORMED_XML_DATA; // Constant from abstract base class.
415 int statusCode = submitRequest(method, url, mediaType, entity);
417 // Check the status code of the response: does it match
418 // the expected response(s)?
419 if(logger.isDebugEnabled()){
420 logger.debug("updateWithMalformedXml: url=" + url +
421 " status=" + statusCode);
423 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
424 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
425 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
429 @Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
430 public void updateWithWrongXmlSchema() throws Exception {
433 setupUpdateWithWrongXmlSchema();
435 // Submit the request to the service and store the response.
436 String method = REQUEST_TYPE.httpMethodName();
437 String url = getResourceURL(knownResourceId);
438 String mediaType = MediaType.APPLICATION_XML;
439 final String entity = WRONG_XML_SCHEMA_DATA; // Constant from abstract base class.
440 int statusCode = submitRequest(method, url, mediaType, entity);
442 // Check the status code of the response: does it match
443 // the expected response(s)?
444 if(logger.isDebugEnabled()){
445 logger.debug("updateWithWrongXmlSchema: url=" + url +
446 " status=" + statusCode);
448 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
449 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
450 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
455 @Test(dependsOnMethods = {"update", "testSubmitRequest"})
456 public void updateNonExistent() throws Exception {
459 setupUpdateNonExistent();
461 // Submit the request to the service and store the response.
462 // Note: The ID used in this 'create' call may be arbitrary.
463 // The only relevant ID may be the one used in update(), below.
464 MultipartOutput multipart = createRelationInstance(NON_EXISTENT_ID);
465 ClientResponse<MultipartInput> res =
466 client.update(NON_EXISTENT_ID, multipart);
467 int statusCode = res.getStatus();
469 // Check the status code of the response: does it match
470 // the expected response(s)?
471 if(logger.isDebugEnabled()){
472 logger.debug("updateNonExistent: status = " + res.getStatus());
474 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
475 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
476 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
479 // ---------------------------------------------------------------
480 // CRUD tests : DELETE tests
481 // ---------------------------------------------------------------
484 @Test(dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
485 public void delete() throws Exception {
490 // Submit the request to the service and store the response.
491 ClientResponse<Response> res = client.delete(knownResourceId);
492 int statusCode = res.getStatus();
494 // Check the status code of the response: does it match
495 // the expected response(s)?
496 if(logger.isDebugEnabled()){
497 logger.debug("delete: status = " + res.getStatus());
499 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
500 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
501 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
506 @Test(dependsOnMethods = {"delete"})
507 public void deleteNonExistent() throws Exception {
510 setupDeleteNonExistent();
512 // Submit the request to the service and store the response.
513 ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
514 int statusCode = res.getStatus();
516 // Check the status code of the response: does it match
517 // the expected response(s)?
518 if(logger.isDebugEnabled()){
519 logger.debug("deleteNonExistent: status = " + res.getStatus());
521 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
522 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
523 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
526 // ---------------------------------------------------------------
527 // RELATE_OBJECT tests
528 // ---------------------------------------------------------------
529 @Test(dependsOnMethods = {"create"})
530 public void relateObjects() {
533 // ---------------------------------------------------------------
534 // Utility tests : tests of code used in tests above
535 // ---------------------------------------------------------------
537 * Tests the code for manually submitting data that is used by several
538 * of the methods above.
540 @Test(dependsOnMethods = {"create", "read"})
541 public void testSubmitRequest() {
543 // Expected status code: 200 OK
544 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
546 // Submit the request to the service and store the response.
547 String method = ServiceRequestType.READ.httpMethodName();
548 String url = getResourceURL(knownResourceId);
549 int statusCode = submitRequest(method, url);
551 // Check the status code of the response: does it match
552 // the expected response(s)?
553 if(logger.isDebugEnabled()){
554 logger.debug("testSubmitRequest: url=" + url +
555 " status=" + statusCode);
557 Assert.assertEquals(statusCode, EXPECTED_STATUS);
561 // ---------------------------------------------------------------
562 // Utility methods used by tests above
563 // ---------------------------------------------------------------
565 public String getServicePathComponent() {
566 return SERVICE_PATH_COMPONENT;
569 private MultipartOutput createRelationInstance(String identifier) {
570 RelationsCommon relation = new RelationsCommon();
571 fillRelation(relation, identifier);
573 MultipartOutput multipart = new MultipartOutput();
574 OutputPart commonPart =
575 multipart.addPart(relation, MediaType.APPLICATION_XML_TYPE);
576 commonPart.getHeaders().add("label", client.getCommonPartName());
577 if(logger.isDebugEnabled()){
578 verbose("to be created, relation common ", relation,
579 RelationsCommon.class);
585 * Fills the relation.
587 * @param identifier the identifier
589 * @return the relation
591 private void fillRelation(RelationsCommon relation, String identifier) {
592 fillRelation(relation, "Subject-" + identifier,
593 "SubjectType-" + identifier + "-type",
594 "Object-" + identifier,
595 "ObjectType-" + identifier + "-type",
596 RelationshipType.COLLECTIONOBJECT_INTAKE);
600 * Fills the relation.
602 * @param documentId1 the document id1
603 * @param documentType1 the document type1
604 * @param documentId2 the document id2
605 * @param documentType2 the document type2
608 * @return the relation
610 private void fillRelation(RelationsCommon relation,
611 String documentId1, String documentType1,
612 String documentId2, String documentType2,
613 RelationshipType rt) {
614 relation.setDocumentId1(documentId1);
615 relation.setDocumentType1(documentType1);
616 relation.setDocumentId2(documentId2);
617 relation.setDocumentType2(documentType2);
619 relation.setRelationshipType(rt);