From: Aron Roberts Date: Sat, 25 Jul 2009 00:16:53 +0000 (+0000) Subject: CSPACE-327: Added initial 'negative' tests; some minor fixes, simplifications and... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=d6c14b8107f05d42aa4e4c8fcf10848ee5b49638;p=tmp%2Fjakarta-migration.git CSPACE-327: Added initial 'negative' tests; some minor fixes, simplifications and commenting. --- diff --git a/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java b/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java index ff4ed014e..5cff49160 100644 --- a/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java +++ b/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java @@ -1,3 +1,26 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.collectionspace.services.client.test; import java.util.ArrayList; @@ -17,150 +40,305 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * A CollectionObjectNuxeoServiceTest. + * CollectionObjectServiceTest, carries out tests against a + * deployed and running CollectionObject Service. * - * @version $Revision:$ + * $LastChangedRevision$ + * $LastChangedDate$ */ public class CollectionObjectServiceTest { - private CollectionObjectClient collectionObjectClient = CollectionObjectClient.getInstance(); - private String updateId = null; - private String deleteId = null; - final Logger logger = LoggerFactory.getLogger(CollectionObjectServiceTest.class); - - @Test - public void createCollectionObject() { - long identifier = this.createIdentifier(); - - CollectionObject collectionObject = createCollectionObject(identifier); - ClientResponse res = collectionObjectClient.createCollectionObject(collectionObject); - verbose("createCollectionObject: status = " + res.getStatus()); - Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode()); - - //store updateId locally for "update" test - if(updateId == null){ - updateId = extractId(res); - }else{ - deleteId = extractId(res); - verbose("Set deleteId: " + deleteId); - } - } + private CollectionObjectClient collectionObjectClient = CollectionObjectClient.getInstance(); + private String knownCollectionObjectId = null; + private final String NON_EXISTENT_ID = createNonExistentIdentifier(); + final Logger logger = LoggerFactory.getLogger(CollectionObjectServiceTest.class); + + + // --------------------------------------------------------------- + // Service Discovery tests + // --------------------------------------------------------------- - @Test(dependsOnMethods = {"createCollectionObject"}) - public void updateCollectionObject() { - ClientResponse res = collectionObjectClient.getCollectionObject(updateId); - verbose("getCollectionObject: status = " + res.getStatus()); - Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); - - CollectionObject collectionObject = res.getEntity(); - verbose("Got CollectionObject to update with ID: " + updateId, - collectionObject, CollectionObject.class); - - //collectionObject.setCsid("updated-" + updateId); - collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber()); - collectionObject.setObjectName("updated-" + collectionObject.getObjectName()); - - // make call to update service - res = collectionObjectClient.updateCollectionObject(updateId, collectionObject); - verbose("updateCollectionObject: status = " + res.getStatus()); - Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); - - // check the response - CollectionObject updatedCollectionObject = res.getEntity(); - Assert.assertEquals(updatedCollectionObject.getObjectName(), collectionObject.getObjectName()); - verbose("updateCollectionObject: ", updatedCollectionObject, CollectionObject.class); - - return; - } + // TBA + + + // --------------------------------------------------------------- + // CRUD tests : CREATE tests + // --------------------------------------------------------------- - @Test(dependsOnMethods = {"createCollectionObject"}) - public void createCollection() { - for(int i = 0; i < 3; i++){ - this.createCollectionObject(); - } - } + // Success outcomes + // ---------------- + + // NOTE The W3C HTTP spec suggests that the URL of the newly-created + // resource be returned in the Location header, as well as in the + // entity body of the response: . + // If we follow this practice in our service, we might also test for the presence of + // these URLs in the response headers (e.g. via res.getMetadata().getFirst("Location")) + // and entity body. - @Test(dependsOnMethods = {"createCollection"}) - public void getCollectionObjectList() { - //the resource method is expected to return at least an empty list - ClientResponse res = collectionObjectClient.getCollectionObjectList(); - CollectionObjectList coList = res.getEntity(); - verbose("getCollectionObjectList: status = " + res.getStatus()); - Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); - - List coItemList = coList.getCollectionObjectListItem(); - int i = 0; - for(CollectionObjectList.CollectionObjectListItem pli : coItemList){ - verbose("getCollectionObjectList: list-item[" + i + "] csid=" + pli.getCsid()); - verbose("getCollectionObjectList: list-item[" + i + "] objectNumber=" + pli.getObjectNumber()); - verbose("getCollectionObjectList: list-item[" + i + "] URI=" + pli.getUri()); - i++; - } - } + // Create + @Test + public void createCollectionObject() { + String identifier = this.createIdentifier(); - @Test(dependsOnMethods = {"createCollection"}) - public void deleteCollectionObject() { - verbose("Calling deleteCollectionObject:" + deleteId); - ClientResponse res = collectionObjectClient.deleteCollectionObject(deleteId); - verbose("deleteCollectionObject: csid=" + deleteId); - verbose("deleteCollectionObject: status = " + res.getStatus()); - Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); - } + CollectionObject collectionObject = createCollectionObject(identifier); + ClientResponse res = collectionObjectClient.createCollectionObject(collectionObject); + verbose("createCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode()); - private CollectionObject createCollectionObject(long identifier) { - CollectionObject collectionObject = createCollectionObject("objectNumber-" + identifier, - "objectName-" + identifier); + // Store the ID returned from this create operation for additional tests below. + knownCollectionObjectId = extractId(res); + knownCollectionObjectId = extractId(res); + } - return collectionObject; + // Create multiple (used for Read multiple tests, below) + @Test(dependsOnMethods = {"createCollectionObject"}) + public void createCollection() { + for(int i = 0; i < 3; i++){ + this.createCollectionObject(); } + } - private CollectionObject createCollectionObject(String objectNumber, String objectName) { - CollectionObject collectionObject = new CollectionObject(); + // Failure outcomes + // ---------------- - collectionObject.setObjectNumber(objectNumber); - collectionObject.setObjectName(objectName); + // Create : sending null payload - return collectionObject; - } + // Create : sending wrong schema in payload + + // Create : sending random data in payload - private String extractId(ClientResponse res) { - MultivaluedMap mvm = res.getMetadata(); - String uri = (String) ((ArrayList) mvm.get("Location")).get(0); - String[] segments = uri.split("/"); - String id = segments[segments.length - 1]; - verbose("id=" + id); - return id; - } + // Invalid CollectionObject schema + // Question: How can we pass an empty entity body, a different (non-CollectionObject) schema, + // and/or 'junk' data to the service via the CollectionObjectClient? + + // Create : with duplicate object ID + // + // Should fail with a 409 Conflict status code. + @Test(dependsOnMethods = {"createCollectionObject"}) + public void createDuplicateCollectionObject() { + CollectionObject collectionObject = createCollectionObject(knownCollectionObjectId); + ClientResponse res = + collectionObjectClient.createCollectionObject(collectionObject); + verbose("createDuplicateCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.CONFLICT.getStatusCode()); + } - private void verbose(String msg) { -// if(logger.isInfoEnabled()){ -// logger.debug(msg); -// } - System.out.println(msg); - } - private void verbose(String msg, Object o, Class clazz) { - try{ - verbose(msg); - JAXBContext jc = JAXBContext.newInstance(clazz); - Marshaller m = jc.createMarshaller(); - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, - Boolean.TRUE); - m.marshal(o, System.out); - }catch(Exception e){ - e.printStackTrace(); - } + // --------------------------------------------------------------- + // CRUD tests : READ tests + // --------------------------------------------------------------- + + // Success outcomes + // ---------------- + + // These two test methods have not yet been tested: + +/* + // Read + @Test(dependsOnMethods = {"createCollectionObject"}) + public void getCollectionObject() { + ClientResponse res = + collectionObjectClient.getCollectionObject(knownCollectionObjectId); + verbose("getCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); + } +*/ + + // Failure outcomes + // ---------------- + +/* + // Read : with non-existent object ID + // + // Should fail with a 404 Not Found status code. + @Test(dependsOnMethods = {"createCollectionObject"}) + public void getNonExistentCollectionObject() { + ClientResponse res = + collectionObjectClient.getCollectionObject(NON_EXISTENT_ID); + verbose("getNonExistentCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); + } +*/ + + // --------------------------------------------------------------- + // CRUD tests : READ (list, or multiple) tests + // --------------------------------------------------------------- + + // Success outcomes + // ---------------- + + // Read (multiple) + @Test(dependsOnMethods = {"createCollection"}) + public void getCollectionObjectList() { + // The resource method is expected to return at least an empty list + ClientResponse res = collectionObjectClient.getCollectionObjectList(); + CollectionObjectList coList = res.getEntity(); + verbose("getCollectionObjectList: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); + + List coItemList = + coList.getCollectionObjectListItem(); + int i = 0; + for(CollectionObjectList.CollectionObjectListItem pli : coItemList){ + verbose("getCollectionObjectList: list-item[" + i + "] csid=" + pli.getCsid()); + verbose("getCollectionObjectList: list-item[" + i + "] objectNumber=" + pli.getObjectNumber()); + verbose("getCollectionObjectList: list-item[" + i + "] URI=" + pli.getUri()); + i++; } + } + + // Failure outcomes + // ---------------- + + + + // --------------------------------------------------------------- + // CRUD tests : UPDATE tests + // --------------------------------------------------------------- - private void verboseMap(MultivaluedMap map) { - for(Object entry : map.entrySet()){ - MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry; - verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue()); - } + // Success outcomes + // ---------------- + + // Update + @Test(dependsOnMethods = {"createCollectionObject"}) + public void updateCollectionObject() { + ClientResponse res = + collectionObjectClient.getCollectionObject(knownCollectionObjectId); + verbose("getCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); + CollectionObject collectionObject = res.getEntity(); + verbose("Got CollectionObject to update with ID: " + knownCollectionObjectId, + collectionObject, CollectionObject.class); + + //collectionObject.setCsid("updated-" + knownCollectionObjectId); + collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber()); + collectionObject.setObjectName("updated-" + collectionObject.getObjectName()); + + // make call to update service + res = + collectionObjectClient.updateCollectionObject(knownCollectionObjectId, collectionObject); + verbose("updateCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); + + // check the response + CollectionObject updatedCollectionObject = res.getEntity(); + Assert.assertEquals(updatedCollectionObject.getObjectName(), + collectionObject.getObjectName()); + verbose("updateCollectionObject: ", updatedCollectionObject, CollectionObject.class); + } + + // Failure outcomes + // ---------------- + + // Update : with non-existent object ID + // + // Should fail with a 404 Not Found status code. + @Test(dependsOnMethods = {"updateCollectionObject"}) + public void updateNonExistentCollectionObject() { + CollectionObject collectionObject = createCollectionObject(NON_EXISTENT_ID); + // make call to update service + ClientResponse res = + collectionObjectClient.updateCollectionObject(NON_EXISTENT_ID, collectionObject); + verbose("createCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); + } + + + // --------------------------------------------------------------- + // CRUD tests : DELETE tests + // --------------------------------------------------------------- + + // Success outcomes + // ---------------- + + // Delete + @Test(dependsOnMethods = {"createCollectionObject"}) + public void deleteCollectionObject() { + verbose("Calling deleteCollectionObject:" + knownCollectionObjectId); + ClientResponse res = collectionObjectClient.deleteCollectionObject(knownCollectionObjectId); + verbose("deleteCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode()); + } + + // Failure outcomes + // ---------------- + + // Delete : with non-existent object ID + // + // Should fail with a 404 Not Found status code. + @Test(dependsOnMethods = {"deleteCollectionObject"}) + public void deleteNonExistentCollectionObject() { + verbose("Calling deleteCollectionObject:" + NON_EXISTENT_ID); + ClientResponse res = + collectionObjectClient.deleteCollectionObject(NON_EXISTENT_ID); + verbose("deleteCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); + } + + + // --------------------------------------------------------------- + // Utility methods used by tests above + // --------------------------------------------------------------- + + private CollectionObject createCollectionObject(String identifier) { + CollectionObject collectionObject = createCollectionObject("objectNumber-" + identifier, + "objectName-" + identifier); + + return collectionObject; + } + + private CollectionObject createCollectionObject(String objectNumber, String objectName) { + CollectionObject collectionObject = new CollectionObject(); + + collectionObject.setObjectNumber(objectNumber); + collectionObject.setObjectName(objectName); + + return collectionObject; + } + + private String extractId(ClientResponse res) { + MultivaluedMap mvm = res.getMetadata(); + String uri = (String) ((ArrayList) mvm.get("Location")).get(0); + String[] segments = uri.split("/"); + String id = segments[segments.length - 1]; + verbose("id=" + id); + return id; + } + + private void verbose(String msg) { +// if(logger.isInfoEnabled()){ +// logger.debug(msg); +// } + System.out.println(msg); + } + + private void verbose(String msg, Object o, Class clazz) { + try{ + verbose(msg); + JAXBContext jc = JAXBContext.newInstance(clazz); + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, + Boolean.TRUE); + m.marshal(o, System.out); + }catch(Exception e){ + e.printStackTrace(); } + } - private long createIdentifier() { - long identifier = System.currentTimeMillis(); - return identifier; + private void verboseMap(MultivaluedMap map) { + for(Object entry : map.entrySet()){ + MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry; + verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue()); } + } + + private String createIdentifier() { + long identifier = System.currentTimeMillis(); + return Long.toString(identifier); + } + + private String createNonExistentIdentifier() { + return Long.toString(Long.MAX_VALUE); + } + }