import { describe, expect, it } from "vitest"; import { StringCatalog } from "../../src/i18n/catalog"; import { scanPage } from "../../src/tutorial/AttackDetector"; import { stepsFor } from "../../src/tutorial/TutorialContent"; const catalogs = import.meta.glob<{ default: StringCatalog }>("../../src/i18n/locales/*.ts", { eager: true }); const titles = (triggerEventName: string): string[] => { document.body.innerHTML = "

Verify you are human

"; return stepsFor(scanPage(triggerEventName, document)).map(step => step.titleKey); }; describe("tutorial", () => { it("explains a copied ClickFix command as malware the person was about to run", () => { document.body.innerHTML = "

Verify you are human

"; const detection = scanPage("command_copied", document); const steps = stepsFor(detection); expect(detection.type).toBe("malware"); expect(detection.permissionKind).toBe("command"); expect(steps.find(step => step.titleKey === "perm_command_title")).toMatchObject({ bodyKey: "perm_command_body", icon: "command" }); expect(titles("command_copied")).toContain("lesson_malware_title"); expect(titles("command_copied")).not.toContain("lesson_permission_title"); }); it("explains granted OAuth consent as access given away", () => { document.body.innerHTML = "

An app wants access

"; const detection = scanPage("consent_granted", document); const steps = stepsFor(detection); expect(detection.type).toBe("fake_page"); expect(detection.permissionKind).toBe("consent"); expect(steps.find(step => step.titleKey === "perm_consent_title")).toMatchObject({ bodyKey: "perm_consent_body", icon: "consent" }); expect(titles("consent_granted")).toContain("lesson_permission_title"); }); it("keeps the permission lesson for the existing permission events", () => { expect(titles("webcam_accepted")).toEqual(expect.arrayContaining(["perm_webcam_title", "lesson_permission_title"])); expect(titles("clipboard_accepted")).toEqual(expect.arrayContaining(["perm_clipboard_title", "lesson_permission_title"])); }); it("translates every string into every locale", () => { const english = catalogs["../../src/i18n/locales/en-US.ts"].default; const locales = Object.keys(catalogs); expect(locales).toHaveLength(10); for (const path of locales) { const catalog = catalogs[path].default; for (const key of Object.keys(english) as (keyof StringCatalog)[]) { expect(catalog[key], `${path} ${key}`).toBeTruthy(); } } }); it("words the new steps in each locale rather than falling back to English", () => { const english = catalogs["../../src/i18n/locales/en-US.ts"].default; for (const path of Object.keys(catalogs).filter(path => !path.endsWith("en-US.ts"))) { const catalog = catalogs[path].default; for (const key of ["perm_command_title", "perm_command_body", "perm_consent_title", "perm_consent_body"] as (keyof StringCatalog)[]) { expect(catalog[key], `${path} ${key}`).toBeTruthy(); expect(catalog[key], `${path} ${key}`).not.toBe(english[key]); } } }); });