package org.jooby.test; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.isA; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicInteger; import org.jooby.Err; import org.jooby.Jooby; import org.jooby.Mutant; import org.jooby.Request; import org.jooby.Response; import org.jooby.Result; import org.jooby.Results; import org.jooby.Status; import org.jooby.View; import org.jooby.test.MockRouter; import org.junit.Test; import com.google.inject.Injector; public class MockRouterTest { public static class HelloService { public String hello() { return "Hi"; } } public static class MyForm { public String hello() { return "Hi"; } } public static class HelloWorld extends Jooby { { before("/before", (req, rsp) -> { req.charset(); }); after("/before", (req, rsp, result) -> { req.charset(); return result; }); after("/afterResult", (req, rsp, result) -> { return Results.with(result.get() + ":unit"); }); get("/afterResult", () -> { return Results.with("hello"); }); get("/injector", () -> { return require(Injector.class).getParent(); }); get("/async", promise(deferred -> { deferred.resolve("async"); })); get("/deferred", deferred(() -> { return "deferred"; })); get("/deferred-err", deferred(() -> { throw new IllegalStateException("intentional err"); })); get("/deferred-executor", deferred("executor", () -> { return "deferred"; })); get("/before", req -> req.charset()); post("/form", req -> req.form(MyForm.class).hello()); put("/form", req -> req.form(MyForm.class).hello()); patch("/form", req -> req.form(MyForm.class).hello()); delete("/item/:id", req -> req.param("id").intValue()); get("/result", req -> Results.html("index")); get("/hello", () -> "Hello world!"); get("/request", req -> req.path()); get("/rsp.send", (req, rsp) -> { rsp.send("Response"); }); get("/rsp.send.result", (req, rsp) -> { rsp.send(Results.with("Response")); }); AtomicInteger inc = new AtomicInteger(0); get("/chain", (req, rsp) -> inc.incrementAndGet()); get("/chain", (req, rsp) -> inc.incrementAndGet()); get("/chain", () -> inc.incrementAndGet()); get("/require", () -> { return require(HelloService.class).hello(); }); get("/requirenamed", () -> { return require("foo", HelloService.class).hello(); }); get("/params", req -> { return req.param("foo").value("bar"); }); get("/rsp.committed", (req, rsp) -> { rsp.send("committed"); }); get("/rsp.committed", (req, rsp) -> { rsp.send("ignored"); }); get("/before", req -> req.charset()); use("/api/items") .get(() -> "All") .get("/:id", () -> "One"); } } @Test public void basicCall() throws Exception { new MockUnit() .run(unit -> { String result = new MockRouter(new HelloWorld()) .get("/hello"); assertEquals("Hello world!", result); }); } @Test(expected = UnsupportedOperationException.class) public void fakedInjector() throws Exception { new MockUnit(Request.class, Response.class) .run(unit -> { new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/injector"); }); } @Test public void post() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Request req = unit.get(Request.class); expect(req.form(MyForm.class)).andReturn(new MyForm()); }) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .post("/form"); assertEquals("Hi", result); }); } @Test public void put() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Request req = unit.get(Request.class); expect(req.form(MyForm.class)).andReturn(new MyForm()); }) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .put("/form"); assertEquals("Hi", result); }); } @Test public void patch() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Request req = unit.get(Request.class); expect(req.form(MyForm.class)).andReturn(new MyForm()); }) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .patch("/form"); assertEquals("Hi", result); }); } @Test public void delete() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Mutant id = unit.mock(Mutant.class); expect(id.intValue()).andReturn(123); Request req = unit.get(Request.class); expect(req.param("id")).andReturn(id); }) .run(unit -> { Integer result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .delete("/item/123"); assertEquals(123, result.intValue()); }); } @Test(expected = UnsupportedOperationException.class) public void requestAccessEmptyRequest() throws Exception { new MockUnit() .run(unit -> { new MockRouter(new HelloWorld()) .get("/request"); }); } @Test public void requestAccess() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Request req = unit.get(Request.class); expect(req.path()).andReturn("/mock-path"); }) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/request"); assertEquals("/mock-path", result); }); } @Test public void routeChain() throws Exception { new MockUnit(Request.class) .run(unit -> { Integer result = new MockRouter(new HelloWorld(), unit.get(Request.class)) .get("/chain"); assertEquals(3, result.intValue()); }); } @Test public void responseSend() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Response rsp = unit.get(Response.class); rsp.send("Response"); }) .run(unit -> { Object result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/rsp.send"); assertEquals("Response", result); }); } @Test public void responseSendResult() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Response rsp = unit.get(Response.class); rsp.send(isA(Result.class)); }) .run(unit -> { Result result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/rsp.send.result"); assertEquals("Response", result.get()); }); } @Test public void requireService() throws Exception { new MockUnit(Request.class, Response.class, HelloService.class) .expect(unit -> { HelloService rsp = unit.get(HelloService.class); expect(rsp.hello()).andReturn("Hola"); }) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .set(unit.get(HelloService.class)) .get("/require"); assertEquals("Hola", result); }); } @Test(expected = IllegalStateException.class) public void serviceNotFound() throws Exception { new MockUnit(Request.class, Response.class, HelloService.class) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/require"); assertEquals("Hola", result); }); } @Test public void requireNamedService() throws Exception { new MockUnit(Request.class, Response.class, HelloService.class) .expect(unit -> { HelloService rsp = unit.get(HelloService.class); expect(rsp.hello()).andReturn("Named"); }) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .set("foo", unit.get(HelloService.class)) .get("/requirenamed"); assertEquals("Named", result); }); } @Test(expected = IllegalStateException.class) public void requireNamedServiceNotFound() throws Exception { new MockUnit(Request.class, Response.class, HelloService.class) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/requirenamed"); assertEquals("Named", result); }); } @Test public void requestMockParam() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Mutant foo = unit.mock(Mutant.class); expect(foo.value("bar")).andReturn("mock"); Request req = unit.get(Request.class); expect(req.param("foo")).andReturn(foo); }) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/params"); assertEquals("mock", result); }); } @Test public void beforeAfterRequest() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Request req = unit.get(Request.class); expect(req.charset()).andReturn(StandardCharsets.US_ASCII).times(3); }) .run(unit -> { Charset result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/before"); assertEquals(StandardCharsets.US_ASCII, result); }); } @Test public void afterResult() throws Exception { new MockUnit(Request.class, Response.class) .run(unit -> { Result result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/afterResult"); assertEquals("hello:unit", result.get()); }); } @Test public void resultResponse() throws Exception { new MockUnit(Request.class, Response.class) .run(unit -> { View result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/result"); assertEquals("index", result.name()); }); } @Test public void responseCommitted() throws Exception { new MockUnit(Request.class, Response.class) .expect(unit -> { Response rsp = unit.get(Response.class); rsp.send("committed"); }) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/rsp.committed"); assertEquals("committed", result); }); } @Test public void async() throws Exception { new MockUnit(Request.class, Response.class) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/async"); assertEquals("async", result); }); } @Test public void deferred() throws Exception { new MockUnit(Request.class, Response.class) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/deferred"); assertEquals("deferred", result); }); new MockUnit(Request.class, Response.class) .run(unit -> { String result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/deferred-executor"); assertEquals("deferred", result); }); } @Test(expected = IllegalStateException.class) public void deferredReject() throws Exception { new MockUnit(Request.class, Response.class) .run(unit -> { new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/deferred-err"); }); } @Test public void routeGroup() throws Exception { new MockUnit(Request.class, Response.class) .run(unit -> { Object result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/api/items"); assertEquals("All", result); }); new MockUnit(Request.class, Response.class) .run(unit -> { Object result = new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/api/items/1"); assertEquals("One", result); }); } @Test public void notFound() throws Exception { new MockUnit(Request.class, Response.class) .run(unit -> { try { new MockRouter(new HelloWorld(), unit.get(Request.class), unit.get(Response.class)) .get("/notFound"); fail(); } catch (Err x) { assertEquals(Status.NOT_FOUND.value(), x.statusCode()); } }); } }