Files
cfw-autumn/server/tests/unit/auth/auth-error-middleware.test.ts

115 lines
2.8 KiB
TypeScript

import { ErrCode, RecaseError } from "@autumn/shared";
import { expect, test } from "bun:test";
import { APIError } from "better-auth";
import { Hono } from "hono";
import { errorMiddleware } from "@/honoMiddlewares/errorMiddleware.js";
import type { HonoEnv } from "@/honoUtils/HonoEnv.js";
test("error middleware returns RecaseError status before request context exists", async () => {
const app = new Hono<HonoEnv>();
app.get("/api/auth/organization/list", () => {
throw new RecaseError({
message: "Unauthorized - no session found",
code: ErrCode.NoAuthHeader,
statusCode: 401,
});
});
app.onError(errorMiddleware);
const response = await app.fetch(
new Request("https://autumn-api.bowong.cc/api/auth/organization/list"),
);
expect(response.status).toBe(401);
await expect(response.json()).resolves.toMatchObject({
message: "Unauthorized - no session found",
code: ErrCode.NoAuthHeader,
});
});
test("error middleware maps Stripe-shaped errors to a 400", async () => {
const app = new Hono<HonoEnv>();
const consoleErrors: unknown[][] = [];
const originalConsoleError = console.error;
console.error = (...args: unknown[]) => {
consoleErrors.push(args);
};
app.use("*", async (c, next) => {
c.set("ctx", {
env: "sandbox",
logger: {
error: () => {},
warn: () => {},
},
} as never);
await next();
});
app.post("/v1/rewards", () => {
const error = new Error("No such product: prod_missing") as Error & {
type: string;
statusCode: number;
code: string;
};
error.type = "StripeInvalidRequestError";
error.statusCode = 400;
error.code = "resource_missing";
throw error;
});
app.onError(errorMiddleware);
try {
const response = await app.fetch(
new Request("https://autumn-api.bowong.cc/v1/rewards", {
method: "POST",
}),
);
expect(response.status).toBe(400);
await expect(response.json()).resolves.toMatchObject({
message: "(Stripe Error) No such product: prod_missing",
code: ErrCode.StripeError,
env: "sandbox",
});
expect(consoleErrors).toEqual([]);
} finally {
console.error = originalConsoleError;
}
});
test("error middleware preserves Better Auth unauthorized errors", async () => {
const app = new Hono<HonoEnv>();
app.use("*", async (c, next) => {
c.set("ctx", {
env: "sandbox",
logger: {
error: () => {},
warn: () => {},
},
} as never);
await next();
});
app.get("/query/event_names/list", () => {
throw APIError.from("UNAUTHORIZED", {
message: "Unauthorized",
code: "UNAUTHORIZED",
});
});
app.onError(errorMiddleware);
const response = await app.fetch(
new Request("https://autumn-api.bowong.cc/query/event_names/list"),
);
expect(response.status).toBe(401);
await expect(response.json()).resolves.toMatchObject({
message: "Unauthorized",
code: ErrCode.NoAuthHeader,
env: "sandbox",
});
});