164 lines
6.3 KiB
Java
164 lines
6.3 KiB
Java
package dev.coph.nextusweb.server.router;
|
|
|
|
import io.netty.handler.codec.http.HttpMethod;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
class RouterTest {
|
|
|
|
private final Router.Handler noop = (req, res) -> {};
|
|
|
|
@Test
|
|
void getRegistersAndResolvesExactPath() {
|
|
Router r = new Router().get("/hello", noop);
|
|
assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.GET, "/hello"));
|
|
}
|
|
|
|
@Test
|
|
void postPutDeleteRegister() {
|
|
Router r = new Router()
|
|
.post("/p", noop)
|
|
.put("/u", noop)
|
|
.delete("/d", noop);
|
|
assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.POST, "/p"));
|
|
assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.PUT, "/u"));
|
|
assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.DELETE, "/d"));
|
|
}
|
|
|
|
@Test
|
|
void notFoundForUnknownPath() {
|
|
Router r = new Router().get("/a", noop);
|
|
assertInstanceOf(Router.Resolution.NotFound.class, r.resolve(HttpMethod.GET, "/x"));
|
|
}
|
|
|
|
@Test
|
|
void methodNotAllowedWhenPathMatchesDifferentMethod() {
|
|
Router r = new Router().get("/a", noop);
|
|
Router.Resolution res = r.resolve(HttpMethod.POST, "/a");
|
|
Router.Resolution.MethodNotAllowed mna = assertInstanceOf(Router.Resolution.MethodNotAllowed.class, res);
|
|
assertTrue(mna.allowedMethods().contains(HttpMethod.GET));
|
|
}
|
|
|
|
@Test
|
|
void pathParamsAreExtracted() {
|
|
Router r = new Router().get("/u/{id}", noop);
|
|
Router.Resolution res = r.resolve(HttpMethod.GET, "/u/42");
|
|
Router.Resolution.Match m = assertInstanceOf(Router.Resolution.Match.class, res);
|
|
assertEquals("42", m.pathParams().get("id"));
|
|
}
|
|
|
|
@Test
|
|
void wildcardMatches() {
|
|
Router r = new Router().get("/files/*", noop);
|
|
assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.GET, "/files/anything"));
|
|
}
|
|
|
|
@Test
|
|
void useAddsMiddlewareReturned() {
|
|
AtomicInteger count = new AtomicInteger();
|
|
Router r = new Router().use((req, res) -> count.incrementAndGet());
|
|
assertEquals(1, r.middlewares().size());
|
|
r.middlewares().getFirst().accept(null, null);
|
|
assertEquals(1, count.get());
|
|
}
|
|
|
|
@Test
|
|
void registerWorksWithCustomMethod() {
|
|
Router r = new Router().register(HttpMethod.valueOf("OPTIONS"), "/x", noop);
|
|
assertInstanceOf(Router.Resolution.Match.class,
|
|
r.resolve(HttpMethod.valueOf("OPTIONS"), "/x"));
|
|
}
|
|
|
|
@Test
|
|
void handlerInvocationWorks() throws Exception {
|
|
AtomicInteger called = new AtomicInteger();
|
|
Router r = new Router().get("/x", (req, res) -> called.incrementAndGet());
|
|
var match = (Router.Resolution.Match) r.resolve(HttpMethod.GET, "/x");
|
|
match.handler().handle(null, null);
|
|
assertEquals(1, called.get());
|
|
}
|
|
|
|
@Test
|
|
void samePathWithDifferentMethodsResolvesToDistinctHandlers() throws Exception {
|
|
AtomicInteger getCalls = new AtomicInteger();
|
|
AtomicInteger putCalls = new AtomicInteger();
|
|
AtomicInteger deleteCalls = new AtomicInteger();
|
|
|
|
Router r = new Router()
|
|
.get("/user", (req, res) -> getCalls.incrementAndGet())
|
|
.put("/user", (req, res) -> putCalls.incrementAndGet())
|
|
.delete("/user", (req, res) -> deleteCalls.incrementAndGet());
|
|
|
|
var get = assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.GET, "/user"));
|
|
var put = assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.PUT, "/user"));
|
|
var del = assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.DELETE, "/user"));
|
|
|
|
get.handler().handle(null, null);
|
|
put.handler().handle(null, null);
|
|
del.handler().handle(null, null);
|
|
|
|
assertEquals(1, getCalls.get());
|
|
assertEquals(1, putCalls.get());
|
|
assertEquals(1, deleteCalls.get());
|
|
assertNotSame(get.handler(), put.handler());
|
|
assertNotSame(put.handler(), del.handler());
|
|
}
|
|
|
|
@Test
|
|
void samePathUnregisteredMethodReturnsMethodNotAllowedWithAllAllowed() {
|
|
Router r = new Router()
|
|
.get("/user", noop)
|
|
.put("/user", noop)
|
|
.delete("/user", noop);
|
|
|
|
var res = r.resolve(HttpMethod.POST, "/user");
|
|
var mna = assertInstanceOf(Router.Resolution.MethodNotAllowed.class, res);
|
|
assertTrue(mna.allowedMethods().contains(HttpMethod.GET));
|
|
assertTrue(mna.allowedMethods().contains(HttpMethod.PUT));
|
|
assertTrue(mna.allowedMethods().contains(HttpMethod.DELETE));
|
|
assertFalse(mna.allowedMethods().contains(HttpMethod.POST));
|
|
assertEquals(3, mna.allowedMethods().size());
|
|
}
|
|
|
|
@Test
|
|
void registeringSameMethodAndPathTwiceOverwritesHandler() throws Exception {
|
|
AtomicInteger first = new AtomicInteger();
|
|
AtomicInteger second = new AtomicInteger();
|
|
|
|
Router r = new Router()
|
|
.get("/user", (req, res) -> first.incrementAndGet())
|
|
.get("/user", (req, res) -> second.incrementAndGet());
|
|
|
|
var match = (Router.Resolution.Match) r.resolve(HttpMethod.GET, "/user");
|
|
match.handler().handle(null, null);
|
|
|
|
assertEquals(0, first.get());
|
|
assertEquals(1, second.get());
|
|
}
|
|
|
|
@Test
|
|
void samePathWithParamAndMultipleMethodsKeepsParamsAndHandlers() throws Exception {
|
|
AtomicInteger getCalls = new AtomicInteger();
|
|
AtomicInteger putCalls = new AtomicInteger();
|
|
|
|
Router r = new Router()
|
|
.get("/user/{id}", (req, res) -> getCalls.incrementAndGet())
|
|
.put("/user/{id}", (req, res) -> putCalls.incrementAndGet());
|
|
|
|
var get = assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.GET, "/user/42"));
|
|
var put = assertInstanceOf(Router.Resolution.Match.class, r.resolve(HttpMethod.PUT, "/user/42"));
|
|
|
|
assertEquals("42", get.pathParams().get("id"));
|
|
assertEquals("42", put.pathParams().get("id"));
|
|
|
|
get.handler().handle(null, null);
|
|
put.handler().handle(null, null);
|
|
assertEquals(1, getCalls.get());
|
|
assertEquals(1, putCalls.get());
|
|
assertNotSame(get.handler(), put.handler());
|
|
}
|
|
}
|