package com.vtence.molecule; import com.vtence.molecule.middlewares.AbstractMiddleware; import org.junit.Test; import static com.vtence.molecule.testing.ResponseAssert.assertThat; import static org.hamcrest.CoreMatchers.is; public class MiddlewareStackTest { MiddlewareStack stack = new MiddlewareStack(); Request request = new Request(); Response response = new Response(); @Test public void assemblesChainInOrderOfAddition() throws Exception { stack.use(middleware("top")); stack.use(middleware("middle")); stack.use(middleware("bottom")); stack.run(application("runner")); stack.handle(request, response); assertChain(is("top -> middle -> bottom -> runner")); } @Test public void supportMountPointsInsteadOfRunners() throws Exception { stack.mount("/api", application("api")); stack.handle(request.path("/api"), response); assertChain(is("api")); } @Test public void usesRunnerAsDefaultMountPoint() throws Exception { stack.mount("/api", application("api")); stack.run(application("main")); stack.handle(request.path("/"), response); assertChain(is("main")); } @Test public void mixesMountPointsAndMiddlewaresAccordingly() throws Exception { stack.use(middleware("top")); stack.mount("/api", application("api")); stack.use(middleware("bottom")); stack.mount("/admin", application("admin")); stack.run(application("main")); stack.handle(request.path("/"), response); assertChain(is("top -> bottom -> main")); } @Test public void takesIntoAccountOrderOfMiddlewareAndMountDefinitions() throws Exception { stack.use(middleware("top")); stack.mount("/api", application("api")); stack.use(middleware("bottom")); stack.mount("/admin", application("admin")); stack.handle(request.path("/api"), response); assertChain(is("top -> api")); } @Test public void acceptsAnWarmUpSequence() throws Exception { stack.use(middleware("ready")); stack.use(middleware("set")); stack.warmup(app -> { try { app.handle(request, response); } catch (Exception e) { throw new AssertionError(e); } }); stack.run(application("go!")); stack.boot(); assertChain(is("ready -> set -> go!")); } @Test(expected = IllegalStateException.class) public void eitherMountOrRunnerIsRequired() throws Exception { stack.use(middleware("middleware")); stack.handle(request, response); } private Middleware middleware(final String order) { return new AbstractMiddleware() { public void handle(Request request, Response response) throws Exception { forward(request, response); response.header("chain", order + " -> " + response.header("chain")); } }; } private Application application(final String app) { return (request, response) -> response.header("chain", app); } private void assertChain(org.hamcrest.Matcher<? super String> chaining) { assertThat(response).hasHeader("chain", chaining); } }