Files
fusion/packages/dashboard/app/hooks/__tests__/useAuthTokenRecovery.test.ts
gsxdsm 0ff60a79d1 FN-7243: focus auth token recovery on unauthorized
Focus daemon authorization failures on auth-token recovery instead of engine remediation.

- Pass auth-token recovery state into dashboard banners so engine unavailable and status remediation banners stay hidden while recovery is open.
- Improve auth recovery dialog focus styling and tests for unauthorized daemon responses.
- Add release notes for focused auth-token recovery behavior.

Files changed:
 .changeset/auth-token-recovery-focus.md            |   7 ++
 .changeset/fn-7243-auth-recovery-banner.md         |   7 ++
 packages/dashboard/app/App.tsx                     |   1 +
 packages/dashboard/app/__tests__/auth.test.ts      |  31 ++++-
 .../app/components/AuthTokenRecoveryDialog.css     |   7 +-
 .../__tests__/AuthTokenRecoveryDialog.test.tsx     |  41 +++++-
 .../app/components/dashboard/DashboardBanners.tsx  |  14 ++-
 .../dashboard/__tests__/DashboardBanners.test.tsx  | 138 ++++++++++++++++++++-
 .../dashboard/app/components/dashboard/types.ts    |   1 +
 .../hooks/__tests__/useAuthTokenRecovery.test.ts   |   9 +-
 10 files changed, 238 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-7243

Fusion-Task-Lineage: 8292080d-a310-4fdc-9b5f-baa17a592bad

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-29 15:34:06 -07:00

44 lines
1.5 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
import { renderHook, act } from "@testing-library/react";
import { AUTH_TOKEN_RECOVERY_REQUIRED_EVENT } from "../../auth";
import { useAuthTokenRecovery } from "../useAuthTokenRecovery";
describe("useAuthTokenRecovery", () => {
afterEach(() => {
vi.restoreAllMocks();
});
it("opens on daemon auth-failure events and stays open for duplicate signals", () => {
const { result } = renderHook(() => useAuthTokenRecovery());
expect(result.current.open).toBe(false);
act(() => {
window.dispatchEvent(new Event(AUTH_TOKEN_RECOVERY_REQUIRED_EVENT));
});
expect(result.current.open).toBe(true);
act(() => {
window.dispatchEvent(new Event(AUTH_TOKEN_RECOVERY_REQUIRED_EVENT));
window.dispatchEvent(new Event(AUTH_TOKEN_RECOVERY_REQUIRED_EVENT));
});
expect(result.current.open).toBe(true);
});
it("removes the daemon auth-failure listener on unmount", () => {
const addSpy = vi.spyOn(window, "addEventListener");
const removeSpy = vi.spyOn(window, "removeEventListener");
const { unmount } = renderHook(() => useAuthTokenRecovery());
const addedCall = addSpy.mock.calls.find(
([type]) => type === AUTH_TOKEN_RECOVERY_REQUIRED_EVENT,
);
expect(addedCall).toBeTruthy();
const addedHandler = addedCall![1] as EventListener;
unmount();
expect(removeSpy).toHaveBeenCalledWith(AUTH_TOKEN_RECOVERY_REQUIRED_EVENT, addedHandler);
});
});