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>
44 lines
1.5 KiB
TypeScript
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);
|
|
});
|
|
});
|