common-smartgears/src/test/java/test/application/ControllerTest.java

289 lines
7.9 KiB
Java

package test.application;
import static app.Request.request;
import static org.gcube.smartgears.Constants.accept;
import static org.gcube.smartgears.Constants.allow;
import static org.gcube.smartgears.Constants.content_type;
import static org.gcube.smartgears.extensions.ApiResource.handles;
import static org.gcube.smartgears.extensions.ApiResource.method;
import static org.gcube.smartgears.extensions.HttpExtension.Method.GET;
import static org.gcube.smartgears.extensions.HttpExtension.Method.POST;
import static org.gcube.smartgears.extensions.HttpExtension.Method.PUT;
import static org.gcube.smartgears.handlers.application.request.RequestError.incoming_contenttype_unsupported_error;
import static org.gcube.smartgears.handlers.application.request.RequestError.method_unsupported_error;
import static org.gcube.smartgears.handlers.application.request.RequestError.outgoing_contenttype_unsupported_error;
import static org.gcube.smartgears.handlers.application.request.RequestError.resource_notfound_error;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.WebApplicationException;
import org.gcube.smartgears.Constants;
import org.gcube.smartgears.extensions.ApiResource;
import org.gcube.smartgears.extensions.ApiSignature;
import org.gcube.smartgears.extensions.HttpController;
import org.gcube.smartgears.extensions.HttpExtension;
import org.glassfish.jersey.client.ClientResponse;
import org.junit.Test;
import app.Request;
import app.SomeApp;
public class ControllerTest {
String name = "name";
String extension_path = "/ext";
String extension_mapping = "/ext/*";
String resource_path = "/resource";
@Test
public void dispatchesToResource() {
// returns a given type
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
// requires same type
Request request = request().at(resource()).with(accept, "text/plain");
SomeApp app = startAppWith(signature);
app.send(request);
}
@Test
public void toleratesTrainingSlashes() {
// returns a given type
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
// requires same type
Request request = request().at(resource()).with(accept, "text/plain");
SomeApp app = startAppWith(signature);
app.send(request);
}
@Test
public void handlesUnknownResources() {
ApiSignature signature = handles(resource_path);
// points to not existing resource
Request request = request().at(resource() + "/bad");
SomeApp app = startAppWith(signature);
try {
app.send(request);
fail();
} catch (WebApplicationException e) {
assertEquals(resource_notfound_error.code(), e.getResponse().getStatus());
}
}
@Test
public void handlesUnsupportedMethods() {
ApiSignature signature = handles(resource_path).with(method(GET)).with(method(PUT));
Request request = request().at(resource()).using(POST);
SomeApp app = startAppWith(signature);
try {
app.send(request);
fail();
} catch (WebApplicationException e) {
assertEquals(method_unsupported_error.code(), e.getResponse().getStatus());
assertNotNull(e.getResponse().getHeaders().toString(),e.getResponse().getHeaders().get(allow));
}
}
@Test
public void enforcesAcceptHeaders() {
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
Request request = request().at(resource()).with(accept, "text/xml");
SomeApp app = startAppWith(signature);
try {
app.send(request);
fail();
} catch (WebApplicationException e) {
assertEquals(outgoing_contenttype_unsupported_error.code(), e.getResponse().getStatus());
}
}
@Test
public void enforcesAcceptHeadersEvenWhenResourceDeclaresNone() {
ApiSignature signature = handles(resource_path).with(method(GET));
Request request = request().at(resource()).with(accept, "text/xml");
SomeApp app = startAppWith(signature);
try {
app.send(request);
fail();
} catch (WebApplicationException e) {
assertEquals(outgoing_contenttype_unsupported_error.code(), e.getResponse().getStatus());
}
}
@Test
public void enforcesMultiValuedAcceptHeader() {
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
Request request = request().at(resource()).with(accept, "text/xml").with(accept,"text/plain");
SomeApp app = startAppWith(signature);
app.send(request);
}
@Test
public void setsContentTypeIfUnsetAndUnambiguous() {
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
Request request = request().at(resource()).with(accept, "text/plain");
SomeApp app = startAppWith(signature);
ClientResponse response = app.httpSend(request);
assertTrue(response.getHeaders().get(content_type).get(0).contains("text/plain"));
}
@Test
public void doesntSetContentTypeIfUnsetButAmbiguous() {
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain","text/xml"));
Request request = request().at(resource()).with(accept, "text/plain");
SomeApp app = startAppWith(signature);
ClientResponse response = app.httpSend(request);
System.out.println(response.getHeaders());
assertNull(response.getHeaders().get(content_type));
}
@Test
public void enforcesMultiValuedContentTypeHeader() {
ApiSignature signature = handles(resource_path).with(method(POST).accepts("application/xml"));
Request request = request().at(resource()).using(POST).with(content_type, "text/xml").with(content_type,"text/plain");
SomeApp app = startAppWith(signature);
try {
app.send(request);
fail();
} catch (WebApplicationException e) {
assertEquals(incoming_contenttype_unsupported_error.code(), e.getResponse().getStatus());
}
}
@Test
public void acceptsContentTypeHeadersWhenResourceDeclaresNone() {
ApiSignature signature = handles(resource_path).with(method(POST));
Request request = request().at(resource()).using(POST).with(content_type, "text/xml");
SomeApp app = startAppWith(signature);
app.httpSend(request);
}
///////////////////////////////// helpers
private String resource() {
return Constants.root_mapping + extension_path + resource_path;
}
SomeApp startAppWith(ApiSignature signature) {
SomeApp app = new SomeApp();
app.extensions().set(controllerWith(signature));
app.bypassExtensionsDeployment();
app.bypassHandlerDeployment();
app.start();
return app;
}
@SuppressWarnings("serial")
HttpExtension controllerWith(final ApiSignature signature) {
return new HttpController(name, extension_mapping) {
{
addResources(new ApiResource(signature) {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
if (!supports(Method.valueOf(req.getMethod())))
super.doGet(req, resp);
else
resp.getWriter().write(req.getMethod() + " invoked @ " + signature.mapping());
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
if (!supports(Method.valueOf(req.getMethod())))
super.doPost(req, resp);
else
resp.getWriter().write(req.getMethod() + " invoked @ " + signature.mapping());
}
@Override
public void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
if (!supports(Method.valueOf(req.getMethod())))
super.doPut(req, resp);
else
resp.getWriter().write(req.getMethod() + " invoked @ " + signature.mapping());
}
});
}
@Override
public String toString() {
return "SUT controller";
}
};
}
}