package org.collectionspace.services.client.test;
import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
public abstract class AbstractServiceTestImpl implements ServiceTest {
private final Logger logger =
- LoggerFactory.getLogger(AbstractServiceTestImpl.class);
+ LoggerFactory.getLogger(AbstractServiceTestImpl.class);
// A base-level client, used (only) to obtain the base service URL.
protected static final TestServiceClient serviceClient =
- new TestServiceClient();
+ new TestServiceClient();
// A resource identifier believed to be non-existent in actual use,
// used when testing service calls that reference non-existent resources.
protected final String NON_EXISTENT_ID = createNonExistentIdentifier();
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
// Note: this constant is intentionally missing its last angle bracket.
protected final static String MALFORMED_XML_DATA =
- XML_DECLARATION +
- "<malformed_xml>wrong schema contents</malformed_xml";
+ XML_DECLARATION
+ + "<malformed_xml>wrong schema contents</malformed_xml";
protected final String WRONG_XML_SCHEMA_DATA =
- XML_DECLARATION +
- "<wrong_schema>wrong schema contents</wrong_schema>";
+ XML_DECLARATION
+ + "<wrong_schema>wrong schema contents</wrong_schema>";
// A MIME media type character set designation for the entity bodies
// of PUT and POST requests. Set this to null to avoid adding a character
// set attribute to the MIME type in the "Content-Type:" HTTP header.
// ---------------------------------------------------------------
// CRUD tests : CREATE tests
// ---------------------------------------------------------------
-
// Success outcomes
@Override
public void create(String testName) throws Exception {
}
protected void setupCreate() {
- setupCreate("Create");
+ setupCreate("Create");
}
-
+
protected void setupCreate(String label) {
clearSetup();
// Expected status code: 201 Created
public abstract void createList(String testName) throws Exception;
// No setup required for createList()
-
// Failure outcomes
-
@Override
public abstract void createWithEmptyEntityBody(String testName)
- throws Exception;
+ throws Exception;
protected void setupCreateWithEmptyEntityBody() {
- setupCreateWithEmptyEntityBody("CreateWithEmptyEntityBody");
+ setupCreateWithEmptyEntityBody("CreateWithEmptyEntityBody");
}
-
+
protected void setupCreateWithEmptyEntityBody(String label) {
clearSetup();
EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
if (logger.isDebugEnabled()) {
banner(label);
}
- }
+ }
@Override
public abstract void createWithMalformedXml(String testName) throws Exception;
protected void setupCreateWithMalformedXml() {
- setupCreateWithMalformedXml("CreateWithMalformedXml");
+ setupCreateWithMalformedXml("CreateWithMalformedXml");
}
-
+
protected void setupCreateWithMalformedXml(String label) {
clearSetup();
// Expected status code: 400 Bad Request
public abstract void createWithWrongXmlSchema(String testName) throws Exception;
protected void setupCreateWithWrongXmlSchema() {
- setupCreateWithWrongXmlSchema("CreateWithWrongXmlSchema");
+ setupCreateWithWrongXmlSchema("CreateWithWrongXmlSchema");
}
-
+
protected void setupCreateWithWrongXmlSchema(String label) {
clearSetup();
// Expected status code: 400 Bad Request
// ---------------------------------------------------------------
// CRUD tests : READ tests
// ---------------------------------------------------------------
-
// Success outcomes
@Override
public abstract void read(String testName) throws Exception;
protected void setupRead() {
- setupRead("Read");
+ setupRead("Read");
}
-
+
protected void setupRead(String label) {
clearSetup();
// Expected status code: 200 OK
public abstract void readNonExistent(String testName) throws Exception;
protected void setupReadNonExistent() {
- setupReadNonExistent("ReadNonExistent");
+ setupReadNonExistent("ReadNonExistent");
}
protected void setupReadNonExistent(String label) {
// ---------------------------------------------------------------
// CRUD tests : READ (list, or multiple) tests
// ---------------------------------------------------------------
-
// Success outcomes
@Override
public abstract void readList(String testName) throws Exception;
protected void setupReadList() {
- setupReadList("ReadList");
+ setupReadList("ReadList");
}
-
+
protected void setupReadList(String label) {
clearSetup();
// Expected status code: 200 OK
// Failure outcomes
// None tested at present.
-
// ---------------------------------------------------------------
// CRUD tests : UPDATE tests
// ---------------------------------------------------------------
-
// Success outcomes
@Override
public abstract void update(String testName) throws Exception;
protected void setupUpdate() {
- setupUpdate("Update");
+ setupUpdate("Update");
}
-
+
protected void setupUpdate(String label) {
clearSetup();
// Expected status code: 200 OK
public abstract void updateWithEmptyEntityBody(String testName) throws Exception;
protected void setupUpdateWithEmptyEntityBody() {
- setupUpdateWithEmptyEntityBody("UpdateWithEmptyEntityBody");
+ setupUpdateWithEmptyEntityBody("UpdateWithEmptyEntityBody");
}
-
+
protected void setupUpdateWithEmptyEntityBody(String label) {
clearSetup();
// Expected status code: 400 Bad Request
public abstract void updateWithMalformedXml(String testName) throws Exception;
protected void setupUpdateWithMalformedXml() {
- setupUpdateWithMalformedXml("UpdateWithMalformedXml");
+ setupUpdateWithMalformedXml("UpdateWithMalformedXml");
}
-
+
protected void setupUpdateWithMalformedXml(String label) {
clearSetup();
// Expected status code: 400 Bad Request
public abstract void updateWithWrongXmlSchema(String testName) throws Exception;
protected void setupUpdateWithWrongXmlSchema() {
- setupUpdateWithWrongXmlSchema("UpdateWithWrongXmlSchema");
+ setupUpdateWithWrongXmlSchema("UpdateWithWrongXmlSchema");
}
-
+
protected void setupUpdateWithWrongXmlSchema(String label) {
clearSetup();
// Expected status code: 400 Bad Request
public abstract void updateNonExistent(String testName) throws Exception;
protected void setupUpdateNonExistent() {
- setupUpdateNonExistent("UpdateNonExistent");
+ setupUpdateNonExistent("UpdateNonExistent");
}
-
+
protected void setupUpdateNonExistent(String label) {
clearSetup();
// Expected status code: 404 Not Found
// ---------------------------------------------------------------
// CRUD tests : DELETE tests
// ---------------------------------------------------------------
-
// Success outcomes
@Override
public abstract void delete(String testName) throws Exception;
protected void setupDelete() {
- setupDelete("Delete");
+ setupDelete("Delete");
}
-
+
protected void setupDelete(String label) {
clearSetup();
// Expected status code: 200 OK
public abstract void deleteNonExistent(String testName) throws Exception;
protected void setupDeleteNonExistent() {
- setupDeleteNonExistent("DeleteNonExistent");
+ setupDeleteNonExistent("DeleteNonExistent");
}
-
+
protected void setupDeleteNonExistent(String label) {
clearSetup();
// Expected status code: 404 Not Found
*
* @return The common part name for the service request.
*/
-/*
+ /*
public String getCommonPartName();
-*/
-
+ */
// ---------------------------------------------------------------
// Utility methods
// ---------------------------------------------------------------
REQUEST_TYPE = ServiceRequestType.NON_EXISTENT;
}
- /**
- * Returns the name of the currently running test.
- *
- * Note: although the return type is listed as Object[][],
- * this method instead returns a String.
- *
- * @param m The currently running test method.
- *
- * @return The name of the currently running test method.
- */
- @DataProvider(name="testName")
- public static Object[][] testName(Method m){
+ /**
+ * Returns the name of the currently running test.
+ *
+ * Note: although the return type is listed as Object[][],
+ * this method instead returns a String.
+ *
+ * @param m The currently running test method.
+ *
+ * @return The name of the currently running test method.
+ */
+ @DataProvider(name = "testName")
+ public static Object[][] testName(Method m) {
return new Object[][]{
- new Object[] { m.getName() }
- };
+ new Object[]{m.getName()}
+ };
}
/**
* @return An error message.
*/
protected String invalidStatusCodeMessage(
- ServiceRequestType requestType, int statusCode) {
- return "Status code '" + statusCode +
- "' in response is NOT within the expected set: " +
- requestType.validStatusCodesAsString();
+ ServiceRequestType requestType, int statusCode) {
+ return "Status code '" + statusCode
+ + "' in response is NOT within the expected set: "
+ + requestType.validStatusCodesAsString();
}
/**
*/
protected int submitRequest(String method, String url) {
int statusCode = 0;
- try{
+ try {
TestServiceClient client = new TestServiceClient();
- if(method.equals(javax.ws.rs.HttpMethod.DELETE)){
+ if (method.equals(javax.ws.rs.HttpMethod.DELETE)) {
DeleteMethod deleteMethod = new DeleteMethod(url);
statusCode = client.getHttpClient().executeMethod(deleteMethod);
- }else if(method.equals(javax.ws.rs.HttpMethod.GET)){
+ } else if (method.equals(javax.ws.rs.HttpMethod.GET)) {
GetMethod getMethod = new GetMethod(url);
statusCode = client.getHttpClient().executeMethod(getMethod);
- }else{
+ } else {
// Do nothing - leave status code at default value.
}
- }catch(Exception e){
+ } catch (Exception e) {
logger.error(
- "Exception during HTTP " + method + " request to " +
- url + ":", e);
+ "Exception during HTTP " + method + " request to "
+ + url + ":", e);
}
return statusCode;
}
protected int submitRequest(String method, String url,
String mediaType, String entityStr) {
int statusCode = 0;
- try{
+ try {
TestServiceClient client = new TestServiceClient();
- if(method.equals(javax.ws.rs.HttpMethod.POST)){
+ if (method.equals(javax.ws.rs.HttpMethod.POST)) {
StringRequestEntity entityBody =
- new StringRequestEntity(mediaType, entityStr, NULL_CHARSET);
+ new StringRequestEntity(mediaType, entityStr, NULL_CHARSET);
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestEntity(entityBody);
statusCode = client.getHttpClient().executeMethod(postMethod);
- }else if(method.equals(javax.ws.rs.HttpMethod.PUT)){
+ } else if (method.equals(javax.ws.rs.HttpMethod.PUT)) {
StringRequestEntity entityBody =
- new StringRequestEntity(mediaType, entityStr, NULL_CHARSET);
+ new StringRequestEntity(mediaType, entityStr, NULL_CHARSET);
PutMethod putMethod = new PutMethod(url);
putMethod.setRequestEntity(entityBody);
statusCode = client.getHttpClient().executeMethod(putMethod);
- }else{
+ } else {
// Do nothing - leave status code at default value.
}
- }catch(Exception e){
+ } catch (Exception e) {
logger.error(
- "Exception during HTTP " + method + " request to " +
- url + ":", e);
+ "Exception during HTTP " + method + " request to "
+ + url + ":", e);
}
return statusCode;
}
protected String extractId(ClientResponse<Response> res) {
MultivaluedMap mvm = res.getMetadata();
String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
- if(logger.isDebugEnabled()){
+ if (logger.isDebugEnabled()) {
logger.debug("extractId:uri=" + uri);
}
String[] segments = uri.split("/");
String id = segments[segments.length - 1];
- if(logger.isDebugEnabled()){
+ if (logger.isDebugEnabled()) {
logger.debug("id=" + id);
}
return id;
}
- protected String createIdentifier() {
+ protected String createIdentifier() {
long identifier = System.currentTimeMillis();
return Long.toString(identifier);
}
}
protected Object extractPart(MultipartInput input, String label,
- Class clazz) throws Exception {
+ Class clazz) throws Exception {
Object obj = null;
String partLabel = "";
List<InputPart> parts = input.getParts();
if (parts.size() == 0) {
logger.warn("No parts found in multipart body.");
}
- if(logger.isDebugEnabled()){
+ if (logger.isDebugEnabled()) {
logger.debug("Parts:");
- for(InputPart part : parts){
- partLabel = part.getHeaders().getFirst("label");
- logger.debug("part = " + partLabel);
+ for (InputPart part : parts) {
+ partLabel = part.getHeaders().getFirst("label");
+ logger.debug("part = " + partLabel);
}
}
boolean partLabelMatched = false;
- for(InputPart part : parts){
+ for (InputPart part : parts) {
partLabel = part.getHeaders().getFirst("label");
- if(label.equalsIgnoreCase(partLabel)){
+ if (label.equalsIgnoreCase(partLabel)) {
partLabelMatched = true;
- if(logger.isDebugEnabled()){
+ if (logger.isDebugEnabled()) {
logger.debug("found part" + partLabel);
}
String partStr = part.getBodyAsString();
if (partStr == null || partStr.trim().isEmpty()) {
logger.warn("Part '" + label + "' in multipart body is empty.");
} else {
- if (logger.isDebugEnabled()){
+ if (logger.isDebugEnabled()) {
logger.debug("extracted part as str=\n" + partStr);
}
obj = part.getBody(clazz, null);
- if(logger.isDebugEnabled()){
+ if (logger.isDebugEnabled()) {
logger.debug("extracted part as obj=\n",
- objectAsXmlString(obj, clazz));
+ objectAsXmlString(obj, clazz));
}
}
break;
}
}
- if (! partLabelMatched) {
+ if (!partLabelMatched) {
logger.warn("Could not find part '" + label + "' in multipart body.");
- // In the event that getBodyAsString() or getBody(), above, do *not*
- // throw an IOException, but getBody() nonetheless retrieves a null object.
- // This *may* be unreachable.
+ // In the event that getBodyAsString() or getBody(), above, do *not*
+ // throw an IOException, but getBody() nonetheless retrieves a null object.
+ // This *may* be unreachable.
} else if (obj == null) {
- logger.warn("Could not extract part '" + label +
- "' in multipart body as an object.");
+ logger.warn("Could not extract part '" + label
+ + "' in multipart body as an object.");
}
return obj;
}
protected Object getPartObject(String partStr, Class clazz)
- throws JAXBException {
+ throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(clazz);
ByteArrayInputStream bais = null;
Object obj = null;
- try{
+ try {
bais = new ByteArrayInputStream(partStr.getBytes());
Unmarshaller um = jc.createUnmarshaller();
obj = um.unmarshal(bais);
- }finally{
- if(bais != null){
- try{
+ } finally {
+ if (bais != null) {
+ try {
bais.close();
- }catch(Exception e){
+ } catch (Exception e) {
}
}
}
// @TODO Some of the methods below may be candidates
// to be moved to a utilities module, suitable for use
// by both client-side and server-side code.
-
protected String objectAsXmlString(Object o, Class clazz) {
StringWriter sw = new StringWriter();
- try{
+ try {
JAXBContext jc = JAXBContext.newInstance(clazz);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
m.marshal(o, sw);
- }catch(Exception e){
+ } catch (Exception e) {
e.printStackTrace();
}
return sw.toString();
}
+
+ /**
+ * getObjectFromFile get object of given class from given file (in classpath)
+ * @param jaxbClass
+ * @param fileName of the file to read to construct the object
+ * @return
+ * @throws Exception
+ */
+ protected Object getObjectFromFile(Class jaxbClass, String fileName)
+ throws Exception {
+
+ JAXBContext context = JAXBContext.newInstance(jaxbClass);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ //note: setting schema to null will turn validator off
+ unmarshaller.setSchema(null);
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ InputStream is = tccl.getResourceAsStream(fileName);
+ return getObjectFromStream(jaxbClass, is);
+ }
+
+ /**
+ * getObjectFromStream get object of given class from given inputstream
+ * @param jaxbClass
+ * @param is stream to read to construct the object
+ * @return
+ * @throws Exception
+ */
+ protected Object getObjectFromStream(Class jaxbClass, InputStream is) throws Exception {
+ JAXBContext context = JAXBContext.newInstance(jaxbClass);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ //note: setting schema to null will turn validator off
+ unmarshaller.setSchema(null);
+ return jaxbClass.cast(unmarshaller.unmarshal(is));
+ }
protected String mapAsString(MultivaluedMap map) {
StringBuffer sb = new StringBuffer();
- for(Object entry : map.entrySet()){
+ for (Object entry : map.entrySet()) {
MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry;
sb.append(" name=" + mentry.getKey());
sb.append(" value=" + mentry.getValue() + "\n");
}
protected void banner(String label) {
- if(logger.isDebugEnabled()){
+ if (logger.isDebugEnabled()) {
logger.debug("===================================================");
logger.debug(" Test = " + label);
logger.debug("===================================================");
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Document : testCambridge.xml
+ Created on : February 18, 2010, 12:10 PM
+ Author :
+ Description:
+ Purpose of the document follows.
+-->
+
+<ns2:collectionobjects_common xmlns:ns2="http://collectionspace.org/services/collectionobject">
+ <objectNumber>objectNumber</objectNumber>
+ <otherNumber>XXX</otherNumber>
+ <otherNumberType>otherNumberType</otherNumberType>
+ <briefDescription>briefDescription</briefDescription>
+ <comments>comments</comments>
+ <distinguishingFeatures>distFeatures</distinguishingFeatures>
+ <numberOfObjects>numberOfObjects</numberOfObjects>
+ <objectName>objectName</objectName>
+ <objectNameCurrency>objectNameCurrency</objectNameCurrency>
+ <objectNameLevel>XXX</objectNameLevel>
+ <objectNameNote>objectNameNote</objectNameNote>
+ <objectNameSystem>objectNameSystem</objectNameSystem>
+ <objectNameType>objectNameType</objectNameType>
+ <objectNameLanguage>objectNameLanguage</objectNameLanguage>
+ <responsibleDepartments>
+ <!--
+ <responsibleDepartment xtmplpoint="responsibleDept"/>
+ -->
+ </responsibleDepartments>
+ <title>title</title>
+ <objectTitleLanguage>objectTitleLanguage</objectTitleLanguage>
+ <titleTranslation>titleTranslation</titleTranslation>
+ <titleType>titleType</titleType>
+ <age>age</age>
+ <ageQualifier>ageQualifier</ageQualifier>
+ <ageUnit>ageUnit</ageUnit>
+ <color>color</color>
+ <contentActivity>contentActivity</contentActivity>
+ <contentConcept>contentConcept</contentConcept>
+ <contentDate>XXX</contentDate>
+ <contentDescription>contentDescription</contentDescription>
+ <contentEventName>contentEventName</contentEventName>
+ <contentEventNameType>contentEventNameType</contentEventNameType>
+ <contentNote>contentNote</contentNote>
+ <contentLanguage>contentLanguage</contentLanguage>
+ <contentObject>contentObject</contentObject>
+ <contentObjectType>contentObjectType</contentObjectType>
+ <contentOrganization>contentOrganization</contentOrganization>
+ <contentOther>contentOther</contentOther>
+ <contentOtherType>contentOtherType</contentOtherType>
+ <contentPeople>contentPeople</contentPeople>
+ <contentPerson>contentPerson</contentPerson>
+ <contentPlace>contentPlace</contentPlace>
+ <contentPosition>contentPosition</contentPosition>
+ <contentScript>XXX</contentScript>
+ <copyNumber>copyNumber</copyNumber>
+ <dimension>dimension</dimension>
+ <dimensionMeasuredPart>dimensionMeasuredPart</dimensionMeasuredPart>
+
+<dimensionMeasurementUnit>dimensionMeasurementUnit</dimensionMeasurementUnit>
+ <dimensionValue>dimensionValue</dimensionValue>
+ <dimensionValueDate>XXX</dimensionValueDate>
+
+<dimensionValueQualifier>dimensionValueQualifier</dimensionValueQualifier>
+ <editionNumber>editionNumber</editionNumber>
+ <form>form</form>
+ <inscriptionContent>inscriptionContent</inscriptionContent>
+ <inscriber>inscriber</inscriber>
+ <inscriptionDate>inscriptionDate</inscriptionDate>
+
+<inscriptionInterpretation>inscriptionInterpretation</inscriptionInterpretation>
+ <inscriptionLanguage>inscriptionLanguage</inscriptionLanguage>
+ <inscriptionMethod>inscriptionMethod</inscriptionMethod>
+ <inscriptionPosition>inscriptionPosition</inscriptionPosition>
+ <inscriptionScript>inscriptionScript</inscriptionScript>
+ <inscriptionTranslation>inscriptionTranslation</inscriptionTranslation>
+
+<inscriptionTransliteration>inscriptionTransliteration</inscriptionTransliteration>
+ <inscriptionType>inscriptionType</inscriptionType>
+ <inscriptionDescription>inscriptionDescription</inscriptionDescription>
+
+<inscriptionDescriptionInscriber>inscriptionDescriptionInscriber</inscriptionDescriptionInscriber>
+
+<inscriptionDescriptionDate>inscriptionDescriptionDate</inscriptionDescriptionDate>
+
+<inscriptionDescriptionInterpretation>inscriptionDescriptionInterpretation</inscriptionDescriptionInterpretation>
+
+<inscriptionDescriptionMethod>inscriptionDescriptionMethod</inscriptionDescriptionMethod>
+
+<inscriptionDescriptionPosition>inscriptionDescriptionPosition</inscriptionDescriptionPosition>
+
+<inscriptionDescriptionType>inscriptionDescriptionType</inscriptionDescriptionType>
+ <material>material</material>
+ <materialComponent>materialComponent</materialComponent>
+ <materialComponentNote>materialComponentNote</materialComponentNote>
+ <materialName>materialName</materialName>
+ <materialSource>materialSource</materialSource>
+ <objectStatus>objectStatus</objectStatus>
+ <phase>phase</phase>
+ <physicalDescription>physicalDescription</physicalDescription>
+ <sex>sex</sex>
+ <style>style</style>
+ <technicalAttribute>technicalAttribute</technicalAttribute>
+
+<technicalAttributeMeasurement>technicalAttributeMeasurement</technicalAttributeMeasurement>
+
+<technicalAttributeMeasurementUnit>technicalAttributeMeasurementUnit</technicalAttributeMeasurementUnit>
+ <objectComponentName>objectComponentName</objectComponentName>
+
+<objectComponentInformation>objectComponentInformation</objectComponentInformation>
+ <dateAssociation>dateAssociation</dateAssociation>
+
+<dateEarliestSingle>{"level":"objectLevel","content-script":"descContentScript","content-method":"descContentMethod","otherNumber":"otherNumber"}</dateEarliestSingle>
+ <!-- XXX -->
+
+<dateEarliestSingleCertainty>dateEarliestSingleCertainty</dateEarliestSingleCertainty>
+
+<dateEarliestSingleQualifier>dateEarlierstSingleQualifier</dateEarliestSingleQualifier>
+ <dateLatest>XXX</dateLatest>
+ <dateLatestCertainty>dateLatestCertainty</dateLatestCertainty>
+ <dateLatestQualifier>dateLatestQualifier</dateLatestQualifier>
+ <datePeriod>datePeriod</datePeriod>
+ <dateText>dateText</dateText>
+</ns2:collectionobjects_common>