package org.fenixedu.bennu.core.rest;
import static org.junit.Assert.assertEquals;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.fenixedu.bennu.core.domain.Bennu;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import pt.ist.fenixframework.test.core.FenixFrameworkRunner;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
/***
* Tests for reading and writing body message as well as param convertion from/to String/JsonElement.
*
* @author Sérgio Silva (sergio.silva@tecnico.ulisboa.pt)
*
* @see JsonBodyReaderWriter
* @see JsonParamConverterProvider
* @see JerseyTest
*
*/
@RunWith(FenixFrameworkRunner.class)
public class GsonBodyReaderWriterTest extends JerseyTest {
private static String urlEncode(String payload) {
try {
return URLEncoder.encode(payload, "UTF-8").replace("+", "%20");
} catch (UnsupportedEncodingException e) {
throw new Error(e); //will never happen
}
}
@Path("resource")
public static class TestResource {
@Path("/bodyreadertest")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public String getJsonNameProperty(JsonElement json) {
return json.getAsJsonObject().get("name").getAsString();
}
@Path("/bodywritertest")
@GET
@Produces(MediaType.APPLICATION_JSON)
public JsonElement getJsonElement(@QueryParam("name") String name) {
JsonObject json = new JsonObject();
json.addProperty("name", name);
return json;
}
@Path("/readerwritertest")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JsonArray map(@QueryParam("data") JsonObject data, JsonArray elements) {
JsonArray array = new JsonArray();
array.add(new JsonPrimitive("Doing map for " + data.get("name").getAsString()));
for (JsonElement el : elements) {
final int newValue = el.getAsJsonObject().get("value").getAsInt() * 2;
el.getAsJsonObject().addProperty("value", newValue);
array.add(el);
}
return array;
}
@Path("/readerwritertest")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JsonObject map(@QueryParam("data") JsonObject data) {
return data;
}
@Path("/readerwritertestparams")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
public JsonArray readerwritertestparams(@QueryParam("bennu") Bennu bennu, @QueryParam("query") JsonObject data,
@FormParam("body") JsonElement body) {
JsonArray array = new JsonArray();
array.add(new JsonPrimitive("Doing map for " + data.get("name").getAsString()));
array.add(new JsonPrimitive(bennu.getExternalId()));
for (JsonElement el : body.getAsJsonArray()) {
final int newValue = el.getAsJsonObject().get("value").getAsInt() * 2;
el.getAsJsonObject().addProperty("value", newValue);
array.add(el);
}
return array;
}
}
@Override
protected void configureClient(ClientConfig config) {
super.configureClient(config);
config.register(JsonBodyReaderWriter.class);
}
@Override
protected Application configure() {
return new ResourceConfig(TestResource.class, JsonParamConverterProvider.class, JsonBodyReaderWriter.class,
DomainObjectParamConverter.class);
}
@Test
public void testBodyReader() {
JsonObject json = new JsonObject();
json.addProperty("name", "John Doe");
final String johnDoe =
target("resource").path("bodyreadertest").request(MediaType.APPLICATION_JSON)
.post(Entity.entity(json.toString(), MediaType.APPLICATION_JSON), String.class);
assertEquals("John Doe", johnDoe);
}
@Test
public void testBodyWriter() {
final JsonObject json =
target("resource").path("bodywritertest").queryParam("name", "John Doe").request(MediaType.APPLICATION_JSON)
.get(JsonObject.class);
JsonObject expected = new JsonObject();
expected.addProperty("name", "John Doe");
assertEquals(expected, json);
}
@Test
public void testJsonObjectReaderWriter() throws UnsupportedEncodingException {
JsonObject payload = new JsonObject();
payload.addProperty("value", 1);
JsonObject response =
target("resource").path("readerwritertest").queryParam("data", urlEncode(payload.toString()))
.request(MediaType.APPLICATION_JSON).get(JsonObject.class);
assertEquals(payload.toString(), response.toString());
}
@Test
public void testMalformedJson() throws UnsupportedEncodingException {
String payload = "{'xpto': '}";
Response response =
target("resource").path("readerwritertest").queryParam("data", urlEncode(payload))
.request(MediaType.APPLICATION_JSON).get();
assertEquals(Status.BAD_REQUEST, response.getStatusInfo());
}
@Test
public void testBoth() throws UnsupportedEncodingException {
JsonObject payload = new JsonObject();
payload.addProperty("name", "testBoth");
String values = "[{\"value\" : 1}, {\"value\" : 2}, {\"value\" : 3} , {\"value\" : 4}]";
final JsonArray mapResult =
target("resource").path("readerwritertest").queryParam("data", urlEncode(payload.toString()))
.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(values, MediaType.APPLICATION_JSON), JsonArray.class);
assertEquals("Doing map for testBoth", mapResult.get(0).getAsString());
assertEquals(2, mapResult.get(1).getAsJsonObject().get("value").getAsInt());
assertEquals(4, mapResult.get(2).getAsJsonObject().get("value").getAsInt());
assertEquals(6, mapResult.get(3).getAsJsonObject().get("value").getAsInt());
assertEquals(8, mapResult.get(4).getAsJsonObject().get("value").getAsInt());
}
@Test
public void testWithBodyAndParams() throws UnsupportedEncodingException {
JsonObject payload = new JsonObject();
final String bennuId = Bennu.getInstance().getExternalId();
payload.addProperty("name", "testBoth");
String values = "[{\"value\" : 1}, {\"value\" : 2}, {\"value\" : 3} , {\"value\" : 4}]";
Form form = new Form();
form.param("body", values);
final JsonArray mapResult =
target("resource").path("readerwritertestparams").queryParam("bennu", bennuId)
.queryParam("query", urlEncode(payload.toString())).request(MediaType.APPLICATION_JSON)
.post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), JsonArray.class);
assertEquals("Doing map for testBoth", mapResult.get(0).getAsString());
assertEquals(bennuId, mapResult.get(1).getAsString());
assertEquals(2, mapResult.get(2).getAsJsonObject().get("value").getAsInt());
assertEquals(4, mapResult.get(3).getAsJsonObject().get("value").getAsInt());
assertEquals(6, mapResult.get(4).getAsJsonObject().get("value").getAsInt());
assertEquals(8, mapResult.get(5).getAsJsonObject().get("value").getAsInt());
}
}