import { beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("next/cache", async () => ({ revalidatePath: (await import("@/tests/helpers/next-mocks")).revalidatePath })); vi.mock("next/navigation", async () => ({ redirect: (await import("@/tests/helpers/next-mocks")).redirect })); vi.mock("next/dist/client/components/redirect-error", async () => ({ isRedirectError: (await import("@/tests/helpers/next-mocks")).isRedirectError, })); vi.mock("@/lib/admin-auth", async () => { const m = await import("@/tests/helpers/next-mocks"); return { isAdminAuthenticated: m.isAdminAuthenticated, clearAdminSessionCookie: m.clearAdminSessionCookie }; }); import { saveSiteBrandSettingsAction, saveSiteLocalizationSettingsAction, } from "@/app/_admin/site-settings/actions"; import { getSiteSettings, getSiteSettingsMediaBindings } from "@/lib/app-config"; import { adminAuth, captureRedirect, formDataFrom, resetNextMocks } from "@/tests/helpers/next-mocks"; beforeEach(() => { resetNextMocks(); }); describe("saveSiteBrandSettingsAction", () => { it("saves a normalized primary color", async () => { const url = await captureRedirect(() => saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "#123456" }))); expect(url).toContain("success="); expect((await getSiteSettings()).brand.primaryColor).toBe("#123456"); }); it("falls back to the default color for invalid input", async () => { await captureRedirect(() => saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "not-a-color" }))); expect((await getSiteSettings()).brand.primaryColor).toBe("#dc5a35"); }); it("wires an external favicon into media bindings", async () => { const faviconMedia = JSON.stringify({ mode: "external", url: "https://cdn/f.svg", kind: "IMAGE", label: "F" }); const url = await captureRedirect(() => saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "#222222", faviconMedia })), ); expect(url).toContain("success="); const bindings = await getSiteSettingsMediaBindings(); expect(bindings.favicon?.url).toBe("https://cdn/f.svg"); }); it("errors on an invalid media json payload", async () => { const url = await captureRedirect(() => saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "#222222", faviconMedia: "{not json" })), ); expect(url).toContain("error="); }); it("redirects unauthenticated callers to the admin root", async () => { adminAuth.authenticated = false; const url = await captureRedirect(() => saveSiteBrandSettingsAction(formDataFrom({ primaryColor: "#123456" }))); expect(url).toBe("/"); }); }); const localizationForm = { defaultLocale: "en", siteNameAr: "الموقع", siteNameEn: "The Site", siteNameDe: "Die Seite", titleTemplateAr: "{pageTitle} | {siteName}", titleTemplateEn: "{pageTitle} | {siteName}", titleTemplateDe: "{pageTitle} | {siteName}", siteDescriptionAr: "وصف", siteDescriptionEn: "Description", siteDescriptionDe: "Beschreibung", subheadAr: "", subheadEn: "", subheadDe: "", }; describe("saveSiteLocalizationSettingsAction", () => { it("saves valid localization settings and the default locale", async () => { const url = await captureRedirect(() => saveSiteLocalizationSettingsAction(formDataFrom(localizationForm))); expect(url).toContain("success="); const settings = await getSiteSettings(); expect(settings.defaultLocale).toBe("en"); expect(settings.locales.en.siteName).toBe("The Site"); }); it("requires a site name for every locale", async () => { const url = await captureRedirect(() => saveSiteLocalizationSettingsAction(formDataFrom({ ...localizationForm, siteNameEn: "" })), ); expect(url).toContain("error="); }); it("requires the {pageTitle} token in every title template", async () => { const url = await captureRedirect(() => saveSiteLocalizationSettingsAction(formDataFrom({ ...localizationForm, titleTemplateDe: "{siteName} only" })), ); expect(url).toContain("error="); }); it("redirects unauthenticated callers to the admin root", async () => { adminAuth.authenticated = false; const url = await captureRedirect(() => saveSiteLocalizationSettingsAction(formDataFrom(localizationForm))); expect(url).toBe("/"); }); });