feat(t5): Darstellung hell/dunkel/Sonne ohne Flackern (T5a A2)
Blockierendes Skript im <head> setzt Darstellung, Kontrast und Bewegung vor dem ersten Zeichnen (gleiche Logik wie resolveAppearance, für alle Eingaben getestet), theme-color je Satz, Wahl je Gerät in localStorage mit Rückfall bei gesperrtem Speicher; Abgleich über Tabs, Systemeinstellungen und Seitenwechsel an einer Stelle. Profil-Karte „Darstellung“, Sonnenmodus im Benutzermenü; Dunkel bleibt bis A4 hinter NEXT_PUBLIC_APPEARANCE_DARK. next-themes entfernt. ARCHITECTURE §9: 'unsafe-inline' der Frontend-CSP als getragenes Risiko mit Begründung. Refs #26 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
947a46f435
commit
cf53cf35ac
22 files changed
+980
-97
No files matched your search
@@ -2,6 +2,8 @@ import { useMutation } from "@tanstack/react-query";
|
||||
import { act, render, screen, waitFor } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { Providers } from "./providers";
|
||||
|
||||
vi.mock("@/lib/auth/auth-context", () => ({
|
||||
@@ -37,4 +39,26 @@ describe("Providers", () => {
|
||||
await userEvent.click(screen.getByRole("button", { name: "Speichern" }));
|
||||
await waitFor(() => expect(mutationFn).toHaveBeenCalledTimes(1));
|
||||
});
|
||||
|
||||
it("does not apply the motion level itself any more (the inline script does)", () => {
|
||||
document.documentElement.removeAttribute("data-motion");
|
||||
window.localStorage.setItem("apicore.motion", "off");
|
||||
render(
|
||||
<Providers>
|
||||
<p>x</p>
|
||||
</Providers>,
|
||||
);
|
||||
expect(document.documentElement).not.toHaveAttribute("data-motion");
|
||||
window.localStorage.clear();
|
||||
});
|
||||
});
|
||||
|
||||
describe("theme handling", () => {
|
||||
it("the toaster follows resolvedTheme and next-themes is not imported", () => {
|
||||
const toaster = readFileSync(path.resolve(__dirname, "../components/ui/sonner.tsx"), "utf8");
|
||||
expect(toaster).toContain("resolvedTheme");
|
||||
expect(toaster).not.toContain("next-themes");
|
||||
const pkg = JSON.parse(readFileSync(path.resolve(__dirname, "../../package.json"), "utf8"));
|
||||
expect(pkg.dependencies["next-themes"]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user