test: add comprehensive automated test coverage

- 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
This commit is contained in:
Moh
2026-08-06 02:27:20 +02:00
parent 0f48381894
commit e2e06be86e
50 changed files with 4975 additions and 26 deletions
+53
View File
@@ -0,0 +1,53 @@
import { describe, expect, it } from "vitest";
import { buildSiteThemeStyleText, buildSiteThemeTokens } from "@/lib/site-theme";
const CHANNEL = /^\d+ \d+% \d+%$/;
describe("buildSiteThemeTokens", () => {
it("converts pure red to the expected HSL channels", () => {
const tokens = buildSiteThemeTokens("#ff0000");
expect(tokens.light.primary).toBe("0 100% 50%");
// dark primary lightens by 6 and clamps saturation into [40,95]
expect(tokens.dark.primary).toBe("0 95% 56%");
});
it("produces zero saturation for a neutral gray", () => {
const tokens = buildSiteThemeTokens("#808080");
expect(tokens.light.primary.startsWith("0 0%")).toBe(true);
});
it("emits well-formed channel strings for every token", () => {
const tokens = buildSiteThemeTokens("#dc5a35");
for (const value of [
tokens.light.primary,
tokens.light.secondary,
tokens.dark.primary,
tokens.dark.secondary,
]) {
expect(value).toMatch(CHANNEL);
}
});
it("derives distinct dark and secondary variants", () => {
const tokens = buildSiteThemeTokens("#dc5a35");
expect(tokens.dark.primary).not.toBe(tokens.light.primary);
expect(tokens.light.secondary).not.toBe(tokens.light.primary);
});
it("falls back to the default brand color for invalid input", () => {
expect(buildSiteThemeTokens("not-a-color")).toEqual(buildSiteThemeTokens("#dc5a35"));
expect(buildSiteThemeTokens("")).toEqual(buildSiteThemeTokens("#dc5a35"));
});
});
describe("buildSiteThemeStyleText", () => {
it("emits :root and .dark blocks with the derived channels", () => {
const css = buildSiteThemeStyleText("#ff0000");
expect(css).toContain(":root {");
expect(css).toContain(".dark {");
expect(css).toContain("--primary: 0 100% 50%;");
expect(css).toContain("--brand-secondary:");
expect(css).toContain("--sidebar-ring:");
});
});