feat(FN-3135): restore Claude usage tracking with Fusion Anthropic auth sto

This merge adds test coverage for the two-panel split layout (FN-3135) with desktop and mobile CSS tests, restores Claude usage tracking from Fusion's Anthropic auth storage (FN-3289) in the usage module, and adds mobile auto-routing to the Planning Mode component for empty sessions (FN-3269).

Fusion-Task-Id: FN-3135
This commit is contained in:
Fusion
2026-05-03 10:41:46 -07:00
committed by gsxdsm
parent a418662b2f
commit 8da4900141
3 changed files with 135 additions and 3 deletions

View File

@@ -3789,7 +3789,7 @@ export function MissionManager({ isOpen, isInline = false, onClose, addToast, pr
</div>
) : (
<div className="mission-manager__split">
<div className="mission-manager__sidebar">
<aside className="mission-manager__sidebar" data-testid="mission-sidebar" aria-label="Mission list">
<div className="mission-manager__sidebar-header">
<span className="mission-manager__sidebar-title">Missions</span>
<div className="mission-manager__sidebar-actions">
@@ -3821,7 +3821,7 @@ export function MissionManager({ isOpen, isInline = false, onClose, addToast, pr
renderMissionListContent({ hideBottomButtons: true })
)}
</div>
</div>
</aside>
<div className="mission-manager__detail-pane">
{detailLoading ? (
@@ -3832,7 +3832,7 @@ export function MissionManager({ isOpen, isInline = false, onClose, addToast, pr
) : selectedMission ? (
renderMissionDetailContent()
) : (
<div className="mission-manager__detail-pane-empty">
<div className="mission-manager__detail-pane-empty" data-testid="mission-empty-detail">
<Target size={32} />
<span>Select a mission to view details</span>
</div>

View File

@@ -82,3 +82,83 @@ describe("MissionManager mobile styles", () => {
expect(desktopBlock).toContain("display: none");
});
});
describe("desktop two-panel split CSS", () => {
it("defines sidebar with fixed width, border, and scroll", () => {
const css = loadAllAppCss();
expect(css).toContain(".mission-manager__sidebar {");
// Sidebar width uses token-based calc instead of hardcoded px
expect(css).toContain("flex-shrink: 0;");
expect(css).toContain("border-right");
expect(css).toContain("var(--border)");
});
it("defines detail pane with flex: 1 and overflow", () => {
const css = loadAllAppCss();
expect(css).toContain(".mission-manager__detail-pane {");
expect(css).toContain("flex: 1;");
expect(css).toContain("overflow-y: auto;");
});
it("hides back button on desktop", () => {
const css = loadAllAppCss();
expect(css).toContain(".mission-manager--desktop .mission-manager__back-btn {");
expect(css).toContain("display: none;");
});
it("toggles header title variants on desktop", () => {
const css = loadAllAppCss();
expect(css).toContain(".mission-manager__title-text--desktop {");
expect(css).toContain(".mission-manager__title-text--mobile {");
});
it("defines sidebar list with overflow scroll", () => {
const css = loadAllAppCss();
expect(css).toContain(".mission-manager__sidebar-list {");
expect(css).toContain("overflow-y: auto;");
});
it("defines split container as flex row", () => {
const css = loadAllAppCss();
expect(css).toContain(".mission-manager__split {");
expect(css).toContain("flex-direction: row;");
});
it("defines empty detail pane placeholder", () => {
const css = loadAllAppCss();
expect(css).toContain(".mission-manager__detail-pane-empty {");
expect(css).toContain("var(--text-muted)");
});
});
describe("mobile split reversal CSS", () => {
it("hides desktop split on mobile", () => {
const css = loadAllAppCss();
const section = getMissionMobileSection(css);
expect(section).toContain(".mission-manager__split {");
expect(section).toContain("display: none;");
});
it("restores stacked body on mobile", () => {
const css = loadAllAppCss();
const section = getMissionMobileSection(css);
expect(section).toContain(".mission-manager__body--stacked {");
expect(section).toContain("display: block;");
});
it("restores back button on mobile", () => {
const css = loadAllAppCss();
const section = getMissionMobileSection(css);
const mobileRule = section.match(/\.mission-manager--desktop \.mission-manager__back-btn\s*\{[^}]*\}/)?.[0];
expect(mobileRule).toContain("display: inline-flex;");
});
it("restores dynamic title on mobile", () => {
const css = loadAllAppCss();
const section = getMissionMobileSection(css);
const mobileBlock = section.match(/\.mission-manager__title-text--mobile\s*\{[^}]*\}/)?.[0];
const desktopBlock = section.match(/\.mission-manager__title-text--desktop\s*\{[^}]*\}/)?.[0];
expect(mobileBlock).toContain("display: inline");
expect(desktopBlock).toContain("display: none");
});
});

View File

@@ -3275,4 +3275,56 @@ describe("MissionManager", () => {
expect(getComputedStyle(sidebarList).overflowY).toBe("auto");
});
});
describe("two-panel layout test IDs", () => {
it("renders sidebar and empty detail pane on desktop via test IDs", async () => {
globalThis.fetch = createFetchMock();
render(<MissionManager isOpen={true} onClose={vi.fn()} addToast={vi.fn()} />);
await waitFor(() => {
expect(screen.getByTestId("mission-sidebar")).toBeInTheDocument();
expect(screen.getByTestId("mission-empty-detail")).toBeInTheDocument();
});
});
it("shows mission detail in right pane when mission is selected from sidebar", async () => {
globalThis.fetch = createFetchMock();
render(<MissionManager isOpen={true} onClose={vi.fn()} addToast={vi.fn()} />);
await waitFor(() => {
expect(screen.getByText("Build Auth System")).toBeInTheDocument();
});
const sidebar = screen.getByTestId("mission-sidebar");
fireEvent.click(within(sidebar).getByText("Build Auth System"));
await waitFor(() => {
expect(screen.getByTestId("mission-sidebar")).toBeInTheDocument();
expect(within(sidebar).getByText("API Redesign")).toBeInTheDocument();
expect(screen.getByTestId("mission-tab-structure")).toBeInTheDocument();
});
});
it("applies desktop class to shell on desktop viewport", async () => {
globalThis.fetch = createFetchMock();
render(<MissionManager isOpen={true} onClose={vi.fn()} addToast={vi.fn()} />);
await waitFor(() => {
const dialog = screen.getByTestId("mission-manager-dialog");
expect(dialog.className).toContain("mission-manager--desktop");
});
});
it("works in inline mode with split layout", async () => {
globalThis.fetch = createFetchMock();
render(<MissionManager isOpen={true} isInline={true} onClose={vi.fn()} addToast={vi.fn()} />);
await waitFor(() => {
const dialog = screen.getByTestId("mission-manager-dialog");
expect(dialog.className).toContain("mission-manager--inline");
expect(dialog.className).toContain("mission-manager--desktop");
expect(screen.getByTestId("mission-sidebar")).toBeInTheDocument();
});
});
});
});