fix: address QA feedback on site theming PR (GH #91)

- Fix gradient regression in ReportCards.tsx: use distinct color stops
  (--color-accent-lighter → --color-accent-light) to restore subtle gradient
- Fix BrandingContext meta tag accumulation: cache ref with useRef instead
  of querying DOM on every render to prevent duplicate elements on remount
- Add BrandingContext.test.tsx: verify CSS vars applied, theme-color meta
  created/updated, and no duplicate meta tags on rerender

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scrubs McBarkley
2026-03-22 00:12:57 +00:00
parent 4060d5b515
commit a15585a8e6
3 changed files with 117 additions and 8 deletions
@@ -0,0 +1,106 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, waitFor } from "@testing-library/react";
import { BrandingProvider, useBranding } from "../BrandingContext.js";
function BrandingConsumer() {
const { branding } = useBranding();
return (
<div data-testid="branding">
<span data-testid="primary">{branding.primaryColor}</span>
<span data-testid="accent">{branding.accentColor}</span>
</div>
);
}
beforeEach(() => {
vi.restoreAllMocks();
document.documentElement.style.removeProperty("--color-primary");
document.documentElement.style.removeProperty("--color-accent");
// Remove any theme-color meta tags
document.querySelectorAll("meta[name='theme-color']").forEach((el) => el.remove());
});
describe("BrandingProvider", () => {
it("applies CSS vars to document root when branding loads", async () => {
const branding = {
businessName: "Test Salon",
primaryColor: "#123456",
accentColor: "#654321",
logoBase64: null,
logoMimeType: null,
};
global.fetch = vi.fn(() =>
Promise.resolve({ ok: true, json: async () => branding } as Response)
) as unknown as typeof fetch;
render(
<BrandingProvider>
<BrandingConsumer />
</BrandingProvider>
);
await waitFor(() => {
expect(document.documentElement.style.getPropertyValue("--color-primary")).toBe("#123456");
expect(document.documentElement.style.getPropertyValue("--color-accent")).toBe("#654321");
});
});
it("creates and updates meta[name=theme-color]", async () => {
const branding = {
businessName: "Test Salon",
primaryColor: "#abcdef",
accentColor: "#fedcba",
logoBase64: null,
logoMimeType: null,
};
global.fetch = vi.fn(() =>
Promise.resolve({ ok: true, json: async () => branding } as Response)
) as unknown as typeof fetch;
render(
<BrandingProvider>
<BrandingConsumer />
</BrandingProvider>
);
await waitFor(() => {
const meta = document.querySelector<HTMLMetaElement>("meta[name='theme-color']");
expect(meta).not.toBeNull();
expect(meta!.content).toBe("#abcdef");
});
});
it("does not create duplicate meta[name=theme-color] tags on rerender", async () => {
const branding = {
businessName: "Test Salon",
primaryColor: "#111111",
accentColor: "#222222",
logoBase64: null,
logoMimeType: null,
};
global.fetch = vi.fn(() =>
Promise.resolve({ ok: true, json: async () => branding } as Response)
) as unknown as typeof fetch;
const { rerender } = render(
<BrandingProvider>
<BrandingConsumer />
</BrandingProvider>
);
await waitFor(() => {
expect(document.querySelector("meta[name='theme-color']")).not.toBeNull();
});
rerender(
<BrandingProvider>
<BrandingConsumer />
</BrandingProvider>
);
await waitFor(() => {
const metas = document.querySelectorAll("meta[name='theme-color']");
expect(metas.length).toBe(1);
});
});
});