import { describe, expect, it } from "vitest"; import { DEFAULT_DEV_EMAIL, DEV_IDENTITY_COOKIE, DEV_IDENTITY_HEADER, getServerIdentity, } from "./dev-identity"; import type { NextRequest } from "next/server"; /** * Minimal NextRequest stub — only the bits getServerIdentity reads. * Avoids pulling in Next's actual class for unit tests. */ function makeReq(opts: { header?: string; cookie?: string; envEmail?: string; }): NextRequest { const headers = new Headers(); if (opts.header) headers.set(DEV_IDENTITY_HEADER, opts.header); // Build a minimal cookie jar NextRequest understands. const cookieValue = opts.cookie ? `${DEV_IDENTITY_COOKIE}=${opts.cookie}` : ""; const req = { headers, cookies: { get(name: string) { if (name !== DEV_IDENTITY_COOKIE) return undefined; if (!cookieValue) return undefined; // mimic NextRequest's behavior: returns the raw value const eq = cookieValue.indexOf("="); return { name, value: cookieValue.slice(eq + 1) }; }, }, } as unknown as NextRequest; if (opts.envEmail !== undefined) { process.env.DEV_USER_EMAIL = opts.envEmail; } else { delete process.env.DEV_USER_EMAIL; } return req; } describe("getServerIdentity", () => { it("returns the X-User-Email header when present", () => { const req = makeReq({ header: "alice@example.com" }); expect(getServerIdentity(req)).toBe("alice@example.com"); }); it("falls back to the cookie when the header is missing", () => { const req = makeReq({ cookie: encodeURIComponent("bob@example.com"), }); expect(getServerIdentity(req)).toBe("bob@example.com"); }); it("falls back to DEV_USER_EMAIL when header and cookie are missing", () => { const req = makeReq({ envEmail: "ci@example.com" }); expect(getServerIdentity(req)).toBe("ci@example.com"); }); it("falls back to the default when nothing is set", () => { const req = makeReq({}); expect(getServerIdentity(req)).toBe(DEFAULT_DEV_EMAIL); }); it("prefers the header over the cookie", () => { const req = makeReq({ header: "header@example.com", cookie: encodeURIComponent("cookie@example.com"), }); expect(getServerIdentity(req)).toBe("header@example.com"); }); it("prefers the cookie over the env default", () => { const req = makeReq({ cookie: encodeURIComponent("cookie@example.com"), envEmail: "env@example.com", }); expect(getServerIdentity(req)).toBe("cookie@example.com"); }); it("trims whitespace from all sources", () => { const req = makeReq({ header: " spaced@example.com " }); expect(getServerIdentity(req)).toBe("spaced@example.com"); }); it("ignores empty values and falls through to the next source", () => { const req = makeReq({ header: " ", cookie: encodeURIComponent(" "), envEmail: "env@example.com", }); expect(getServerIdentity(req)).toBe("env@example.com"); }); });