147 lines
3.8 KiB
TypeScript
147 lines
3.8 KiB
TypeScript
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()
|
|
})
|
|
})
|