import { describe, it, expect } from "vitest"; import type { CollectionConfig } from "payload"; import { RETENTION_TOMBSTONE_FIELD, hasPostDeletionPolicy, withRetentionTombstone, } from "@/payload/retention-purge/tombstone"; function makeCollection(custom?: Record): CollectionConfig { return { slug: "things", custom, fields: [{ name: "title", type: "text" }], } as CollectionConfig; } const postDeletionRetention = { retention: { purgeSchedule: "daily", postDeletion: { duration: "P30D", trigger: "after-deletion", action: "hard-delete", }, }, }; describe("hasPostDeletionPolicy", () => { it("is true when custom.retention.postDeletion is declared", () => { expect(hasPostDeletionPolicy(makeCollection(postDeletionRetention))).toBe( true, ); }); it("is false without retention or postDeletion", () => { expect(hasPostDeletionPolicy(makeCollection())).toBe(false); expect( hasPostDeletionPolicy( makeCollection({ retention: { purgeSchedule: "daily" } }), ), ).toBe(false); }); }); describe("withRetentionTombstone", () => { it("appends the deletedAt field to postDeletion collections", () => { const result = withRetentionTombstone( makeCollection(postDeletionRetention), ); const names = result.fields.map((f) => (f as { name?: string }).name); expect(names).toContain(RETENTION_TOMBSTONE_FIELD); const tombstone = result.fields.find( (f) => (f as { name?: string }).name === RETENTION_TOMBSTONE_FIELD, ) as { type?: string; index?: boolean }; expect(tombstone.type).toBe("date"); expect(tombstone.index).toBe(true); }); it("returns collections without a postDeletion policy unchanged", () => { const collection = makeCollection(); expect(withRetentionTombstone(collection)).toBe(collection); }); it("does not duplicate an already-declared tombstone field", () => { const collection = { ...makeCollection(postDeletionRetention), fields: [{ name: RETENTION_TOMBSTONE_FIELD, type: "date" }], } as CollectionConfig; const result = withRetentionTombstone(collection); expect( result.fields.filter( (f) => (f as { name?: string }).name === RETENTION_TOMBSTONE_FIELD, ), ).toHaveLength(1); }); it("does not mutate the input collection", () => { const collection = makeCollection(postDeletionRetention); const before = collection.fields.length; withRetentionTombstone(collection); expect(collection.fields.length).toBe(before); }); });