web: add test for the compact event api

This commit is contained in:
2026-08-31 23:29:50 +02:00
parent 7df0a646bc
commit f9bc0d404c
+138
View File
@@ -0,0 +1,138 @@
import { NextRequest } from "next/server";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const queryMock = vi.fn();
vi.mock("@/app/client", () => ({
getClient: () => ({ query: queryMock }),
}));
import { GET } from "./route.ts";
const request = (path: string) => new NextRequest(`http://localhost${path}`);
const occurrence = (id: string, start: string) => ({
id,
start,
end: null,
venue: {
id: "v1",
slug: "storsalen",
title: "Storsalen",
preposition: "i",
url: "/lokaler/storsalen",
},
});
const data = (futureEvents: unknown[]) => ({
index: { id: "idx" },
events: { futureEvents },
eventCategories: [],
eventOrganizers: [],
venues: [],
});
// "now" is 2026-07-07 12:00 in Oslo
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-07-07T10:00:00Z"));
vi.stubEnv("URL", "https://neuf.no");
});
afterEach(() => {
vi.useRealTimers();
vi.unstubAllEnvs();
vi.clearAllMocks();
});
describe("GET /api/v1/events", () => {
it("rejects a missing or unknown view parameter", async () => {
for (const path of ["/api/v1/events", "/api/v1/events?view=full"]) {
const res = await GET(request(path));
expect(res.status).toBe(400);
expect(await res.json()).toEqual({
error: "must provide valid view parameter",
});
}
expect(queryMock).not.toHaveBeenCalled();
});
it("returns compact events with the earliest future occurrence", async () => {
queryMock.mockResolvedValue({
data: data([
{
id: "a",
slug: "konsert",
title: "Konsert",
subtitle: "Med kor",
occurrences: [
occurrence("a-0", "2026-07-01T18:00:00Z"), // past, dropped
occurrence("a-1", "2026-07-12T18:00:00Z"),
occurrence("a-2", "2026-07-08T18:00:00Z"),
],
},
]),
});
const res = await GET(request("/api/v1/events?view=compact-app"));
expect(res.status).toBe(200);
expect(await res.json()).toEqual({
events: [
{
id: "a",
slug: "konsert",
title: "Konsert",
subtitle: "Med kor",
nextOccurrence: occurrence("a-2", "2026-07-08T18:00:00Z"),
url: "https://neuf.no/arrangementer/konsert",
futureOccurrencesCount: 2,
},
],
total: 1,
});
});
it("keeps events with no future occurrences, with a null nextOccurrence", async () => {
queryMock.mockResolvedValue({
data: data([
{
id: "b",
slug: "fortid",
title: "Fortid",
subtitle: "",
occurrences: [occurrence("b-0", "2026-07-01T18:00:00Z")],
},
]),
});
const res = await GET(request("/api/v1/events?view=compact-app"));
expect(res.status).toBe(200);
expect(await res.json()).toEqual({
events: [
{
id: "b",
slug: "fortid",
title: "Fortid",
subtitle: "",
nextOccurrence: null,
url: "https://neuf.no/arrangementer/fortid",
futureOccurrencesCount: 0,
},
],
total: 1,
});
});
it("throws on a query error or missing data", async () => {
queryMock.mockResolvedValue({ error: { message: "cms nede" } });
await expect(GET(request("/api/v1/events?view=compact-app"))).rejects.toThrow(
"cms nede"
);
queryMock.mockResolvedValue({ data: { index: { id: "idx" } } });
await expect(GET(request("/api/v1/events?view=compact-app"))).rejects.toThrow(
"Failed to fetch events"
);
});
});