import type { ReactNode } from "react";
import { describe, expect, it } from "vitest";
import { render as rtlRender, screen, type RenderOptions } from "@testing-library/react";
import { ONBOARDING_STEP_ORDER } from "@multica/core/onboarding";
import { I18nProvider } from "@multica/core/i18n/react";
import enCommon from "../../locales/en/common.json";
import enOnboarding from "../../locales/en/onboarding.json";
import { StepHeader } from "./step-header";
const TEST_RESOURCES = {
en: { common: enCommon, onboarding: enOnboarding },
};
function I18nWrapper({ children }: { children: ReactNode }) {
return (
{children}
);
}
function render(ui: React.ReactElement, options?: RenderOptions) {
return rtlRender(ui, { wrapper: I18nWrapper, ...options });
}
describe("StepHeader", () => {
it("renders one dot per step in ONBOARDING_STEP_ORDER", () => {
const { container } = render();
const dots = container.querySelectorAll('[aria-hidden="true"]');
expect(dots).toHaveLength(ONBOARDING_STEP_ORDER.length);
});
it("shows 'Step N of M' text matching the current step's position", () => {
// workspace is index 1 (after about_you) → Step 2.
render();
expect(
screen.getByText(`Step 2 of ${ONBOARDING_STEP_ORDER.length}`),
).toBeInTheDocument();
});
it("sets accessible progressbar attrs", () => {
render();
const bar = screen.getByRole("progressbar");
expect(bar).toHaveAttribute("aria-valuenow", "3"); // runtime is index 2 → step 3
expect(bar).toHaveAttribute("aria-valuemax", String(ONBOARDING_STEP_ORDER.length));
});
it("falls back to step 1 when given an unknown step", () => {
// TS would normally prevent this, but at runtime the store enum and
// the flow's local step could drift during a refactor — the header
// must not crash. Assert the defensive fallback lands on step 1.
render();
expect(
screen.getByText(`Step 1 of ${ONBOARDING_STEP_ORDER.length}`),
).toBeInTheDocument();
});
});