- Vitest multi-project setup (unit / integration / component) - Real-Postgres integration harness via in-process PGlite (TEST_DATABASE_URL override), migrations applied per worker; production code untouched - Unit: routing, locale, validation/Zod schemas, metadata, mail, site-theme, marquee, media, portfolio helpers, plus architecture-rule tests - Integration: Prisma data layer, API routes, and all server actions - Component: UI primitives and form components (jsdom + Testing Library) - 371 tests passing
86 lines
3.1 KiB
TypeScript
86 lines
3.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
buildDefaultMarqueeSettings,
|
|
parseMarqueeSettingsValue,
|
|
splitMarqueeRowItems,
|
|
syncMarqueeSettingsToGermanSource,
|
|
} from "@/lib/marquee-settings";
|
|
|
|
describe("buildDefaultMarqueeSettings", () => {
|
|
it("provides all four rows for every locale", () => {
|
|
const settings = buildDefaultMarqueeSettings();
|
|
for (const locale of ["ar", "en", "de"] as const) {
|
|
expect(settings.locales[locale].row1).toContain("Next.js");
|
|
expect(settings.locales[locale].row2).toContain("TypeScript");
|
|
expect(settings.locales[locale].row3).toContain("JavaScript");
|
|
expect(settings.locales[locale].row4).toContain("Frontend Strategy");
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("syncMarqueeSettingsToGermanSource", () => {
|
|
it("copies the german rows over english and arabic", () => {
|
|
const base = buildDefaultMarqueeSettings();
|
|
base.locales.de.row1 = "GERMAN";
|
|
base.locales.en.row1 = "english";
|
|
base.locales.ar.row1 = "arabic";
|
|
const synced = syncMarqueeSettingsToGermanSource(base);
|
|
expect(synced.locales.de.row1).toBe("GERMAN");
|
|
expect(synced.locales.en.row1).toBe("GERMAN");
|
|
expect(synced.locales.ar.row1).toBe("GERMAN");
|
|
});
|
|
|
|
it("returns independent copies (no shared references)", () => {
|
|
const synced = syncMarqueeSettingsToGermanSource(buildDefaultMarqueeSettings());
|
|
synced.locales.en.row1 = "changed";
|
|
expect(synced.locales.de.row1).not.toBe("changed");
|
|
});
|
|
});
|
|
|
|
describe("parseMarqueeSettingsValue", () => {
|
|
it("returns german-synced defaults for empty input", () => {
|
|
const settings = parseMarqueeSettingsValue(null);
|
|
expect(settings.locales.en.row1).toBe(settings.locales.de.row1);
|
|
expect(settings.locales.de.row1).toContain("Next.js");
|
|
});
|
|
|
|
it("returns defaults for invalid json", () => {
|
|
const settings = parseMarqueeSettingsValue("{not json");
|
|
expect(settings.locales.de.row1).toContain("Next.js");
|
|
});
|
|
|
|
it("normalizes stored values, trims, and syncs to german", () => {
|
|
const settings = parseMarqueeSettingsValue(
|
|
JSON.stringify({
|
|
locales: {
|
|
de: { row1: " Custom Row 1 ", row2: "R2", row3: "R3", row4: "R4" },
|
|
en: { row1: "IGNORED" },
|
|
},
|
|
}),
|
|
);
|
|
expect(settings.locales.de.row1).toBe("Custom Row 1");
|
|
// english is overwritten by the german source
|
|
expect(settings.locales.en.row1).toBe("Custom Row 1");
|
|
expect(settings.locales.ar.row2).toBe("R2");
|
|
});
|
|
|
|
it("falls back to per-row defaults when a row is blank", () => {
|
|
const settings = parseMarqueeSettingsValue(
|
|
JSON.stringify({ locales: { de: { row1: " ", row2: "", row3: "R3", row4: "R4" } } }),
|
|
);
|
|
expect(settings.locales.de.row1).toContain("Next.js");
|
|
expect(settings.locales.de.row3).toBe("R3");
|
|
});
|
|
});
|
|
|
|
describe("splitMarqueeRowItems", () => {
|
|
it("splits on newlines and commas and trims blanks", () => {
|
|
expect(splitMarqueeRowItems("A\nB, C\n\n , D")).toEqual(["A", "B", "C", "D"]);
|
|
});
|
|
|
|
it("returns an empty array for whitespace-only input", () => {
|
|
expect(splitMarqueeRowItems(" \n ")).toEqual([]);
|
|
});
|
|
});
|