import { existsSync, readdirSync, readFileSync } from "node:fs"; import { join } from "node:path"; import { Resvg } from "@resvg/resvg-js"; import { describe, expect, it } from "vitest"; import manifest from "@/app/manifest"; import { metadata } from "@/app/layout"; const ORDNER = "public/brand"; /** Breite und Höhe aus dem IHDR-Block einer PNG-Datei. */ function pngGroesse(datei: string): [number, number] { const daten = readFileSync(join(ORDNER, datei)); expect(daten.subarray(1, 4).toString()).toBe("PNG"); return [daten.readUInt32BE(16), daten.readUInt32BE(20)]; } describe("Marken-Dateien (pnpm marke)", () => { it("alle SVGs der Vorgabe sind da, renderbar und ohne kaputte Koordinaten", () => { const svgs = readdirSync(ORDNER).filter((d) => d.endsWith(".svg")); expect(svgs.sort()).toEqual( [ "avatar.svg", "banner.svg", "icon-small.svg", "logo-light.svg", "logo.svg", "symbol-light.svg", "symbol.svg", ].sort(), ); for (const datei of svgs) { const text = readFileSync(join(ORDNER, datei), "utf8"); expect(text, datei).not.toMatch(/NaN|Infinity/); const bild = new Resvg(text).render(); expect(bild.width, datei).toBeGreaterThan(0); } const banner = new Resvg(readFileSync(join(ORDNER, "banner.svg"), "utf8")).render(); expect([banner.width, banner.height]).toEqual([1280, 640]); }); it("kein Proxmox-Orange und nur Markenfarben", () => { const erlaubt = new Set(["#11161C", "#1A2129", "#2A333D", "#8B98A5", "#E6EDF3", "#2DD4BF", "#0F766E"]); for (const datei of readdirSync(ORDNER).filter((d) => d.endsWith(".svg"))) { for (const [farbe] of readFileSync(join(ORDNER, datei), "utf8").matchAll(/#[0-9A-Fa-f]{6}\b/g)) { expect(erlaubt.has(farbe.toUpperCase()), `${datei}: ${farbe}`).toBe(true); } } }); it("Rasterbilder haben die richtige Größe; Layout und Manifest zeigen nur auf vorhandene Dateien", () => { expect(pngGroesse("favicon-16.png")).toEqual([16, 16]); expect(pngGroesse("favicon-32.png")).toEqual([32, 32]); expect(pngGroesse("apple-touch-icon.png")).toEqual([180, 180]); expect(pngGroesse("icon-192.png")).toEqual([192, 192]); expect(pngGroesse("icon-512.png")).toEqual([512, 512]); expect(pngGroesse("icon-maskable-512.png")).toEqual([512, 512]); expect(pngGroesse("banner.png")).toEqual([1280, 640]); const pfade = [ ...(manifest().icons ?? []).map((i) => i.src), ...JSON.stringify(metadata.icons) .matchAll(/"url":"([^"]+)"/g) .map((t) => t[1]!), ]; expect(pfade.length).toBeGreaterThan(5); for (const pfad of pfade) expect(existsSync(join("public", pfad)), pfad).toBe(true); }); });