package dev.coph.nextusweb.server.router; import dev.coph.nextusweb.server.auth.Principal; import dev.coph.nextusweb.server.router.exception.BadRequestException; import io.netty.buffer.Unpooled; import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpVersion; import io.netty.util.CharsetUtil; import org.junit.jupiter.api.Test; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; class RequestTest { private FullHttpRequest build(HttpMethod method, String uri, String body) { var content = body == null ? Unpooled.EMPTY_BUFFER : Unpooled.copiedBuffer(body, CharsetUtil.UTF_8); return new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, method, uri, content); } record Payload(String name, int age) {} @Test void pathParamReturnsFromMap() { Request req = new Request(build(HttpMethod.GET, "/u/1", null), Map.of("id", "1")); assertEquals("1", req.pathParam("id")); assertNull(req.pathParam("missing")); } @Test void queryParamReturnsFirstValue() { Request req = new Request(build(HttpMethod.GET, "/?a=1&a=2&b=foo", null), Map.of()); assertEquals("1", req.queryParam("a")); assertEquals("foo", req.queryParam("b")); assertNull(req.queryParam("nope")); } @Test void queryParamsReturnsAllValues() { Request req = new Request(build(HttpMethod.GET, "/?a=1&a=2", null), Map.of()); assertEquals(java.util.List.of("1", "2"), req.queryParams("a")); assertTrue(req.queryParams("missing").isEmpty()); } @Test void headerReturnsValue() { FullHttpRequest raw = build(HttpMethod.GET, "/", null); raw.headers().set("X-Foo", "bar"); Request req = new Request(raw, Map.of()); assertEquals("bar", req.header("X-Foo")); } @Test void bodyReturnsContentAsString() { Request req = new Request(build(HttpMethod.POST, "/", "hello"), Map.of()); assertEquals("hello", req.body()); } @Test void methodAndPathExpose() { Request req = new Request(build(HttpMethod.POST, "/a/b?q=1", null), Map.of()); assertEquals(HttpMethod.POST, req.method()); assertEquals("/a/b", req.path()); } @Test void jsonReturnsNullNodeForEmptyBody() { Request req = new Request(build(HttpMethod.POST, "/", null), Map.of()); var node = req.json(); assertNotNull(node); assertTrue(node.isNull()); } @Test void jsonParsesObject() { Request req = new Request(build(HttpMethod.POST, "/", "{\"a\":1}"), Map.of()); var node = req.json(); assertTrue(node.has("a")); } @Test void jsonThrowsBadRequestOnInvalidJson() { Request req = new Request(build(HttpMethod.POST, "/", "not-json"), Map.of()); assertThrows(BadRequestException.class, req::json); } @Test void jsonAsDeserializes() { Request req = new Request(build(HttpMethod.POST, "/", "{\"name\":\"x\",\"age\":42}"), Map.of()); Payload p = req.jsonAs(Payload.class); assertEquals("x", p.name()); assertEquals(42, p.age()); } @Test void jsonAsThrowsBadRequestOnInvalid() { Request req = new Request(build(HttpMethod.POST, "/", "not-json"), Map.of()); assertThrows(BadRequestException.class, () -> req.jsonAs(Payload.class)); } @Test void cookieParsesNamedCookie() { FullHttpRequest raw = build(HttpMethod.GET, "/", null); raw.headers().set("Cookie", "sid=abc123; theme=dark"); Request req = new Request(raw, Map.of()); assertEquals("abc123", req.cookie("sid")); assertEquals("dark", req.cookie("theme")); assertNull(req.cookie("missing")); } @Test void cookieReturnsNullWhenNoCookieHeader() { Request req = new Request(build(HttpMethod.GET, "/", null), Map.of()); assertNull(req.cookie("sid")); } @Test void attributesSetGetAndRemove() { Request req = new Request(build(HttpMethod.GET, "/", null), Map.of()); assertNull(req.attribute("k")); req.attribute("k", "v"); assertEquals("v", req.attribute("k")); req.attribute("k", null); assertNull(req.attribute("k")); } @Test void clientIpRoundTrips() { Request req = new Request(build(HttpMethod.GET, "/", null), Map.of()); assertNull(req.clientIp()); req.clientIp("203.0.113.9"); assertEquals("203.0.113.9", req.clientIp()); } @Test void principalRoundTripsAndDrivesIsAuthenticated() { Request req = new Request(build(HttpMethod.GET, "/", null), Map.of()); assertFalse(req.isAuthenticated()); assertNull(req.principal()); req.principal(Principal.of("user-7")); assertTrue(req.isAuthenticated()); assertEquals("user-7", req.principal().id()); } }