hts/packages/hono/src/index.test.ts

182 lines
4.1 KiB
TypeScript

import { Hono } from "hono";
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";
import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
import { z } from "zod";
import { UnkeyContext, unkey } from "./index";
const key = "test_key";
const apiId = "api_test";
const server = setupServer(
// @ts-expect-error
http.post("https://api.unkey.dev/v1/keys.verifyKey", async ({ request }) => {
const req = z
.object({
apiId: z.string(),
key: z.string(),
})
.parse(await request.json());
if (req.apiId !== apiId) {
return HttpResponse.json({
valid: false,
code: "FORBDIDDEN",
});
}
if (req.key !== key) {
return HttpResponse.json({
valid: false,
code: "NOT_FOUND",
});
}
return HttpResponse.json({
valid: true,
environment: "test",
});
}),
);
beforeAll(() => {
server.listen();
});
afterEach(() => {
server.resetHandlers();
});
afterAll(() => {
server.close();
});
describe("No custom Config", () => {
describe("happy path", () => {
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
app.use(
"*",
unkey({
apiId,
}),
);
app.get("/", (c) => c.json(c.get("unkey")));
test("Should be hello message", async () => {
const res = await app.request("http://localhost/", {
headers: {
Authorization: `Bearer ${key}`,
},
});
expect(res.status).toBe(200);
expect(await res.json()).toMatchObject({ valid: true });
});
});
describe("No Authorization header", () => {
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
app.use(
"*",
unkey({
apiId,
}),
);
app.get("/", (c) => c.json(c.get("unkey")));
test("should be unauthorized", async () => {
const res = await app.request("http://localhost/");
expect(res.status).toBe(401);
expect(await res.json()).toMatchObject({
error: "unauthorized",
});
});
});
});
describe("with key environment", () => {
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
app.use(
"/*",
unkey({
apiId,
}),
);
let returnedEnvironment: string | undefined = undefined;
app.get("/", (c) => {
returnedEnvironment = c.get("unkey").environment;
return c.text("hello");
});
test("environment should be returned in context", async () => {
const res = await app.request("http://localhost/", {
headers: {
Authorization: `Bearer ${key}`,
},
});
expect(res.status).toBe(200);
expect(returnedEnvironment).toBe("test");
});
});
describe("With custom key getter", () => {
describe("No Authorization header", () => {
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
app.use(
"/*",
unkey({
apiId,
getKey: (c) => {
return c.text("oh well");
},
}),
);
app.get("/", (c) => c.json(c.get("unkey")));
test("should be called with response", async () => {
const res = await app.request("http://localhost/");
expect(res.status).toBe(200);
expect(await res.text()).toEqual("oh well");
});
});
});
describe("With custom invald handler", () => {
describe("No Authorization header", () => {
const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();
let calledWith: UnkeyContext | null = null;
app.use(
"/*",
unkey({
apiId,
handleInvalidKey: (c, result) => {
calledWith = result;
return c.text("oh well");
},
}),
);
app.get("/", (c) => c.json(c.get("unkey")));
test("should be called with response", async () => {
const res = await app.request("http://localhost/", {
headers: {
Authorization: "Bearer notakey",
},
});
expect(res.status).toBe(200);
expect(await res.text()).toEqual("oh well");
expect(calledWith).toMatchObject({
valid: false,
code: "NOT_FOUND",
});
});
});
});