From d651049659ab57b7094c16704ecaf2dd5f00ff86 Mon Sep 17 00:00:00 2001 From: hugo Date: Sat, 21 Feb 2026 13:53:55 +0100 Subject: [PATCH] chore: safety checks mixed-language installations --- tests/engine/BlogGenerationEngine.test.ts | 20 ++++++++ tests/engine/PreviewServer.test.ts | 58 +++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/tests/engine/BlogGenerationEngine.test.ts b/tests/engine/BlogGenerationEngine.test.ts index 103e795..80c4ce6 100644 --- a/tests/engine/BlogGenerationEngine.test.ts +++ b/tests/engine/BlogGenerationEngine.test.ts @@ -3,6 +3,7 @@ import { mkdtemp, readFile, rm, readdir, stat } from 'node:fs/promises'; import path from 'node:path'; import { tmpdir } from 'node:os'; import type { PostData } from '../../src/main/engine/PostEngine'; +import { resolveUiLanguageFromSystemLocale } from '../../src/main/shared/i18n'; const generatedFileHashes = new Map(); const getGeneratedFileHashMock = vi.fn(async (projectId: string, relativePath: string) => { @@ -365,6 +366,25 @@ describe('BlogGenerationEngine', () => { expect(await fileExists(path.join(tempDir, 'html', '2025', '02', '20', 'index.html'))).toBe(true); }); + it('keeps static render language from project settings when ui language differs', async () => { + const uiLanguage = resolveUiLanguageFromSystemLocale('de-DE'); + expect(uiLanguage).toBe('de'); + + const posts = [ + makePost({ id: 'fr-1', slug: 'fr-1', title: 'FR 1', createdAt: new Date('2020-02-15T10:00:00Z') }), + makePost({ id: 'fr-2', slug: 'fr-2', title: 'FR 2', createdAt: new Date('2020-02-14T10:00:00Z') }), + ]; + + await generate(posts, { language: 'fr', maxPostsPerPage: 50 }); + + const monthArchivePath = path.join(tempDir, 'html', '2020', '02', 'index.html'); + const monthHtml = await readFile(monthArchivePath, 'utf-8'); + + expect(monthHtml).toContain(''); + expect(monthHtml).toContain('

Archives février 2020

'); + expect(monthHtml).not.toContain('

Archiv Februar 2020

'); + }); + it('excludes draft-only posts from generated pages', async () => { const posts = [ makePost({ id: '1', slug: 'published', title: 'Published', status: 'published' }), diff --git a/tests/engine/PreviewServer.test.ts b/tests/engine/PreviewServer.test.ts index 6f713e2..1b62904 100644 --- a/tests/engine/PreviewServer.test.ts +++ b/tests/engine/PreviewServer.test.ts @@ -4,6 +4,7 @@ import path from 'node:path'; import { tmpdir } from 'node:os'; import type { PostData, PostFilter } from '../../src/main/engine/PostEngine'; import { PreviewServer } from '../../src/main/engine/PreviewServer'; +import { resolveUiLanguageFromSystemLocale } from '../../src/main/shared/i18n'; type PostEngineLike = { getPostsFiltered: (filter: PostFilter) => Promise; @@ -607,6 +608,63 @@ describe('PreviewServer', () => { expect(monthPageHtml).toContain('

Archive February 2020

'); }); + it('uses project mainLanguage for translated archive heading text', async () => { + const posts = [ + makePost({ id: 'fr-1', slug: 'fr-1', title: 'FR1', content: 'Body 1', createdAt: new Date('2020-02-05T10:00:00.000Z') }), + makePost({ id: 'fr-2', slug: 'fr-2', title: 'FR2', content: 'Body 2', createdAt: new Date('2020-02-04T10:00:00.000Z') }), + ]; + + server = new PreviewServer({ + postEngine: makeEngine(posts), + settingsEngine: { + setProjectContext: vi.fn(), + async getProjectMetadata() { + return { + mainLanguage: 'fr', + maxPostsPerPage: 50, + }; + }, + }, + getActiveProjectContext: async () => ({ projectId: 'default' }), + }); + + await server.start(0); + + const monthPageHtml = await (await fetch(`${server.getBaseUrl()}/2020/2/`)).text(); + expect(monthPageHtml).toContain('

Archives février 2020

'); + }); + + it('keeps preview render language from project settings when ui language differs', async () => { + const uiLanguage = resolveUiLanguageFromSystemLocale('de-DE'); + expect(uiLanguage).toBe('de'); + + const posts = [ + makePost({ id: 'mixed-1', slug: 'mixed-1', title: 'Mixed 1', content: 'Body 1', createdAt: new Date('2020-02-05T10:00:00.000Z') }), + makePost({ id: 'mixed-2', slug: 'mixed-2', title: 'Mixed 2', content: 'Body 2', createdAt: new Date('2020-02-04T10:00:00.000Z') }), + ]; + + server = new PreviewServer({ + postEngine: makeEngine(posts), + settingsEngine: { + setProjectContext: vi.fn(), + async getProjectMetadata() { + return { + mainLanguage: 'fr', + maxPostsPerPage: 50, + }; + }, + }, + getActiveProjectContext: async () => ({ projectId: 'default' }), + }); + + await server.start(0); + + const monthPageHtml = await (await fetch(`${server.getBaseUrl()}/2020/2/`)).text(); + expect(monthPageHtml).toContain(''); + expect(monthPageHtml).toContain('

Archives février 2020

'); + expect(monthPageHtml).not.toContain('

Archiv Februar 2020

'); + }); + it('renders tag heading on first page and adds date range on later pages', async () => { const posts = [ makePost({ id: 't-1', slug: 't-1', title: 'T1', content: 'Body 1', tags: ['dev'], createdAt: new Date('2020-02-05T10:00:00.000Z') }),