test(ui): add account selection flow and component tests

This commit is contained in:
alejandrobailo
2026-02-24 13:01:04 +01:00
parent 38bb2f1e36
commit dd76aeea07
2 changed files with 208 additions and 0 deletions
@@ -0,0 +1,128 @@
import { act, renderHook, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { useOrgSetupStore } from "@/store/organizations/store";
import { APPLY_STATUS } from "@/types/organizations";
import { useOrgAccountSelectionFlow } from "./use-org-account-selection-flow";
const organizationsActionsMock = vi.hoisted(() => ({
applyDiscovery: vi.fn(),
}));
const providersActionsMock = vi.hoisted(() => ({
checkConnectionProvider: vi.fn(),
getProvider: vi.fn(),
}));
vi.mock("@/actions/organizations/organizations", () => organizationsActionsMock);
vi.mock("@/actions/providers/providers", () => providersActionsMock);
describe("useOrgAccountSelectionFlow", () => {
beforeEach(() => {
sessionStorage.clear();
localStorage.clear();
useOrgSetupStore.getState().reset();
organizationsActionsMock.applyDiscovery.mockReset();
useOrgSetupStore
.getState()
.setOrganization("org-1", "My Organization", "o-abc123def4");
useOrgSetupStore.getState().setDiscovery("discovery-1", {
roots: [
{ id: "r-root", arn: "arn:root", name: "Root", policy_types: [] },
],
organizational_units: [],
accounts: [
{
id: "111111111111",
name: "Account One",
arn: "arn:aws:organizations::111111111111:account/o-123/111111111111",
email: "one@example.com",
status: "ACTIVE",
joined_method: "CREATED",
joined_timestamp: "2024-01-01T00:00:00Z",
parent_id: "r-root",
registration: {
provider_exists: false,
provider_id: null,
organization_relation: "link_required",
organizational_unit_relation: "not_applicable",
provider_secret_state: "will_create",
apply_status: APPLY_STATUS.READY,
blocked_reasons: [],
},
},
{
id: "222222222222",
name: "Account Two",
arn: "arn:aws:organizations::222222222222:account/o-123/222222222222",
email: "two@example.com",
status: "ACTIVE",
joined_method: "CREATED",
joined_timestamp: "2024-01-01T00:00:00Z",
parent_id: "r-root",
registration: {
provider_exists: false,
provider_id: null,
organization_relation: "link_required",
organizational_unit_relation: "not_applicable",
provider_secret_state: "will_create",
apply_status: APPLY_STATUS.READY,
blocked_reasons: [],
},
},
],
});
useOrgSetupStore.getState().setSelectedAccountIds(["111111111111"]);
});
it("keeps Test Connections action visible after reselection in testing view", async () => {
// Given
organizationsActionsMock.applyDiscovery.mockResolvedValue({
errors: [{ detail: "Apply failed." }],
});
const onFooterChange = vi.fn();
let latestFooterConfig: {
showAction?: boolean;
actionDisabled?: boolean;
onAction?: () => void;
} | null = null;
onFooterChange.mockImplementation((config) => {
latestFooterConfig = config;
});
const { result } = renderHook(() =>
useOrgAccountSelectionFlow({
onBack: vi.fn(),
onNext: vi.fn(),
onSkip: vi.fn(),
onFooterChange,
}),
);
// When
await waitFor(() => {
expect(latestFooterConfig?.showAction).toBe(true);
expect(latestFooterConfig?.onAction).toBeDefined();
});
act(() => {
latestFooterConfig?.onAction?.();
});
await waitFor(() => {
expect(organizationsActionsMock.applyDiscovery).toHaveBeenCalledTimes(1);
});
act(() => {
result.current.handleTreeSelectionChange(["222222222222"]);
});
// Then
await waitFor(() => {
expect(latestFooterConfig?.showAction).toBe(true);
expect(latestFooterConfig?.actionDisabled).toBe(false);
expect(latestFooterConfig?.onAction).toBeDefined();
});
});
});
@@ -0,0 +1,80 @@
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { OrgAccountSelection } from "./org-account-selection";
const { useOrgAccountSelectionFlowMock, handleTreeSelectionChangeMock } =
vi.hoisted(() => ({
useOrgAccountSelectionFlowMock: vi.fn(),
handleTreeSelectionChangeMock: vi.fn(),
}));
vi.mock("./hooks/use-org-account-selection-flow", () => ({
useOrgAccountSelectionFlow: useOrgAccountSelectionFlowMock,
}));
vi.mock("@/components/shadcn/tree-view", () => ({
TreeView: ({
onSelectionChange,
}: {
onSelectionChange?: (ids: string[]) => void;
}) => (
<button onClick={() => onSelectionChange?.(["222222222222"])}>
trigger-tree-selection
</button>
),
}));
describe("OrgAccountSelection", () => {
beforeEach(() => {
useOrgAccountSelectionFlowMock.mockReset();
handleTreeSelectionChangeMock.mockReset();
useOrgAccountSelectionFlowMock.mockReturnValue({
accountAliases: {},
accountLookup: {},
applyError: null,
canAdvanceToLaunch: false,
discoveryResult: {
roots: [],
organizational_units: [],
accounts: [],
},
handleTreeSelectionChange: handleTreeSelectionChangeMock,
hasConnectionErrors: true,
isTesting: false,
isTestingView: true,
isSelectionLocked: false,
organizationExternalId: "o-abc123def4",
selectedCount: 1,
selectedIdsForTree: ["111111111111"],
setAccountAlias: vi.fn(),
showHeaderHelperText: true,
totalAccounts: 2,
treeDataWithConnectionState: [],
});
});
it("allows changing account selection after finishing connection tests", async () => {
// Given
const user = userEvent.setup();
render(
<OrgAccountSelection
onBack={vi.fn()}
onNext={vi.fn()}
onSkip={vi.fn()}
onFooterChange={vi.fn()}
/>,
);
// When
await user.click(
screen.getByRole("button", { name: "trigger-tree-selection" }),
);
// Then
expect(handleTreeSelectionChangeMock).toHaveBeenCalledWith([
"222222222222",
]);
});
});