// @vitest-environment happy-dom import React, { act } from "react"; import { createRoot, type Root } from "react-dom/client"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { AppKeysPanel } from "./app-keys-popover"; const queryState = vi.hoisted(() => ({ refetchSecrets: vi.fn(), refetchGrants: vi.fn(), refetchAccess: vi.fn(), queryCalls: [] as Array<{ name: string; options?: { enabled?: boolean } }>, secretsError: new Error("Vault unavailable") as Error | null, })); const orgRoleState = vi.hoisted(() => ({ org: { orgId: "org_123" }, role: "owner" as "owner" | "admin" | "member", isLoading: false, error: null as Error | null, })); vi.mock("@agent-native/core/client/i18n", () => ({ useT: () => (key: string) => ({ "dispatch.pages.dataLoadFailed": "Couldn't load data", "dispatch.pages.dataLoadFailedDescription": "Dispatch couldn't load this data.", "dispatch.pages.tryAgain": "Try again", })[key] ?? key, })); vi.mock("@agent-native/core/client/hooks", () => ({ useActionQuery: ( name: string, _args?: unknown, options?: { enabled?: boolean }, ) => { queryState.queryCalls.push({ name, options }); const queries = { "list-vault-secret-options": { data: undefined, isLoading: false, error: queryState.secretsError, refetch: queryState.refetchSecrets, }, "list-vault-grants": { data: [], isLoading: false, error: null, refetch: queryState.refetchGrants, }, "get-vault-access-settings": { data: undefined, isLoading: false, error: null, refetch: queryState.refetchAccess, }, }; return queries[name as keyof typeof queries]; }, useActionMutation: () => ({ mutate: vi.fn(), isPending: false }), })); vi.mock("@agent-native/core/client/org", () => ({ useOrgRole: () => orgRoleState, })); describe("AppKeysPanel", () => { let container: HTMLDivElement; let root: Root; beforeEach(() => { vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true); vi.clearAllMocks(); queryState.queryCalls.length = 0; queryState.secretsError = new Error("Vault unavailable"); orgRoleState.role = "owner"; orgRoleState.isLoading = false; orgRoleState.error = null; container = document.createElement("div"); document.body.appendChild(container); root = createRoot(container); }); afterEach(() => { act(() => root.unmount()); container.remove(); vi.unstubAllGlobals(); }); it("shows a retryable error instead of an empty key list", () => { act(() => { root.render(); }); expect(container.textContent).toContain("Couldn't load data"); expect(container.textContent).toContain( "Dispatch couldn't load this data.", ); expect(container.textContent).not.toContain("Vault unavailable"); expect(container.textContent).not.toContain("No vault keys yet"); act(() => { container.querySelector("button")?.click(); }); expect(queryState.refetchSecrets).toHaveBeenCalledOnce(); expect(queryState.refetchGrants).toHaveBeenCalledOnce(); expect(queryState.refetchAccess).toHaveBeenCalledOnce(); }); it("does not request admin-only grants for workspace members", () => { orgRoleState.role = "member"; queryState.secretsError = null; act(() => { root.render( , ); }); const grantsQuery = queryState.queryCalls.find( (query) => query.name === "list-vault-grants", ); expect(grantsQuery?.options).toEqual({ enabled: false }); expect(container.textContent).toContain( "Only workspace owners and admins can manage keys.", ); expect(container.textContent).not.toContain("Couldn't load data"); }); it("requests grants for workspace owners", () => { queryState.secretsError = null; act(() => { root.render( , ); }); const grantsQuery = queryState.queryCalls.find( (query) => query.name === "list-vault-grants", ); expect(grantsQuery?.options).toEqual({ enabled: true }); }); });