69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
import { NextRequest } from "next/server";
|
|
import { afterEach, expect, it, vi } from "vitest";
|
|
import { GET } from "../app/api/imaging/avatar/route";
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllEnvs();
|
|
vi.unstubAllGlobals();
|
|
});
|
|
it("forwards multicolor figures and preserves configured query options at runtime", async () => {
|
|
const figure = "hr-11782-40-40.hd-180-7-14.ch-11592-66.lg-10726-79-1408";
|
|
const fetcher = vi.fn(
|
|
async (_input: string | URL) =>
|
|
new Response(new Uint8Array([1, 2, 3]), {
|
|
headers: { "content-type": "image/png" },
|
|
}),
|
|
);
|
|
vi.stubGlobal("fetch", fetcher);
|
|
for (const hotel of ["alpha", "beta"]) {
|
|
vi.stubEnv("IMAGER_URL", `https://${hotel}.test/avatar?renderer=custom`);
|
|
const result = await GET(
|
|
new NextRequest(
|
|
`https://hotel.test/api/imaging/avatar?figure=${figure}&headonly=1&effect=0`,
|
|
),
|
|
);
|
|
expect(result.status).toBe(200);
|
|
const target = new URL(String(fetcher.mock.calls.at(-1)?.[0]));
|
|
expect(target.origin).toBe(`https://${hotel}.test`);
|
|
expect(target.searchParams.get("figure")).toBe(figure);
|
|
expect(target.searchParams.get("renderer")).toBe("custom");
|
|
expect(target.searchParams.get("headonly")).toBe("1");
|
|
}
|
|
});
|
|
it("rejects malformed figure input without contacting a renderer", async () => {
|
|
const fetcher = vi.fn();
|
|
vi.stubGlobal("fetch", fetcher);
|
|
expect(
|
|
(
|
|
await GET(
|
|
new NextRequest("https://hotel.test/api/imaging/avatar?figure=../bad"),
|
|
)
|
|
).status,
|
|
).toBe(400);
|
|
expect(fetcher).not.toHaveBeenCalled();
|
|
});
|
|
it("falls back to the public Habbo renderer when the configured imager is down", async () => {
|
|
const fetcher = vi.fn(async (input: string | URL) => {
|
|
const url = new URL(String(input));
|
|
if (url.origin === "https://hotel.test")
|
|
return new Response("unavailable", { status: 503 });
|
|
return new Response(new Uint8Array([4, 5, 6]), {
|
|
headers: { "content-type": "image/png" },
|
|
});
|
|
});
|
|
vi.stubGlobal("fetch", fetcher);
|
|
vi.stubEnv("IMAGER_URL", "https://hotel.test/avatarimage");
|
|
const result = await GET(
|
|
new NextRequest(
|
|
"https://hotel.test/api/imaging/avatar?figure=hd-180-1&img_format=apng&effect=0",
|
|
),
|
|
);
|
|
expect(result.status).toBe(200);
|
|
expect(result.headers.get("x-imager-source")).toBe("fallback");
|
|
expect(result.headers.get("cache-control")).toContain("max-age=300");
|
|
const target = new URL(String(fetcher.mock.calls.at(-1)?.[0]));
|
|
expect(target.host).toBe("www.habbo.com");
|
|
expect(target.searchParams.get("img_format")).toBe("png");
|
|
expect(target.searchParams.has("effect")).toBe(false);
|
|
});
|