feat(i18n): add localized navigation and news translations

This commit is contained in:
2026-02-12 21:29:15 +01:00
parent 618319dbc2
commit a7895e4dd9
12 changed files with 687 additions and 164 deletions

View File

@@ -9,6 +9,9 @@ const { mockDb } = vi.hoisted(() => ({
update: vi.fn(),
delete: vi.fn(),
},
postTranslation: {
upsert: vi.fn(),
},
},
}))
@@ -16,7 +19,15 @@ vi.mock("./client", () => ({
db: mockDb,
}))
import { createPost, getPostBySlug, listPosts, updatePost } from "./posts"
import {
createPost,
getPostBySlug,
getPostBySlugForLocale,
listPosts,
listPostsForLocale,
updatePost,
upsertPostTranslation,
} from "./posts"
describe("posts service", () => {
beforeEach(() => {
@@ -25,6 +36,7 @@ describe("posts service", () => {
fn.mockReset()
}
}
mockDb.postTranslation.upsert.mockReset()
})
it("lists posts ordered by update date desc", async () => {
@@ -72,4 +84,63 @@ describe("posts service", () => {
},
})
})
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()
})
})