package com.temenos.interaction.example.odata.notes;
/*
* #%L
* interaction-example-odata-notes
* %%
* Copyright (C) 2012 - 2013 Temenos Holdings N.V.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.Arrays;
import javax.ws.rs.core.Response;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.odata4j.consumer.ODataConsumer;
import org.odata4j.core.ODataConstants;
import org.odata4j.core.OEntity;
import org.odata4j.core.OProperties;
import org.odata4j.edm.EdmDataServices;
import org.odata4j.format.Entry;
import org.odata4j.format.FormatParser;
import org.odata4j.format.FormatParserFactory;
import org.odata4j.format.FormatType;
import org.odata4j.format.Settings;
import org.odata4j.jersey.consumer.ODataJerseyConsumer;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.test.framework.JerseyTest;
public class CreateReadUpdateDeleteITCase extends JerseyTest {
public final static String PERSONS_RESOURCE = "/Persons";
public final static String NOTES_RESOURCE = "/Notes";
private final static String NOTE_ENTITYSET_NAME = "Notes";
private final static String PERSON_ENTITYSET_NAME = "Persons";
@Before
public void initTest() {
// TODO make this configurable
// test with external server
webResource = Client.create().resource(Configuration.TEST_ENDPOINT_URI);
// Create note 3, linked to person 2 if it doesn't exist
ODataConsumer consumer = ODataJerseyConsumer.newBuilder(Configuration.TEST_ENDPOINT_URI).build();
OEntity person = null;
try {
person = consumer.getEntity(PERSON_ENTITYSET_NAME, 2).execute();
} catch (Exception e) {
// Ignore as Odata4j client 0.7 is expecting incorrect result
}
if (person == null) {
person = consumer
.createEntity(PERSON_ENTITYSET_NAME)
.properties(OProperties.string("name", "Ron"))
.execute();
}
OEntity note = null;
try {
note = consumer.getEntity(NOTE_ENTITYSET_NAME, 3).execute();
} catch (Exception e) {
// Ignore as Odata4j client 0.7 is expecting incorrect result
}
if (note == null) {
note = consumer
.createEntity(NOTE_ENTITYSET_NAME)
.properties(OProperties.string("body", "test"))
.link("NotePerson", person)
.execute();
}
}
@After
public void tearDown() {}
public CreateReadUpdateDeleteITCase() throws Exception {
/* Allows standalone Jersey Test
super("example", "rest", "com.temenos.interaction.example");
*/
// enable logging on base web resource
System.setProperty("enableLogging", "ya");
}
@Test
public void testOptions() {
String noteUri = NOTES_RESOURCE + "(1)";
ClientResponse response = webResource.path(noteUri).options(ClientResponse.class);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
assertEquals(5, response.getAllow().size());
assertTrue(response.getAllow().contains("GET"));
assertTrue(response.getAllow().contains("PUT"));
assertTrue(response.getAllow().contains("DELETE"));
assertTrue(response.getAllow().contains("OPTIONS"));
assertTrue(response.getAllow().contains("HEAD"));
}
@Test
public void testDeleteNote() {
String noteUri = NOTES_RESOURCE + "(3)";
// delete Note number 3 (which should now exists see initTest)
ClientResponse response = webResource.path(noteUri).delete(ClientResponse.class);
assertEquals(204, response.getStatus());
// make sure Note number 3 is really gone
ClientResponse deletedResponse = webResource.path(noteUri).get(ClientResponse.class);
assertEquals(404, deletedResponse.getStatus());
// delete Note number 56 (which does not exist)
String notFoundNoteUri = NOTES_RESOURCE + "(56)";
ClientResponse nresponse = webResource.path(notFoundNoteUri).delete(ClientResponse.class);
assertEquals(404, nresponse.getStatus());
}
@Test
public void testDeletePerson() {
// delete Person number 1 (which exists), but we have bound a NoopDELETECommand
String noteUri = PERSONS_RESOURCE + "(1)";
ClientResponse response = webResource.path(noteUri).delete(ClientResponse.class);
assertEquals(405, response.getStatus());
}
@Test
public void testCreate() {
ODataConsumer consumer = ODataJerseyConsumer.newBuilder(Configuration.TEST_ENDPOINT_URI).build();
OEntity person = consumer.createEntity(PERSON_ENTITYSET_NAME)
.properties(OProperties.string("name", "Ron"))
.execute();
assertTrue(person != null);
}
/**
* Tests create with application/x-www-form-urlencoded request Content-Type.
*
* @throws HttpException
* @throws IOException
*/
@Test
public void testCreateUrlEncodedForm() throws HttpException, IOException {
ODataConsumer consumer = ODataJerseyConsumer.newBuilder(Configuration.TEST_ENDPOINT_URI).build();
EdmDataServices metadata = consumer.getMetadata();
HttpClient client = new HttpClient();
PostMethod postMethod = new PostMethod(Configuration.TEST_ENDPOINT_URI + PERSONS_RESOURCE);
postMethod.setRequestEntity(new StringRequestEntity("name=RonOnForm&abcd=",
"application/x-www-form-urlencoded",
"UTF-8"));
postMethod.addRequestHeader("Content-Type", PostMethod.FORM_URL_ENCODED_CONTENT_TYPE);
postMethod.addRequestHeader("Accept", "application/atom+xml");
String personId = null;
try {
client.executeMethod(postMethod);
assertEquals(201, postMethod.getStatusCode());
InputStream is = postMethod.getResponseBodyAsStream();
InputStreamReader isr = new InputStreamReader(is);
char[] buffer = new char[1];
int read = 0;
int offset = 0;
while ((read = isr.read(buffer, offset, buffer.length - offset)) != -1) {
offset += read;
if (offset >= buffer.length) {
buffer = Arrays.copyOf(buffer, buffer.length * 2);
}
}
char[] carr = Arrays.copyOf(buffer, offset);
int checkEOF = is.read();
assertEquals(-1, checkEOF);
String str = new String(carr);
assertEquals("application/atom+xml", postMethod.getResponseHeader("Content-Type").getValue());
FormatParser<Entry> parser = FormatParserFactory.getParser(Entry.class,
FormatType.ATOM, new Settings(ODataConstants.DATA_SERVICE_VERSION, metadata, PERSON_ENTITYSET_NAME, null, null));
Entry entry = parser.parse(new StringReader(str));
personId = entry.getEntity().getProperty("id").getValue().toString();
assertEquals("RonOnForm", entry.getEntity().getProperty("name").getValue().toString());
} finally {
postMethod.releaseConnection();
}
assertNotNull(personId);
// read the person to check it was created ok
OEntity person = consumer.getEntity(PERSON_ENTITYSET_NAME, Integer.valueOf(personId)).execute();
assertTrue(person != null);
assertEquals("RonOnForm", person.getProperty("name").getValue());
}
@Test
public void testDelete() {
ODataConsumer consumer = ODataJerseyConsumer.newBuilder(Configuration.TEST_ENDPOINT_URI).build();
// find a person
OEntity person = null;
try {
person = consumer.getEntity(PERSON_ENTITYSET_NAME, 2).execute();
} catch (Exception e) {
// Ignore as Odata4j client 0.7 is expecting incorrect result
}
if (person == null) {
person = consumer
.createEntity(PERSON_ENTITYSET_NAME)
.properties(OProperties.string("name", "Ron"))
.execute();
}
// create a note
OEntity note = null;
try {
note = consumer.getEntity(NOTE_ENTITYSET_NAME, 6).execute();
} catch (Exception e) {
// Ignore as Odata4j client 0.7 is expecting incorrect result
}
if (note == null) {
note = consumer
.createEntity(NOTE_ENTITYSET_NAME)
.properties(OProperties.string("body", "test"))
.link("NotePerson", person)
.execute();
}
// delete one note
consumer.deleteEntity(note).execute();
// check its deleted
OEntity afterDelete = null;
boolean exceptionThrown = false;
try {
afterDelete = consumer.getEntity(note).execute();
} catch (Exception e) {
exceptionThrown = true;
}
assertEquals(true, exceptionThrown);
assertEquals(null, afterDelete);
}
// TODO AtomXMLProvider needs better support for matching of URIs to resources
@Test
public void testUpdate() {
// Create note for person 1
ODataConsumer consumer = ODataJerseyConsumer.newBuilder(Configuration.TEST_ENDPOINT_URI).build();
OEntity person = consumer.getEntity(PERSON_ENTITYSET_NAME, 1).execute();
OEntity note = consumer
.createEntity(NOTE_ENTITYSET_NAME)
.properties(OProperties.string("body", "test"))
.link("NotePerson", person)
.execute();
// update the note text
consumer.updateEntity(note)
.properties(OProperties.string("body", "new text for note"))
.execute();
// read the note again, check text
OEntity afterUpdate = consumer.getEntity(note).execute();
assertEquals("new text for note", afterUpdate.getProperty("body").getValue());
}
}