1import { Children, isValidElement, type ReactElement } from "react";
2import { describe, expect, it, vi } from "vite-plus/test";
3
4import { WizardSteps } from "../ui/wizard";
5import { ADD_PROVIDER_WIZARD_STEPS } from "./AddProviderInstanceDialog.logic";
6import { AddProviderInstanceWizardSteps } from "./AddProviderInstanceWizardSteps";
7
8interface StepButtonProps {
9 readonly "aria-current"?: string;
10 readonly onClick: () => void;
11}
12
13interface StepListItemProps {
14 readonly children: ReactElement<StepButtonProps>;
15}
16
17function renderStepButtons(
18 currentStep: number,
19 instanceIdError: string | null,
20 onNavigation: Parameters<typeof AddProviderInstanceWizardSteps>[0]["onNavigation"],
21): ReactElement<StepButtonProps>[] {
22 const header = AddProviderInstanceWizardSteps({
23 currentStep,
24 summaries: ["Codex", "Codex Workspace", null],
25 instanceIdError,
26 onNavigation,
27 });
28
29 return Children.toArray(WizardSteps(header.props).props.children)
30 .filter((child): child is ReactElement<StepListItemProps> => isValidElement(child))
31 .map((item) => item.props.children);
32}
33
34describe("AddProviderInstanceWizardSteps", () => {
35 it("gates the actual Config header click through Identity validation", () => {
36 const onNavigation = vi.fn();
37 const buttons = renderStepButtons(0, "Instance ID is required.", onNavigation);
38
39 expect(buttons).toHaveLength(ADD_PROVIDER_WIZARD_STEPS.length);
40 buttons[2]!.props.onClick();
41
42 expect(onNavigation).toHaveBeenCalledOnce();
43 expect(onNavigation).toHaveBeenCalledWith({
44 kind: "blocked",
45 step: 1,
46 error: "Instance ID is required.",
47 });
48 });
49
50 it("marks the wizard step separately from the clicked button focus", () => {
51 const buttons = renderStepButtons(1, "Instance ID is required.", vi.fn());
52
53 expect(buttons[0]!.props["aria-current"]).toBeUndefined();
54 expect(buttons[1]!.props["aria-current"]).toBe("step");
55 expect(buttons[2]!.props["aria-current"]).toBeUndefined();
56 });
57
58 it("preserves the actual backward header click", () => {
59 const onNavigation = vi.fn();
60 const buttons = renderStepButtons(2, "Instance ID is required.", onNavigation);
61
62 buttons[0]!.props.onClick();
63
64 expect(onNavigation).toHaveBeenCalledWith({ kind: "navigate", step: 0 });
65 });
66});