feat(FN-2154): show dismissible setup warning on project page

- Render SetupWarningBanner from App only in project view when setup readiness reports warnings
- Persist dismiss state per project via scoped storage and restore it when switching projects
- Add optional dismiss action to SetupWarningBanner with close button UI and responsive styles
- Remove inline banner from QuickEntryBox and add tests covering dismiss button behavior
This commit is contained in:
Fusion
2026-04-19 13:49:18 -07:00
committed by gsxdsm
parent 1e8bb8345d
commit b052f17bd1
5 changed files with 174 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { describe, it, expect, vi } from "vitest";
import { fireEvent, render, screen } from "@testing-library/react";
import { SetupWarningBanner } from "../SetupWarningBanner";
describe("SetupWarningBanner", () => {
@@ -71,4 +71,69 @@ describe("SetupWarningBanner", () => {
const banner = screen.getByRole("status");
expect(banner).toHaveAttribute("aria-live", "polite");
});
it("does not render dismiss button when onDismiss is not provided", () => {
render(<SetupWarningBanner hasAiProvider={false} hasGithub />);
expect(
screen.queryByRole("button", { name: "Dismiss setup warning" }),
).toBeNull();
});
it("renders dismiss button when onDismiss is provided (full mode)", () => {
const onDismiss = vi.fn();
render(
<SetupWarningBanner
hasAiProvider={false}
hasGithub
onDismiss={onDismiss}
/>,
);
const dismissButton = screen.getByRole("button", {
name: "Dismiss setup warning",
});
expect(dismissButton).toBeInTheDocument();
fireEvent.click(dismissButton);
expect(onDismiss).toHaveBeenCalledTimes(1);
});
it("renders dismiss button when onDismiss is provided (compact mode)", () => {
const onDismiss = vi.fn();
render(
<SetupWarningBanner
hasAiProvider={false}
hasGithub
compact
onDismiss={onDismiss}
/>,
);
const dismissButton = screen.getByRole("button", {
name: "Dismiss setup warning",
});
expect(dismissButton).toBeInTheDocument();
fireEvent.click(dismissButton);
expect(onDismiss).toHaveBeenCalledTimes(1);
});
it("clicking dismiss button calls onDismiss", () => {
const onDismiss = vi.fn();
render(
<SetupWarningBanner
hasAiProvider={false}
hasGithub={false}
onDismiss={onDismiss}
/>,
);
fireEvent.click(screen.getByRole("button", { name: "Dismiss setup warning" }));
expect(onDismiss).toHaveBeenCalledTimes(1);
});
});