mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 21:11:53 +00:00
test(ui): add tests for hooks, stores, and adapters
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { APPLY_STATUS, DiscoveryResult } from "@/types/organizations";
|
||||
|
||||
import {
|
||||
buildAccountLookup,
|
||||
buildOrgTreeData,
|
||||
getOuIdsForSelectedAccounts,
|
||||
getSelectableAccountIds,
|
||||
} from "./organizations.adapter";
|
||||
|
||||
const discoveryFixture: DiscoveryResult = {
|
||||
roots: [
|
||||
{
|
||||
id: "r-root",
|
||||
arn: "arn:aws:organizations::123:root/o-example/r-root",
|
||||
name: "Root",
|
||||
policy_types: [],
|
||||
},
|
||||
],
|
||||
organizational_units: [
|
||||
{
|
||||
id: "ou-parent",
|
||||
name: "Parent OU",
|
||||
arn: "arn:aws:organizations::123:ou/o-example/ou-parent",
|
||||
parent_id: "r-root",
|
||||
},
|
||||
{
|
||||
id: "ou-child",
|
||||
name: "Child OU",
|
||||
arn: "arn:aws:organizations::123:ou/o-example/ou-child",
|
||||
parent_id: "ou-parent",
|
||||
},
|
||||
],
|
||||
accounts: [
|
||||
{
|
||||
id: "111111111111",
|
||||
arn: "arn:aws:organizations::123:account/o-example/111111111111",
|
||||
name: "App Account",
|
||||
email: "app@example.com",
|
||||
status: "ACTIVE",
|
||||
joined_method: "CREATED",
|
||||
joined_timestamp: "2024-01-01T00:00:00Z",
|
||||
parent_id: "ou-child",
|
||||
registration: {
|
||||
provider_exists: false,
|
||||
provider_id: null,
|
||||
organization_relation: "link_required",
|
||||
organizational_unit_relation: "link_required",
|
||||
provider_secret_state: "will_create",
|
||||
apply_status: APPLY_STATUS.READY,
|
||||
blocked_reasons: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "222222222222",
|
||||
arn: "arn:aws:organizations::123:account/o-example/222222222222",
|
||||
name: "Security Account",
|
||||
email: "security@example.com",
|
||||
status: "ACTIVE",
|
||||
joined_method: "CREATED",
|
||||
joined_timestamp: "2024-01-01T00:00:00Z",
|
||||
parent_id: "ou-parent",
|
||||
registration: {
|
||||
provider_exists: false,
|
||||
provider_id: null,
|
||||
organization_relation: "link_required",
|
||||
organizational_unit_relation: "link_required",
|
||||
provider_secret_state: "manual_required",
|
||||
apply_status: APPLY_STATUS.BLOCKED,
|
||||
blocked_reasons: ["role_missing"],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "333333333333",
|
||||
arn: "arn:aws:organizations::123:account/o-example/333333333333",
|
||||
name: "Legacy Account",
|
||||
email: "legacy@example.com",
|
||||
status: "ACTIVE",
|
||||
joined_method: "INVITED",
|
||||
joined_timestamp: "2024-01-01T00:00:00Z",
|
||||
parent_id: "r-root",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe("buildOrgTreeData", () => {
|
||||
it("builds nested tree structure and marks blocked accounts as disabled", () => {
|
||||
// Given / When
|
||||
const treeData = buildOrgTreeData(discoveryFixture);
|
||||
|
||||
// Then
|
||||
expect(treeData).toHaveLength(2);
|
||||
expect(treeData.map((node) => node.id)).toEqual(
|
||||
expect.arrayContaining(["ou-parent", "333333333333"]),
|
||||
);
|
||||
|
||||
const parentOuNode = treeData.find((node) => node.id === "ou-parent");
|
||||
expect(parentOuNode).toBeDefined();
|
||||
expect(parentOuNode?.children?.map((node) => node.id)).toEqual(
|
||||
expect.arrayContaining(["ou-child", "222222222222"]),
|
||||
);
|
||||
|
||||
const blockedAccount = parentOuNode?.children?.find(
|
||||
(node) => node.id === "222222222222",
|
||||
);
|
||||
expect(blockedAccount?.disabled).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getSelectableAccountIds", () => {
|
||||
it("returns all accounts except explicitly blocked ones", () => {
|
||||
const selectableIds = getSelectableAccountIds(discoveryFixture);
|
||||
|
||||
expect(selectableIds).toEqual(["111111111111", "333333333333"]);
|
||||
});
|
||||
|
||||
it("excludes accounts with explicit non-ready status values", () => {
|
||||
const discoveryWithUnexpectedStatus = {
|
||||
...discoveryFixture,
|
||||
accounts: [
|
||||
...discoveryFixture.accounts,
|
||||
{
|
||||
id: "444444444444",
|
||||
arn: "arn:aws:organizations::123:account/o-example/444444444444",
|
||||
name: "Pending Account",
|
||||
email: "pending@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: "link_required",
|
||||
provider_secret_state: "will_create",
|
||||
apply_status: "pending" as unknown as APPLY_STATUS,
|
||||
blocked_reasons: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
} satisfies DiscoveryResult;
|
||||
|
||||
const selectableIds = getSelectableAccountIds(
|
||||
discoveryWithUnexpectedStatus,
|
||||
);
|
||||
|
||||
expect(selectableIds).toEqual(["111111111111", "333333333333"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildAccountLookup", () => {
|
||||
it("creates a lookup map for all discovered accounts", () => {
|
||||
const lookup = buildAccountLookup(discoveryFixture);
|
||||
|
||||
expect(lookup.get("111111111111")?.name).toBe("App Account");
|
||||
expect(lookup.get("333333333333")?.name).toBe("Legacy Account");
|
||||
expect(lookup.size).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getOuIdsForSelectedAccounts", () => {
|
||||
it("collects all ancestor OUs for selected accounts without duplicates", () => {
|
||||
const ouIds = getOuIdsForSelectedAccounts(discoveryFixture, [
|
||||
"111111111111",
|
||||
"222222222222",
|
||||
]);
|
||||
|
||||
expect(ouIds).toEqual(expect.arrayContaining(["ou-parent", "ou-child"]));
|
||||
expect(ouIds.length).toBe(2);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,193 @@
|
||||
import { act, renderHook } from "@testing-library/react";
|
||||
import { createElement, type PropsWithChildren, StrictMode } from "react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { useOrgSetupStore } from "@/store/organizations/store";
|
||||
import { APPLY_STATUS, DISCOVERY_STATUS } from "@/types/organizations";
|
||||
|
||||
import { useOrgSetupSubmission } from "./use-org-setup-submission";
|
||||
|
||||
const organizationsActionsMock = vi.hoisted(() => ({
|
||||
createOrganization: vi.fn(),
|
||||
createOrganizationSecret: vi.fn(),
|
||||
getDiscovery: vi.fn(),
|
||||
listOrganizationsByExternalId: vi.fn(),
|
||||
listOrganizationSecretsByOrganizationId: vi.fn(),
|
||||
triggerDiscovery: vi.fn(),
|
||||
updateOrganizationSecret: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock(
|
||||
"@/actions/organizations/organizations",
|
||||
() => organizationsActionsMock,
|
||||
);
|
||||
|
||||
function StrictModeWrapper({ children }: PropsWithChildren) {
|
||||
return createElement(StrictMode, null, children);
|
||||
}
|
||||
|
||||
describe("useOrgSetupSubmission", () => {
|
||||
beforeEach(() => {
|
||||
sessionStorage.clear();
|
||||
localStorage.clear();
|
||||
useOrgSetupStore.getState().reset();
|
||||
for (const mockFn of Object.values(organizationsActionsMock)) {
|
||||
mockFn.mockReset();
|
||||
}
|
||||
});
|
||||
|
||||
it("completes the setup chain and stores selectable accounts", async () => {
|
||||
// Given
|
||||
const onNext = vi.fn();
|
||||
const setFieldError = vi.fn();
|
||||
const discoveryResult = {
|
||||
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.BLOCKED,
|
||||
blocked_reasons: ["Already linked"],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
organizationsActionsMock.listOrganizationsByExternalId.mockResolvedValue({
|
||||
data: [],
|
||||
});
|
||||
organizationsActionsMock.createOrganization.mockResolvedValue({
|
||||
data: { id: "org-1" },
|
||||
});
|
||||
organizationsActionsMock.listOrganizationSecretsByOrganizationId.mockResolvedValue(
|
||||
{
|
||||
data: [],
|
||||
},
|
||||
);
|
||||
organizationsActionsMock.createOrganizationSecret.mockResolvedValue({
|
||||
data: { id: "secret-1" },
|
||||
});
|
||||
organizationsActionsMock.triggerDiscovery.mockResolvedValue({
|
||||
data: { id: "discovery-1" },
|
||||
});
|
||||
organizationsActionsMock.getDiscovery.mockResolvedValue({
|
||||
data: {
|
||||
attributes: {
|
||||
status: DISCOVERY_STATUS.SUCCEEDED,
|
||||
result: discoveryResult,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useOrgSetupSubmission({
|
||||
stackSetExternalId: "tenant-external-id",
|
||||
onNext,
|
||||
setFieldError,
|
||||
}),
|
||||
{ wrapper: StrictModeWrapper },
|
||||
);
|
||||
|
||||
// When
|
||||
await act(async () => {
|
||||
await result.current.submitOrganizationSetup({
|
||||
organizationName: "Acme",
|
||||
awsOrgId: "o-abc123def4",
|
||||
roleArn: "arn:aws:iam::123456789012:role/ProwlerOrgRole",
|
||||
});
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(onNext).toHaveBeenCalledTimes(1);
|
||||
expect(setFieldError).not.toHaveBeenCalled();
|
||||
|
||||
const state = useOrgSetupStore.getState();
|
||||
expect(state.organizationId).toBe("org-1");
|
||||
expect(state.organizationExternalId).toBe("o-abc123def4");
|
||||
expect(state.discoveryId).toBe("discovery-1");
|
||||
expect(state.selectedAccountIds).toEqual(["111111111111"]);
|
||||
expect(state.selectableAccountIds).toEqual(["111111111111"]);
|
||||
});
|
||||
|
||||
it("maps external_id server errors to awsOrgId field errors", async () => {
|
||||
// Given
|
||||
const onNext = vi.fn();
|
||||
const setFieldError = vi.fn();
|
||||
organizationsActionsMock.listOrganizationsByExternalId.mockResolvedValue({
|
||||
data: [],
|
||||
});
|
||||
organizationsActionsMock.createOrganization.mockResolvedValue({
|
||||
errors: [
|
||||
{
|
||||
detail: "Organization with this external_id already exists.",
|
||||
source: { pointer: "/data/attributes/external_id" },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useOrgSetupSubmission({
|
||||
stackSetExternalId: "tenant-external-id",
|
||||
onNext,
|
||||
setFieldError,
|
||||
}),
|
||||
);
|
||||
|
||||
// When
|
||||
await act(async () => {
|
||||
await result.current.submitOrganizationSetup({
|
||||
organizationName: "Acme",
|
||||
awsOrgId: "o-abc123def4",
|
||||
roleArn: "arn:aws:iam::123456789012:role/ProwlerOrgRole",
|
||||
});
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(setFieldError).toHaveBeenCalledWith(
|
||||
"awsOrgId",
|
||||
"Organization with this external_id already exists.",
|
||||
);
|
||||
expect(result.current.apiError).toBe(
|
||||
"Organization with this external_id already exists.",
|
||||
);
|
||||
expect(onNext).not.toHaveBeenCalled();
|
||||
expect(
|
||||
organizationsActionsMock.createOrganizationSecret,
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
import { act, render, waitFor } from "@testing-library/react";
|
||||
import type { ComponentProps } from "react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { useOrgSetupStore } from "@/store/organizations/store";
|
||||
|
||||
import { OrgLaunchScan } from "./org-launch-scan";
|
||||
|
||||
const { launchOrganizationScansMock, pushMock, toastMock } = vi.hoisted(() => ({
|
||||
launchOrganizationScansMock: vi.fn(),
|
||||
pushMock: vi.fn(),
|
||||
toastMock: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/actions/scans/scans", () => ({
|
||||
launchOrganizationScans: launchOrganizationScansMock,
|
||||
}));
|
||||
|
||||
vi.mock("next/navigation", () => ({
|
||||
useRouter: () => ({
|
||||
push: pushMock,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("@/components/ui", () => ({
|
||||
ToastAction: ({ children, ...props }: ComponentProps<"button">) => (
|
||||
<button {...props}>{children}</button>
|
||||
),
|
||||
useToast: () => ({
|
||||
toast: toastMock,
|
||||
}),
|
||||
}));
|
||||
|
||||
describe("OrgLaunchScan", () => {
|
||||
beforeEach(() => {
|
||||
sessionStorage.clear();
|
||||
localStorage.clear();
|
||||
launchOrganizationScansMock.mockReset();
|
||||
pushMock.mockReset();
|
||||
toastMock.mockReset();
|
||||
useOrgSetupStore.getState().reset();
|
||||
useOrgSetupStore
|
||||
.getState()
|
||||
.setOrganization("org-1", "My Organization", "o-abc123def4");
|
||||
useOrgSetupStore.getState().setCreatedProviderIds(["provider-1"]);
|
||||
});
|
||||
|
||||
it("shows a success toast with an action linking to scans", async () => {
|
||||
// Given
|
||||
launchOrganizationScansMock.mockResolvedValue({ successCount: 1 });
|
||||
const onFooterChange = vi.fn();
|
||||
|
||||
render(
|
||||
<OrgLaunchScan
|
||||
onClose={vi.fn()}
|
||||
onBack={vi.fn()}
|
||||
onFooterChange={onFooterChange}
|
||||
/>,
|
||||
);
|
||||
|
||||
// When
|
||||
await waitFor(() => {
|
||||
expect(onFooterChange).toHaveBeenCalled();
|
||||
});
|
||||
const footerConfig = onFooterChange.mock.calls.at(-1)?.[0];
|
||||
await act(async () => {
|
||||
footerConfig.onAction?.();
|
||||
});
|
||||
|
||||
// Then
|
||||
await waitFor(() => {
|
||||
expect(toastMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
const toastPayload = toastMock.mock.calls[0]?.[0];
|
||||
expect(toastPayload.title).toBe("Scan Launched");
|
||||
expect(toastPayload.action).toBeDefined();
|
||||
expect(toastPayload.action.props.children.props.href).toBe("/scans");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,188 @@
|
||||
import { act, renderHook, waitFor } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { useOrgSetupStore } from "@/store/organizations/store";
|
||||
import { useProviderWizardStore } from "@/store/provider-wizard/store";
|
||||
import { ORG_WIZARD_STEP } from "@/types/organizations";
|
||||
import {
|
||||
PROVIDER_WIZARD_MODE,
|
||||
PROVIDER_WIZARD_STEP,
|
||||
} from "@/types/provider-wizard";
|
||||
|
||||
import { useProviderWizardController } from "./use-provider-wizard-controller";
|
||||
|
||||
const { pushMock } = vi.hoisted(() => ({
|
||||
pushMock: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("next/navigation", () => ({
|
||||
useRouter: () => ({
|
||||
push: pushMock,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("next-auth/react", () => ({
|
||||
useSession: () => ({
|
||||
data: null,
|
||||
status: "unauthenticated",
|
||||
}),
|
||||
}));
|
||||
|
||||
describe("useProviderWizardController", () => {
|
||||
beforeEach(() => {
|
||||
sessionStorage.clear();
|
||||
localStorage.clear();
|
||||
pushMock.mockReset();
|
||||
useProviderWizardStore.getState().reset();
|
||||
useOrgSetupStore.getState().reset();
|
||||
});
|
||||
|
||||
it("hydrates update mode when initial data is provided", async () => {
|
||||
// Given
|
||||
const onOpenChange = vi.fn();
|
||||
|
||||
// When
|
||||
const { result } = renderHook(() =>
|
||||
useProviderWizardController({
|
||||
open: true,
|
||||
onOpenChange,
|
||||
initialData: {
|
||||
providerId: "provider-1",
|
||||
providerType: "aws",
|
||||
providerUid: "111111111111",
|
||||
providerAlias: "production",
|
||||
secretId: "secret-1",
|
||||
mode: PROVIDER_WIZARD_MODE.UPDATE,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
// Then
|
||||
await waitFor(() => {
|
||||
expect(result.current.currentStep).toBe(PROVIDER_WIZARD_STEP.CREDENTIALS);
|
||||
});
|
||||
expect(result.current.modalTitle).toBe("Update Provider Credentials");
|
||||
expect(result.current.isProviderFlow).toBe(true);
|
||||
expect(result.current.docsLink).toBe(
|
||||
"https://goto.prowler.com/provider-aws",
|
||||
);
|
||||
|
||||
const state = useProviderWizardStore.getState();
|
||||
expect(state.providerId).toBe("provider-1");
|
||||
expect(state.providerType).toBe("aws");
|
||||
expect(state.providerUid).toBe("111111111111");
|
||||
expect(state.providerAlias).toBe("production");
|
||||
expect(state.secretId).toBe("secret-1");
|
||||
expect(state.mode).toBe(PROVIDER_WIZARD_MODE.UPDATE);
|
||||
});
|
||||
|
||||
it("switches into and out of organizations flow", () => {
|
||||
// Given
|
||||
const onOpenChange = vi.fn();
|
||||
const { result } = renderHook(() =>
|
||||
useProviderWizardController({
|
||||
open: true,
|
||||
onOpenChange,
|
||||
}),
|
||||
);
|
||||
|
||||
// When
|
||||
act(() => {
|
||||
result.current.openOrganizationsFlow();
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(result.current.wizardVariant).toBe("organizations");
|
||||
expect(result.current.isProviderFlow).toBe(false);
|
||||
expect(result.current.orgCurrentStep).toBe(ORG_WIZARD_STEP.SETUP);
|
||||
|
||||
// When
|
||||
act(() => {
|
||||
result.current.backToProviderFlow();
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(result.current.wizardVariant).toBe("provider");
|
||||
expect(result.current.isProviderFlow).toBe(true);
|
||||
expect(result.current.currentStep).toBe(PROVIDER_WIZARD_STEP.CONNECT);
|
||||
});
|
||||
|
||||
it("moves to launch step after a successful connection test in add mode", () => {
|
||||
// Given
|
||||
const onOpenChange = vi.fn();
|
||||
const { result } = renderHook(() =>
|
||||
useProviderWizardController({
|
||||
open: true,
|
||||
onOpenChange,
|
||||
}),
|
||||
);
|
||||
|
||||
// When
|
||||
act(() => {
|
||||
result.current.setCurrentStep(PROVIDER_WIZARD_STEP.TEST);
|
||||
result.current.handleTestSuccess();
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(result.current.currentStep).toBe(PROVIDER_WIZARD_STEP.LAUNCH);
|
||||
expect(onOpenChange).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("closes and navigates when launch footer action is triggered", () => {
|
||||
// Given
|
||||
const onOpenChange = vi.fn();
|
||||
const { result } = renderHook(() =>
|
||||
useProviderWizardController({
|
||||
open: true,
|
||||
onOpenChange,
|
||||
}),
|
||||
);
|
||||
|
||||
// When
|
||||
act(() => {
|
||||
result.current.setCurrentStep(PROVIDER_WIZARD_STEP.LAUNCH);
|
||||
});
|
||||
|
||||
const { resolvedFooterConfig } = result.current;
|
||||
act(() => {
|
||||
resolvedFooterConfig.onAction?.();
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(pushMock).toHaveBeenCalledWith("/scans");
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false);
|
||||
expect(result.current.currentStep).toBe(PROVIDER_WIZARD_STEP.CONNECT);
|
||||
});
|
||||
|
||||
it("does not reset organizations step when org store updates while modal is open", () => {
|
||||
// Given
|
||||
const onOpenChange = vi.fn();
|
||||
const { result } = renderHook(() =>
|
||||
useProviderWizardController({
|
||||
open: true,
|
||||
onOpenChange,
|
||||
}),
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.openOrganizationsFlow();
|
||||
result.current.setOrgCurrentStep(ORG_WIZARD_STEP.VALIDATE);
|
||||
});
|
||||
|
||||
// When
|
||||
act(() => {
|
||||
useOrgSetupStore
|
||||
.getState()
|
||||
.setOrganization("org-1", "My Org", "o-abc123def4");
|
||||
useOrgSetupStore.getState().setDiscovery("disc-1", {
|
||||
roots: [],
|
||||
organizational_units: [],
|
||||
accounts: [],
|
||||
});
|
||||
});
|
||||
|
||||
// Then
|
||||
expect(result.current.wizardVariant).toBe("organizations");
|
||||
expect(result.current.orgCurrentStep).toBe(ORG_WIZARD_STEP.VALIDATE);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { useOrgSetupStore } from "./store";
|
||||
|
||||
describe("useOrgSetupStore", () => {
|
||||
beforeEach(() => {
|
||||
sessionStorage.clear();
|
||||
localStorage.clear();
|
||||
useOrgSetupStore.getState().reset();
|
||||
});
|
||||
|
||||
it("persists organization wizard state in sessionStorage", () => {
|
||||
// Given
|
||||
useOrgSetupStore
|
||||
.getState()
|
||||
.setOrganization("org-1", "My Org", "o-abc123def4");
|
||||
useOrgSetupStore.getState().setDiscovery("discovery-1", {
|
||||
roots: [],
|
||||
organizational_units: [],
|
||||
accounts: [],
|
||||
});
|
||||
useOrgSetupStore
|
||||
.getState()
|
||||
.setSelectedAccountIds(["111111111111", "222222222222"]);
|
||||
|
||||
// When
|
||||
const persistedValue = sessionStorage.getItem("org-setup-store");
|
||||
|
||||
// Then
|
||||
expect(persistedValue).toBeTruthy();
|
||||
expect(localStorage.getItem("org-setup-store")).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -1,13 +1,17 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { PROVIDER_WIZARD_MODE } from "@/types/provider-wizard";
|
||||
|
||||
import { useProviderWizardStore } from "./store";
|
||||
|
||||
describe("useProviderWizardStore", () => {
|
||||
it("stores provider identity and mode, then resets to defaults", () => {
|
||||
beforeEach(() => {
|
||||
sessionStorage.clear();
|
||||
localStorage.clear();
|
||||
useProviderWizardStore.getState().reset();
|
||||
});
|
||||
|
||||
it("stores provider identity and mode, then resets to defaults", () => {
|
||||
useProviderWizardStore.getState().setProvider({
|
||||
id: "provider-1",
|
||||
type: "aws",
|
||||
@@ -38,4 +42,21 @@ describe("useProviderWizardStore", () => {
|
||||
expect(afterReset.secretId).toBeNull();
|
||||
expect(afterReset.mode).toBe(PROVIDER_WIZARD_MODE.ADD);
|
||||
});
|
||||
|
||||
it("persists provider wizard state in sessionStorage", () => {
|
||||
// Given
|
||||
useProviderWizardStore.getState().setProvider({
|
||||
id: "provider-1",
|
||||
type: "aws",
|
||||
uid: "123456789012",
|
||||
alias: "prod-account",
|
||||
});
|
||||
|
||||
// When
|
||||
const persistedValue = sessionStorage.getItem("provider-wizard-store");
|
||||
|
||||
// Then
|
||||
expect(persistedValue).toBeTruthy();
|
||||
expect(localStorage.getItem("provider-wizard-store")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user