fix(canvas): dark zinc disabled button, 6 failing tests, case-insensitive icon lookup
Design fixes:
- PricingTable.tsx: replace non-zinc disabled:bg-blue-900 with
bg-zinc-700/text-zinc-500, keeping all states within the dark zinc
palette (zinc-900 bg, zinc-800 surfaces, zinc-700 borders).
Test fixes:
- PurchaseSuccessModal.test.tsx: replace setTimeout(0) anti-pattern under
vi.useFakeTimers() — act() does not advance fake timers, causing 5000ms
timeouts. Use vi.advanceTimersByTime(10) to flush render effects without
triggering the 5s auto-dismiss. 18/18 tests now pass.
- OnboardingWizard.test.tsx: replace stateless mock with
useSyncExternalStore bridge + subscriber set so React re-renders when
mockStoreState is mutated; fix second-render unmount ordering. 13/13 pass.
- yaml-utils.ts: emit tools: [] key unconditionally (matching skills
behaviour); test expectation was correct, implementation was wrong. 36/36.
- tabs/chat/types.ts createMessage: conditional { attachments } spread
avoids undefined key in Object.keys(); Object.freeze() the returned
object so mutation-guards in tests pass.
- tabs/FilesTab/tree.ts getIcon: normalize extracted extension to
lowercase so data.JSON matches the .json entry in FILE_ICONS.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
fdb811e3bb
commit
97176b3746
@ -13,7 +13,7 @@
|
||||
*/
|
||||
import React from "react";
|
||||
import { render, screen, fireEvent, cleanup, act } from "@testing-library/react";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, afterAll, beforeEach, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { PurchaseSuccessModal } from "../PurchaseSuccessModal";
|
||||
|
||||
// ─── URL stub helper ───────────────────────────────────────────────────────────
|
||||
@ -35,6 +35,40 @@ async function waitForDialog() {
|
||||
await act(async () => { await new Promise((r) => setTimeout(r, 50)); });
|
||||
}
|
||||
|
||||
// ─── Global mocks ─────────────────────────────────────────────────────────────
|
||||
|
||||
let replaceStateMock: ReturnType<typeof vi.spyOn>;
|
||||
let pushStateMock: ReturnType<typeof vi.spyOn>;
|
||||
|
||||
beforeAll(() => {
|
||||
replaceStateMock = vi.spyOn(window.history, "replaceState").mockImplementation(
|
||||
(_s, _u, url) => { if (url) currentUrl = String(url); }
|
||||
);
|
||||
pushStateMock = vi.spyOn(window.history, "pushState").mockImplementation(
|
||||
(_s, _u, url) => { if (url) currentUrl = String(url); }
|
||||
);
|
||||
// Mock window.location as a getter so `new URL(window.location.href)` always
|
||||
// reads the live currentUrl value, not a snapshot made at setup time.
|
||||
Object.defineProperty(window, "location", {
|
||||
get() { return new URL(currentUrl); },
|
||||
configurable: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
replaceStateMock?.mockRestore();
|
||||
pushStateMock?.mockRestore();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
currentUrl = "http://localhost/";
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// ─── Tests ────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe("PurchaseSuccessModal — render conditions", () => {
|
||||
@ -233,4 +267,4 @@ describe("PurchaseSuccessModal — accessibility", () => {
|
||||
// Use getByRole which is more reliable than querySelector
|
||||
expect(screen.getByRole("button", { name: "Close" })).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user