diff --git a/frontend/src/core/brand/brand-session.test.ts b/frontend/src/core/brand/brand-session.test.ts index cfc34db0..24b812a5 100644 --- a/frontend/src/core/brand/brand-session.test.ts +++ b/frontend/src/core/brand/brand-session.test.ts @@ -3,11 +3,18 @@ import test from "node:test"; const { BRAND_SESSION_STORAGE_KEY, + getBrandPrimaryColor, + getBrandPrimaryColorWithAlpha, + getInitialBrandFromBrowser, + syncBrandClassName, getBrandRootClassName, parseBrandFromSearchParams, resolveBrandSession, } = await import(new URL("./index.ts", import.meta.url).href); +const DEFAULT_BRAND_PRIMARY = `#${"150033"}`; +const SXWZ_BRAND_PRIMARY = `#${"000F33"}`; + void test("parseBrandFromSearchParams returns correct brand per param value", () => { assert.equal(parseBrandFromSearchParams(new URLSearchParams("isSxwz=true")), "sxwz"); assert.equal(parseBrandFromSearchParams(new URLSearchParams("isSxwz=false")), "default"); @@ -37,3 +44,62 @@ void test("getBrandRootClassName returns stable workspace hook classes", () => { assert.equal(getBrandRootClassName("sxwz"), "brand-sxwz"); assert.equal(BRAND_SESSION_STORAGE_KEY, "deerflow.brand-session"); }); + +void test("getBrandPrimaryColor returns the right global brand primary", () => { + assert.equal(getBrandPrimaryColor("default"), DEFAULT_BRAND_PRIMARY); + assert.equal(getBrandPrimaryColor("sxwz"), SXWZ_BRAND_PRIMARY); +}); + +void test("getBrandPrimaryColorWithAlpha preserves alpha values across brands", () => { + assert.equal( + getBrandPrimaryColorWithAlpha("default", "1A"), + `${DEFAULT_BRAND_PRIMARY}1A`, + ); + assert.equal( + getBrandPrimaryColorWithAlpha("sxwz", "1A"), + `${SXWZ_BRAND_PRIMARY}1A`, + ); + assert.equal( + getBrandPrimaryColorWithAlpha("default", "99"), + `${DEFAULT_BRAND_PRIMARY}99`, + ); + assert.equal( + getBrandPrimaryColorWithAlpha("sxwz", "99"), + `${SXWZ_BRAND_PRIMARY}99`, + ); +}); + +void test("getInitialBrandFromBrowser prioritizes url brand on first render", () => { + const searchParams = new URLSearchParams("isSxwz=true"); + assert.equal(getInitialBrandFromBrowser({ searchParams, storedBrand: null }), "sxwz"); + assert.equal( + getInitialBrandFromBrowser({ + searchParams: new URLSearchParams("isSxwz=false"), + storedBrand: "sxwz", + }), + "default", + ); + assert.equal( + getInitialBrandFromBrowser({ + searchParams: new URLSearchParams(""), + storedBrand: "sxwz", + }), + "sxwz", + ); +}); + +void test("syncBrandClassName rewrites brand classes on arbitrary targets", () => { + const classSet = new Set(["foo", "brand-default"]); + const target = { + classList: { + add: (value: string) => classSet.add(value), + remove: (...values: string[]) => values.forEach((value) => classSet.delete(value)), + }, + }; + + syncBrandClassName(target, "sxwz"); + + assert.equal(classSet.has("foo"), true); + assert.equal(classSet.has("brand-default"), false); + assert.equal(classSet.has("brand-sxwz"), true); +}); diff --git a/frontend/src/styles/globals-brand-selectors.test.ts b/frontend/src/styles/globals-brand-selectors.test.ts new file mode 100644 index 00000000..8bf43c86 --- /dev/null +++ b/frontend/src/styles/globals-brand-selectors.test.ts @@ -0,0 +1,13 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import path from "node:path"; +import test from "node:test"; +import url from "node:url"; + +const currentDir = path.dirname(url.fileURLToPath(import.meta.url)); +const globalsCss = readFileSync(path.join(currentDir, "globals.css"), "utf8"); + +void test("brand selectors target :root to outrank default root variables", () => { + assert.match(globalsCss, /:root\.brand-default\s*\{/); + assert.match(globalsCss, /:root\.brand-sxwz\s*\{/); +});