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.
24 package org.collectionspace.services.client.test;
26 import java.util.ArrayList;
27 import java.util.List;
28 import javax.ws.rs.core.MultivaluedMap;
29 import javax.ws.rs.core.Response;
30 import javax.xml.bind.JAXBContext;
31 import javax.xml.bind.Marshaller;
32 import org.jboss.resteasy.client.ClientResponse;
33 import org.testng.Assert;
34 import org.testng.annotations.Test;
36 import org.collectionspace.services.intake.Intake;
37 import org.collectionspace.services.intake.IntakeList;
38 import org.collectionspace.services.client.IntakeClient;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * IntakeServiceTest, carries out tests against a
44 * deployed and running Intake Service.
46 * $LastChangedRevision: 511 $
47 * $LastChangedDate: 2009-08-06 20:16:16 +0000 (Thu, 06 Aug 2009) $
49 public class IntakeServiceTest {
51 private IntakeClient intakeClient = new IntakeClient();
52 private String knownIntakeId = null;
53 private final String NON_EXISTENT_ID = createNonExistentIdentifier();
54 final Logger logger = LoggerFactory.getLogger(IntakeServiceTest.class);
56 // ---------------------------------------------------------------
57 // Service Discovery tests
58 // ---------------------------------------------------------------
63 // ---------------------------------------------------------------
64 // CRUD tests : CREATE tests
65 // ---------------------------------------------------------------
71 * Tests creation of a new Intake.
73 * Expected status code: 201 Created
75 * Also expected: The 'Location' header contains the URL for the newly created object.
76 * This is required by the extractId() utility method, below.
78 * The newly-created Intake is also used by other test(s)
79 * (e.g. update, delete) which follow, below.
82 public void createIntake() {
83 String identifier = this.createIdentifier();
85 Intake intake = createIntake(identifier);
86 ClientResponse<Response> res = intakeClient.createIntake(intake);
87 verbose("createIntake: status = " + res.getStatus());
88 Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
90 // Store the ID returned from this create operation for additional tests below.
91 knownIntakeId = extractId(res);
95 * Creates two or more new Intakes.
97 * Repeatedly calls the createIntake test, above, and relies on its
100 * Expected status code: 201 Created
102 * The newly-created Intakes are also used by other test(s)
103 * (e.g. read multiple/list) which follow, below.
105 @Test(dependsOnMethods = {"createIntake"})
106 public void createCollection() {
107 for(int i = 0; i < 3; i++){
116 * Tests creation of a Intake by sending a null to the client proxy.
118 * Expected status code: (none)
120 * Expected result: IllegalArgumentException
121 * (Make sure this is a reported exception in the called class.)
123 @Test(dependsOnMethods = {"createIntake"}, expectedExceptions = IllegalArgumentException.class)
124 public void createNullIntake() {
125 ClientResponse<Response> res = intakeClient.createIntake(null);
129 * Tests creation of an Intake by sending bad data
130 * (e.g. in a format that doesn't match the Intake schema)
131 * in the entity body of the request.
133 * Expected status code: 400 Bad Request
136 @Test(dependsOnMethods = {"createIntake"})
137 public void createIntakeWithBadData() {
138 // Currently only a stub.
143 * Tests creation of an Intake by a user who
144 * is not authorized to perform this action.
146 * Expected status code: 403 Forbidden
149 @Test(dependsOnMethods = {"createIntake"})
150 public void createIntakeWithUnauthorizedUser() {
151 // Currently only a stub.
156 * Tests creation of a duplicate Intake, whose unique resource identifier
157 * duplicates that of an existing Intake.
159 * Expected status code: 409 Conflict
162 @Test(dependsOnMethods = {"createIntake"})
163 public void createDuplicateIntake() {
164 Intake intake = createIntake(knownIntakeId);
165 ClientResponse<Response> res =
166 intakeClient.createIntake(intake);
167 verbose("createDuplicateIntake: status = " + res.getStatus());
168 Assert.assertEquals(res.getStatus(), Response.Status.CONFLICT.getStatusCode());
172 // ---------------------------------------------------------------
173 // CRUD tests : READ tests
174 // ---------------------------------------------------------------
180 * Tests reading (i.e. retrieval) of a Intake.
182 * Expected status code: 200 OK
184 @Test(dependsOnMethods = {"createIntake"})
185 public void getIntake() {
186 ClientResponse<Intake> res =
187 intakeClient.getIntake(knownIntakeId);
188 verbose("getIntake: status = " + res.getStatus());
189 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
196 * Tests reading (i.e. retrieval) of a Intake by a user who
197 * is not authorized to perform this action.
199 * Expected status code: 403 Forbidden
202 @Test(dependsOnMethods = {"getIntake"})
203 public void getIntakeWithUnauthorizedUser() {
204 // Currently only a stub
209 * Tests reading (i.e. retrieval) of a non-existent Intake,
210 * whose resource identifier does not exist at the specified URL.
212 * Expected status code: 404 Not Found
214 @Test(dependsOnMethods = {"getIntake"})
215 public void getNonExistentIntake() {
216 ClientResponse<Intake> res =
217 intakeClient.getIntake(NON_EXISTENT_ID);
218 verbose("getNonExistentIntake: status = " + res.getStatus());
219 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
223 // ---------------------------------------------------------------
224 // CRUD tests : READ (list, or multiple) tests
225 // ---------------------------------------------------------------
231 * Tests reading (i.e. retrieval) of a list of multiple Intakes.
233 * Expected status code: 200 OK
235 * Also expected: The entity body in the response contains
236 * a representation of the list of Intakes.
238 @Test(dependsOnMethods = {"createCollection"})
239 public void getIntakeList() {
240 // The resource method is expected to return at least an empty list
241 ClientResponse<IntakeList> res = intakeClient.getIntakeList();
242 IntakeList coList = res.getEntity();
243 verbose("getIntakeList: status = " + res.getStatus());
244 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
246 List<IntakeList.IntakeListItem> coItemList =
247 coList.getIntakeListItem();
249 for(IntakeList.IntakeListItem pli : coItemList){
250 verbose("getIntakeList: list-item[" + i + "] csid=" + pli.getCsid());
251 verbose("getIntakeList: list-item[" + i + "] entryNumber=" + pli.getEntryNumber());
252 verbose("getIntakeList: list-item[" + i + "] URI=" + pli.getUri());
258 * Tests reading (i.e. retrieval) of a list of multiple Intakes
259 * when the contents of the list are expected to be empty.
261 * Expected status code: 200 OK
262 * (Note: *not* 204 No Content)
264 * Also expected: The entity body in the response contains
265 * a representation of an empty list of Intakes.
268 @Test(dependsOnMethods = {"getIntakeList"})
269 public void getIntakeEmptyList() {
270 // Currently only a stub.
278 * Tests reading (i.e. retrieval) of a list of Intakes
279 * when sending unrecognized query parameters with the request.
281 * Expected status code: 400 Bad Request
284 @Test(dependsOnMethods = {"getIntakeList"})
285 public void getIntakeListWithBadParams() {
286 // Currently only a stub.
291 * Tests reading (i.e. retrieval) of a list of Intakes by a user who
292 * is not authorized to perform this action.
294 * Expected status code: 403 Forbidden
297 @Test(dependsOnMethods = {"getIntakeList"})
298 public void getIntakeListWithUnauthorizedUser() {
299 // Currently only a stub.
305 // ---------------------------------------------------------------
306 // CRUD tests : UPDATE tests
307 // ---------------------------------------------------------------
313 * Tests updating the content of a Intake.
315 * Expected status code: 200 OK
317 * Also expected: The entity body in the response contains
318 * a representation of the updated Intake.
320 @Test(dependsOnMethods = {"createIntake"})
321 public void updateIntake() {
322 ClientResponse<Intake> res =
323 intakeClient.getIntake(knownIntakeId);
324 verbose("getIntake: status = " + res.getStatus());
325 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
326 Intake intake = res.getEntity();
327 verbose("Got Intake to update with ID: " + knownIntakeId,
328 intake, Intake.class);
330 //intake.setCsid("updated-" + knownIntakeId);
331 intake.setEntryNumber("updated-" + intake.getEntryNumber());
332 intake.setEntryDate("updated-" + intake.getEntryDate());
334 // make call to update service
336 intakeClient.updateIntake(knownIntakeId, intake);
337 verbose("updateIntake: status = " + res.getStatus());
338 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
340 // check the response
341 Intake updatedIntake = res.getEntity();
342 Assert.assertEquals(updatedIntake.getEntryDate(), intake.getEntryDate());
343 verbose("updateIntake ", updatedIntake, Intake.class);
350 * Tests updating the content of a Intake by sending bad data
351 * (e.g. in a format that doesn't match the Intake schema)
352 * in the entity body of the request.
354 * Expected status code: 400 Bad Request
357 @Test(dependsOnMethods = {"updateIntake"})
358 public void updateIntakeWithBadData() {
359 // Currently only a stub.
364 * Tests updating the content of a Intake by a user who
365 * is not authorized to perform this action.
367 * Expected status code: 403 Forbidden
370 @Test(dependsOnMethods = {"updateIntake"})
371 public void updateIntakeWithUnauthorizedUser() {
372 // Currently only a stub.
377 * Tests updating the content of a non-existent Intake, whose
378 * resource identifier does not exist.
380 * Expected status code: 404 Not Found
382 @Test(dependsOnMethods = {"updateIntake"})
383 public void updateNonExistentIntake() {
384 // Note: The ID used in this 'create' call may be arbitrary.
385 // The only relevant ID may be the one used in updateIntake(), below.
386 Intake intake = createIntake(NON_EXISTENT_ID);
387 // make call to update service
388 ClientResponse<Intake> res =
389 intakeClient.updateIntake(NON_EXISTENT_ID, intake);
390 verbose("createIntake: status = " + res.getStatus());
391 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
395 // ---------------------------------------------------------------
396 // CRUD tests : DELETE tests
397 // ---------------------------------------------------------------
403 * Tests deleting a Intake.
405 * Expected status code: 200 OK
407 @Test(dependsOnMethods = {"createIntake", "getIntake"})
408 public void deleteIntake() {
409 verbose("Calling deleteIntake: " + knownIntakeId);
410 ClientResponse<Response> res = intakeClient.deleteIntake(knownIntakeId);
411 verbose("deleteIntake csid=" + knownIntakeId);
412 verbose("deleteIntake: status = " + res.getStatus());
413 Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
420 * Tests deleting a Intake by a user who
421 * is not authorized to perform this action.
423 * Expected status code: 403 Forbidden
426 @Test(dependsOnMethods = {"deleteIntake"})
427 public void deleteIntakeWithUnauthorizedUser() {
428 // Currently only a stub.
433 * Tests deleting a non-existent Intake, whose
434 * resource identifier does not exist at the specified URL.
436 * Expected status code: 404 Not Found
438 @Test(dependsOnMethods = {"deleteIntake"})
439 public void deleteNonExistentIntake() {
440 verbose("Calling deleteIntake: " + NON_EXISTENT_ID);
441 ClientResponse<Response> res =
442 intakeClient.deleteIntake(NON_EXISTENT_ID);
443 verbose("deleteIntake: status = " + res.getStatus());
444 Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
448 // ---------------------------------------------------------------
449 // Utility methods used by tests above
450 // ---------------------------------------------------------------
452 private Intake createIntake(String identifier) {
453 Intake intake = createIntake("entryNumber-" + identifier,
454 "entryDate-" + identifier);
459 private Intake createIntake(String entryNumber, String entryDate) {
460 Intake intake = new Intake();
462 intake.setEntryNumber(entryNumber);
463 intake.setEntryDate(entryDate);
468 private String extractId(ClientResponse<Response> res) {
469 MultivaluedMap mvm = res.getMetadata();
470 String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
471 verbose("extractId:uri=" + uri);
472 String[] segments = uri.split("/");
473 String id = segments[segments.length - 1];
478 private void verbose(String msg) {
479 // if(logger.isInfoEnabled()){
480 // logger.debug(msg);
482 System.out.println(msg);
485 private void verbose(String msg, Object o, Class clazz) {
488 JAXBContext jc = JAXBContext.newInstance(clazz);
489 Marshaller m = jc.createMarshaller();
490 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
492 m.marshal(o, System.out);
498 private void verboseMap(MultivaluedMap map) {
499 for(Object entry : map.entrySet()){
500 MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry;
501 verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue());
505 private String createIdentifier() {
506 long identifier = System.currentTimeMillis();
507 return Long.toString(identifier);
510 private String createNonExistentIdentifier() {
511 return Long.toString(Long.MAX_VALUE);