import { describe, it, expect } from "bun:test";
import app from "../app";
const NON_400_OK = [200, 301, 302, 303, 307, 401, 403, 404, 503];
describe("GET /live-events/:topic — topic grammar", () => {
it("rejects an empty path beyond the prefix", async () => {
const res = await app.request("/live-events/", { redirect: "manual" });
expect([400, 404]).toContain(res.status);
});
it("rejects a kind-only topic (no id)", async () => {
const res = await app.request("/live-events/repo");
expect([400, 404]).toContain(res.status);
});
it("rejects topics with disallowed characters", async () => {
const res = await app.request(
"/live-events/" + encodeURIComponent("repo:has spaces")
);
expect(res.status).toBe(400);
});
it("rejects topics with embedded slash", async () => {
const res = await app.request(
"/live-events/" + encodeURIComponent("repo:foo/bar")
);
expect(res.status).toBe(400);
});
it("accepts the canonical single-segment form (repo:<uuid>)", async () => {
const uuid = "00000000-0000-0000-0000-000000000000";
const res = await app.request(`/live-events/repo:${uuid}`, {
redirect: "manual",
});
expect(res.status).not.toBe(400);
expect(NON_400_OK).toContain(res.status);
});
it("accepts a multi-segment topic (repo:<uuid>:issue:7)", async () => {
const uuid = "00000000-0000-0000-0000-000000000000";
const res = await app.request(
`/live-events/repo:${uuid}:issue:7`,
{ redirect: "manual" }
);
expect(res.status).not.toBe(400);
expect(NON_400_OK).toContain(res.status);
});
it("accepts a multi-segment PR topic (repo:<uuid>:pr:9)", async () => {
const uuid = "00000000-0000-0000-0000-000000000000";
const res = await app.request(
`/live-events/repo:${uuid}:pr:9`,
{ redirect: "manual" }
);
expect(res.status).not.toBe(400);
expect(NON_400_OK).toContain(res.status);
});
it("accepts a non-repo kind (passes the read-gate)", async () => {
const res = await app.request(`/live-events/user:42`, {
redirect: "manual",
});
expect(res.status).not.toBe(400);
});
});
|