import fs from "node:fs"; import path from "node:path"; import { describe, expect, it } from "vitest"; import DefaultKbsTemplate from "./DefaultKbsTemplate"; const sourcePath = path.resolve(process.cwd(), "apps/web/app/modules/knowledgeBase/utils/DefaultKbsTemplate.ts"); const enTranslationsPath = path.resolve(process.cwd(), "apps/web/public/locales/en/translations.json"); const deTranslationsPath = path.resolve(process.cwd(), "apps/web/public/locales/de/translations.json"); function readTranslations(localePath: string) { return JSON.parse(fs.readFileSync(localePath, "utf8")) as { knowledgeBase: { defaultTemplates: { sample: { knowledgeBases: { docs: { description: string; title: string }; center: { description: string; links: { backToSite: string }; title: string }; }; articles: { exampleSiteKnowledgeBase: { description: string; content: { text: string } }; publishProductDocumentation: { description: string; content: { text: string } }; }; categories: { introduction: { description: string }; kategorie1: { sections: { basics: { description: string } } }; }; }; }; }; }; } describe("DefaultKbsTemplate content", () => { it("keeps seeded knowledge-base copy free from placeholder junk and misspelled API names", () => { const source = fs.readFileSync(sourcePath, "utf8"); expect(source).toContain("knowledgeBase.defaultTemplates.sample"); expect(source).not.toContain("knowlegeBase"); expect(source).not.toContain("asdf"); expect(source).not.toContain("Sample description"); expect(source).not.toContain("Category 1"); expect(source).not.toContain("Introduction category description sample"); expect(source).not.toContain("Example Site - Knowledge Base"); expect(source).not.toContain("loom.com"); expect(source).not.toContain("demo@toolctrl.local"); expect(source).not.toContain("Dynamic vs Static Knowledge Bases"); expect(source).not.toContain("apps/web/app/routes/docs/($lang).tsx"); expect(source).not.toContain("related articles to guide readers"); }); it("stores semantic locale keys for default knowledge-base seed copy", () => { const source = fs.readFileSync(sourcePath, "utf8"); const en = readTranslations(enTranslationsPath); const de = readTranslations(deTranslationsPath); expect(source).toContain('templateKey("knowledgeBases.docs.title")'); expect(source).toContain('templateKey("articles.publishProductDocumentation.content.text")'); expect(source).not.toContain("ui.autogenerated"); expect(en.knowledgeBase.defaultTemplates.sample.knowledgeBases.docs.title).toBe("Docs"); expect(en.knowledgeBase.defaultTemplates.sample.articles.publishProductDocumentation.content.text).toContain("related articles"); expect(de.knowledgeBase.defaultTemplates.sample.knowledgeBases.center.links.backToSite).toBe("Zur Website"); expect(de.knowledgeBase.defaultTemplates.sample.articles.publishProductDocumentation.content.text).toContain("verwandte Artikel"); }); it("exposes locale-scoped admin import samples instead of mixed public chrome", () => { for (const [template, language] of [ [DefaultKbsTemplate.SAMPLE_EN, "en"], [DefaultKbsTemplate.SAMPLE_DE, "de"], ] as const) { expect(Object.keys(template).sort()).toEqual(["articles", "categories", "knowledgeBases"]); expect(template.knowledgeBases.every((kb) => kb.defaultLanguage === language)).toBe(true); expect(template.knowledgeBases.every((kb) => kb.languages.length === 1 && kb.languages[0] === language)).toBe(true); expect(template.categories.every((category) => category.language === language)).toBe(true); expect(template.articles.every((article) => article.language === language)).toBe(true); } expect(DefaultKbsTemplate.SAMPLE_DE.knowledgeBases.map((kb) => kb.title)).toContain("Hilfe-Center"); expect(JSON.stringify(DefaultKbsTemplate.SAMPLE_DE)).not.toContain("Help Center"); expect(JSON.stringify(DefaultKbsTemplate.SAMPLE_DE)).not.toContain("Back to site"); }); it("keeps German knowledge-base copy generic while preserving the Hilfe-Center product title", () => { const deSample = DefaultKbsTemplate.SAMPLE_DE; const deCopy = JSON.stringify(deSample); expect(deSample.knowledgeBases.find((kb) => kb.slug === "center")?.title).toBe("Hilfe-Center"); expect(deSample.categories.find((category) => category.slug === "kategorie-1")?.description).toBe( "Grundlagen für die Einrichtung und Nutzung der Wissensdatenbank." ); expect(deSample.articles.find((article) => article.slug === "beispiel-2")?.title).toBe("Wissensdatenbank strukturieren"); expect(deSample.articles.find((article) => article.slug === "beispiel-1")?.contentPublishedAsText).toContain("Diese Wissensdatenbank bündelt"); expect(deCopy).not.toContain("Nutzung des Hilfe-Centers"); expect(deCopy).not.toContain("Dieses Hilfe-Center bündelt"); }); it("keeps default category and article metadata useful for imported starter content", () => { for (const template of [DefaultKbsTemplate.SAMPLE_EN, DefaultKbsTemplate.SAMPLE_DE]) { for (const knowledgeBase of template.knowledgeBases) { expect(knowledgeBase.title.trim()).not.toHaveLength(0); expect(knowledgeBase.description.trim()).not.toHaveLength(0); } for (const category of template.categories) { expect(category.title.trim()).not.toHaveLength(0); expect(category.description.trim()).not.toHaveLength(0); for (const section of category.sections) { expect(section.title.trim()).not.toHaveLength(0); expect(section.description.trim()).not.toHaveLength(0); } } for (const article of template.articles) { expect(article.title.trim()).not.toHaveLength(0); expect(article.description.trim()).not.toHaveLength(0); } } expect(DefaultKbsTemplate.SAMPLE_EN.knowledgeBases.find((kb) => kb.slug === "docs")?.description).toBe( "Public product documentation and starter guides for your team." ); expect(DefaultKbsTemplate.SAMPLE_EN.knowledgeBases.find((kb) => kb.slug === "center")?.description).toBe( "Customer-facing help articles, setup guidance, and account support." ); expect( DefaultKbsTemplate.SAMPLE_DE.categories.find((category) => category.slug === "kategorie-1")?.sections.find((section) => section.order === 1) ?.description ).toBe("Wichtige Einrichtungshinweise, um hilfreiche Startinhalte zu strukturieren."); expect(DefaultKbsTemplate.SAMPLE_EN.categories.find((category) => category.slug === "introduction")?.description).toBe( "Start here for an overview of the documentation structure." ); const starterArticle = DefaultKbsTemplate.SAMPLE_EN.articles.find((article) => article.slug === "example-site-knowledge-base"); expect(starterArticle?.description).toBe("A short starter article for the public docs knowledge base."); expect(starterArticle?.contentPublishedAsText).toContain("neutral starting point"); expect(starterArticle?.createdByUserEmail).toBeNull(); const publishingArticle = DefaultKbsTemplate.SAMPLE_EN.articles.find((article) => article.slug === "publish-product-documentation"); expect(publishingArticle?.description).toBe("A practical checklist for turning draft articles into useful public documentation."); expect(publishingArticle?.contentPublishedAsText).toContain("answers a real user question"); expect(publishingArticle?.contentPublishedAsText).not.toContain("route files"); }); it("keeps imported sample articles self-contained and attributed to the importing admin", () => { for (const template of [DefaultKbsTemplate.SAMPLE_EN, DefaultKbsTemplate.SAMPLE_DE]) { const serialized = JSON.stringify(template); expect(serialized).not.toContain("loom.com"); expect(serialized).not.toContain("demo@toolctrl.local"); expect(template.articles.every((article) => article.createdByUserEmail === null)).toBe(true); } }); });