t3-code-android-nightly/.repos/effect-smol/packages/effect/test/http/HttpRouter.test.ts
Julius Marminge 6f9cea00ae
chore(refs): sync Effect and Alchemy references to 4.0.1 and beta.80 (#16170)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 13:22:30 -07:00

89 lines
3 KiB
TypeScript

import { assert, describe, it } from "@effect/vitest"
import { Effect, Layer, Option } from "effect"
import { HttpRouter, type HttpServerRequest, HttpServerResponse } from "effect/http"
const echoUrl = (request: HttpServerRequest.HttpServerRequest) => Effect.succeed(HttpServerResponse.text(request.url))
const layerPrefixed = (prefix: string) =>
Layer.effect(
HttpRouter.HttpRouter,
Effect.map(HttpRouter.HttpRouter, (router) => router.prefixed(prefix))
)
const fetchText = (app: Layer.Layer<never, never, HttpRouter.HttpRouter>, path: string) =>
Effect.acquireUseRelease(
Effect.sync(() => HttpRouter.toWebHandler(app, { disableLogger: true })),
({ handler }) =>
Effect.promise(async () => {
const response = await handler(new Request(`http://localhost${path}`))
return await response.text()
}),
({ dispose }) => Effect.promise(dispose)
)
describe("HttpRouter", () => {
it("normalizes the prefix stored by prefixRoute", () => {
const route = HttpRouter.prefixRoute(
HttpRouter.route("GET", "/users", HttpServerResponse.text("ok")),
"/api/"
)
assert.deepStrictEqual(route.prefix, Option.some("/api"))
})
it("handles prefixed routes with toWebHandler", async () => {
const { dispose, handler } = HttpRouter.toWebHandler(
Effect.gen(function*() {
const router = yield* HttpRouter.HttpRouter
yield* router.prefixed("/api").add("GET", "/hello", HttpServerResponse.text("hi"))
}).pipe(Layer.effectDiscard)
)
try {
const response = await handler(new Request("http://localhost/api/hello"))
assert.strictEqual(response.status, 200)
assert.strictEqual(await response.text(), "hi")
} finally {
await dispose()
}
})
for (
const { prefix, requestUrl } of [
{ prefix: "/", requestUrl: "/users" },
{ prefix: "/api/", requestUrl: "/api/users" }
]
) {
it.effect(`preserves the local URL for the ${prefix} prefix`, () =>
Effect.gen(function*() {
const routes = HttpRouter.use((router) => router.prefixed(prefix).add("GET", "/users", echoUrl))
const body = yield* fetchText(routes, requestUrl)
assert.strictEqual(body, "/users")
}))
}
it.effect("nests a prefixed sub-router beneath a prefixed parent router", () =>
Effect.gen(function*() {
const routes = HttpRouter.use((router) => router.prefixed("/app").add("GET", "/users", echoUrl)).pipe(
Layer.provide(layerPrefixed("/api"))
)
const body = yield* fetchText(routes, "/api/app/users")
assert.strictEqual(body, "/users")
}))
it.effect("nests a prefixRoute prefix beneath a prefixed parent router", () =>
Effect.gen(function*() {
const users = HttpRouter.prefixRoute(HttpRouter.route("GET", "/users", echoUrl), "/app")
const routes = HttpRouter.use((router) => router.addAll([users])).pipe(
Layer.provide(layerPrefixed("/api"))
)
const body = yield* fetchText(routes, "/api/app/users")
assert.strictEqual(body, "/users")
}))
})