import type { Kysely } from "kysely"; import { describe, it, expect, beforeEach, afterEach } from "vitest"; import { handleContentCreate } from "../../src/api/index.js"; import { ContentRepository } from "../../src/database/repositories/content.js"; import { RevisionRepository } from "../../src/database/repositories/revision.js"; import type { Database } from "../../src/database/types.js"; import { emdashLoader } from "../../src/loader.js"; import { runWithContext } from "../../src/request-context.js"; import { setupTestDatabaseWithCollections, teardownTestDatabase } from "../utils/test-db.js"; describe("Loader revision preview", () => { let db: Kysely; let revisionRepo: RevisionRepository; beforeEach(async () => { db = await setupTestDatabaseWithCollections(); revisionRepo = new RevisionRepository(db); }); afterEach(async () => { await teardownTestDatabase(db); }); async function createPublishedPost(title: string) { const result = await handleContentCreate(db, "post", { data: { title }, status: "published", }); if (!result.success) throw new Error("Failed to create post"); return result.data!.item; } it("should return Date objects for system date fields in revision preview", async () => { const post = await createPublishedPost("Test Post"); // Publish the post to set published_at const contentRepo = new ContentRepository(db); await contentRepo.publish("post", post.id); // Create a revision (simulating a draft edit) const revision = await revisionRepo.create({ collection: "post", entryId: post.id, data: { title: "Draft Title" }, }); const loader = emdashLoader(); const slug = post.slug!; const result = await runWithContext({ editMode: true, db }, () => loader.loadEntry!({ filter: { type: "post", id: slug, revisionId: revision.id } }), ); expect(result).toBeDefined(); expect(result).not.toHaveProperty("error"); const data = (result as { data: Record }).data; // These must be Date objects, not ISO strings expect(data.createdAt).toBeInstanceOf(Date); expect(data.updatedAt).toBeInstanceOf(Date); expect(data.publishedAt).toBeInstanceOf(Date); }); it("should return null for unpopulated date fields in revision preview", async () => { // Create a draft post (no publishedAt) const createResult = await handleContentCreate(db, "post", { data: { title: "Draft Post" }, status: "draft", }); if (!createResult.success) throw new Error("Failed to create post"); const post = createResult.data!.item; const revision = await revisionRepo.create({ collection: "post", entryId: post.id, data: { title: "Updated Draft" }, }); const loader = emdashLoader(); const slug = post.slug!; const entry = await runWithContext({ editMode: true, db }, () => loader.loadEntry!({ filter: { type: "post", id: slug, revisionId: revision.id } }), ); expect(entry).toBeDefined(); expect(entry).not.toHaveProperty("error"); const data = (entry as { data: Record }).data; // Draft posts have no publishedAt expect(data.publishedAt).toBeNull(); // But createdAt and updatedAt should still be Date objects expect(data.createdAt).toBeInstanceOf(Date); expect(data.updatedAt).toBeInstanceOf(Date); }); it("should use revision content fields while preserving system date types", async () => { const post = await createPublishedPost("Original Title"); const revision = await revisionRepo.create({ collection: "post", entryId: post.id, data: { title: "Revised Title" }, }); const loader = emdashLoader(); const slug = post.slug!; const entry = await runWithContext({ editMode: true, db }, () => loader.loadEntry!({ filter: { type: "post", id: slug, revisionId: revision.id } }), ); expect(entry).toBeDefined(); expect(entry).not.toHaveProperty("error"); const data = (entry as { data: Record }).data; // Content from revision expect(data.title).toBe("Revised Title"); // System dates from content table, as Date objects expect(data.createdAt).toBeInstanceOf(Date); expect(data.updatedAt).toBeInstanceOf(Date); }); });