import { describe, expect, it } from "vitest"; import type { Permissions } from "@/lib/auth/session"; import { resolveAuthorTagIds, statusChangeError } from "@/lib/permissions"; const perms = (overrides: Partial = {}): Permissions => ({ createTags: false, publishPosts: false, unpublishPosts: false, deletePosts: false, approveComments: false, ...overrides, }); describe("statusChangeError", () => { it("requires the publish permission to go draft -> published", () => { expect(statusChangeError(perms(), null, "published")).toMatch(/publish/); expect(statusChangeError(perms(), "draft", "published")).toMatch(/publish/); expect(statusChangeError(perms({ publishPosts: true }), "draft", "published")).toBeNull(); }); it("requires the unpublish permission to go published -> draft", () => { expect(statusChangeError(perms(), "published", "draft")).toMatch(/unpublish/); expect( statusChangeError(perms({ unpublishPosts: true }), "published", "draft"), ).toBeNull(); }); it("never blocks saves that keep the status", () => { expect(statusChangeError(perms(), "draft", "draft")).toBeNull(); expect(statusChangeError(perms(), "published", "published")).toBeNull(); expect(statusChangeError(perms(), null, "draft")).toBeNull(); }); }); describe("resolveAuthorTagIds", () => { const allowed = new Set([1, 2]); it("rejects submissions outside the grants", () => { const result = resolveAuthorTagIds({ submitted: [1, 3], existing: [], allowed, creatingTags: false, }); expect(result).toHaveProperty("error"); }); it("requires at least one granted tag unless creating one", () => { expect( resolveAuthorTagIds({ submitted: [], existing: [], allowed, creatingTags: false }), ).toHaveProperty("error"); expect( resolveAuthorTagIds({ submitted: [], existing: [], allowed, creatingTags: true }), ).toEqual({ tagIds: [] }); }); it("preserves admin-added tags the author cannot see", () => { // Post carries granted tag 1 and admin-added tag 9; the author's form // resubmits only tag 2. Tag 9 must survive. const result = resolveAuthorTagIds({ submitted: [2], existing: [1, 9], allowed, creatingTags: false, }); expect(result).toEqual({ tagIds: [2, 9] }); }); it("lets the author drop their own granted tags", () => { const result = resolveAuthorTagIds({ submitted: [2], existing: [1, 2], allowed, creatingTags: false, }); expect(result).toEqual({ tagIds: [2] }); }); });