import { beforeEach, describe, expect, it, vi } from "vitest" const { mockDb } = vi.hoisted(() => ({ mockDb: { post: { create: vi.fn(), findMany: vi.fn(), findUnique: vi.fn(), update: vi.fn(), delete: vi.fn(), }, postTranslation: { upsert: vi.fn(), }, }, })) vi.mock("./client", () => ({ db: mockDb, })) import { createPost, getPostBySlug, getPostBySlugForLocale, listPosts, listPostsForLocale, updatePost, upsertPostTranslation, } from "./posts" describe("posts service", () => { beforeEach(() => { for (const fn of Object.values(mockDb.post)) { if (typeof fn === "function") { fn.mockReset() } } mockDb.postTranslation.upsert.mockReset() }) it("lists posts ordered by update date desc", async () => { mockDb.post.findMany.mockResolvedValue([]) await listPosts() expect(mockDb.post.findMany).toHaveBeenCalledTimes(1) expect(mockDb.post.findMany.mock.calls[0]?.[0]).toMatchObject({ orderBy: { updatedAt: "desc", }, }) }) it("parses create and update payloads through crud service", async () => { mockDb.post.create.mockResolvedValue({ id: "post-1" }) mockDb.post.findUnique.mockResolvedValue({ id: "550e8400-e29b-41d4-a716-446655440000" }) mockDb.post.update.mockResolvedValue({ id: "post-1" }) await createPost({ title: "A title", slug: "a-title", body: "Body", status: "draft", }) await updatePost("550e8400-e29b-41d4-a716-446655440000", { title: "Updated", }) expect(mockDb.post.create).toHaveBeenCalledTimes(1) expect(mockDb.post.update).toHaveBeenCalledTimes(1) }) it("finds posts by slug", async () => { mockDb.post.findUnique.mockResolvedValue({ id: "post-1", slug: "hello" }) await getPostBySlug("hello") expect(mockDb.post.findUnique).toHaveBeenCalledTimes(1) expect(mockDb.post.findUnique).toHaveBeenCalledWith({ where: { slug: "hello", }, }) }) it("upserts post translation and reads localized/fallback post views", async () => { mockDb.postTranslation.upsert.mockResolvedValue({ id: "pt-1" }) mockDb.post.findUnique .mockResolvedValueOnce({ id: "post-1", slug: "hello", title: "Base title", excerpt: "Base excerpt", body: "Base body", translations: [{ locale: "de", title: "Titel", excerpt: "Auszug", body: "Text" }], }) .mockResolvedValueOnce({ id: "post-1", slug: "hello", title: "Base title", excerpt: "Base excerpt", body: "Base body", translations: [], }) mockDb.post.findMany.mockResolvedValue([ { id: "post-1", slug: "hello", title: "Base title", excerpt: "Base excerpt", body: "Base body", status: "published", translations: [{ locale: "de", title: "Titel", excerpt: "Auszug", body: "Text" }], }, ]) await upsertPostTranslation({ postId: "550e8400-e29b-41d4-a716-446655440000", locale: "de", title: "Titel", body: "Text", }) const localized = await getPostBySlugForLocale("hello", "de") const fallback = await getPostBySlugForLocale("hello", "fr") const localizedList = await listPostsForLocale("de") expect(mockDb.postTranslation.upsert).toHaveBeenCalledTimes(1) expect(localized?.title).toBe("Titel") expect(fallback?.title).toBe("Base title") expect(localizedList[0]?.title).toBe("Titel") }) it("validates locale for post translations", async () => { await expect(() => upsertPostTranslation({ postId: "550e8400-e29b-41d4-a716-446655440000", locale: "it", title: "Titolo", body: "Testo", }), ).rejects.toThrow() }) })