import { describe, it, expect, vi } from "vitest"; // Mock Prisma so the pure helpers can be tested without a database. vi.mock("@/lib/db", () => ({ db: {} })); import { reviewClientEmail, ownsComment } from "./review-auth"; import type { ReviewSession } from "@prisma/client"; const session = (email: string | null): ReviewSession => ({ email, label: null } as ReviewSession); describe("reviewClientEmail", () => { it("uses the session's own email when it has one", () => { expect(reviewClientEmail(session("dailies@client.com"), "tok123456789")).toBe( "dailies@client.com" ); }); it("falls back to a token-derived address when it has none", () => { expect(reviewClientEmail(session(null), "tok123456789")).toBe( "client+tok12345@review.external" ); }); // Identity has to be stable across requests, or a reviewer would stop owning // the notes they wrote a minute ago. it("is stable for the same token", () => { const a = reviewClientEmail(session(null), "tok123456789"); const b = reviewClientEmail(session(null), "tok123456789"); expect(a).toBe(b); }); it("separates two different review links", () => { expect(reviewClientEmail(session(null), "aaaaaaaaaaaa")).not.toBe( reviewClientEmail(session(null), "bbbbbbbbbbbb") ); }); }); describe("ownsComment", () => { it("lets a reviewer edit their own note", () => { expect(ownsComment({ authorId: "u1" }, "u1")).toBe(true); }); it("refuses another author's note", () => { expect(ownsComment({ authorId: "u2" }, "u1")).toBe(false); }); // The studio's notes reach the portal in the same list; they must stay // read-only there. it("refuses a note written by an internal user", () => { expect(ownsComment({ authorId: "supervisor-id" }, "client-id")).toBe(false); }); it("refuses when the reviewer has never posted, so has no identity yet", () => { expect(ownsComment({ authorId: "u1" }, undefined)).toBe(false); expect(ownsComment({ authorId: "u1" }, null)).toBe(false); }); // An authorless comment (its User row was deleted — Comment.authorId is // SetNull) belongs to nobody and must not become claimable. it("refuses an authorless note rather than letting it be claimed", () => { expect(ownsComment({ authorId: null }, "u1")).toBe(false); expect(ownsComment({ authorId: null }, null)).toBe(false); }); });