import { describe, it, beforeEach, afterEach } from "node:test";
import assert from "node:assert";
import "../test-setup.ts";
import { createRoot, type Root } from "react-dom/client";
import { act } from "@testing-library/react";
import { CameraSelector } from "./CameraSelector.tsx";
import { useStore } from "../store/store.ts";
describe("CameraSelector", () => {
let container: HTMLDivElement;
let root: Root;
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
root = createRoot(container);
useStore.setState({
models: [],
selectedModelId: null,
cameraView: "perspective",
backdropUrl: null,
availableModels: [],
});
});
afterEach(() => {
act(() => {
root.unmount();
});
container.remove();
});
it("should render a dropdown", async () => {
await act(async () => {
root.render();
});
const select = container.querySelector("select.camera-selector");
assert.ok(select, "Should render a select dropdown");
});
it("should have perspective as default option", async () => {
await act(async () => {
root.render();
});
const select = container.querySelector(
"select.camera-selector",
) as HTMLSelectElement;
assert.strictEqual(select?.value, "perspective");
});
it("should have all camera view options", async () => {
await act(async () => {
root.render();
});
const options = container.querySelectorAll("select.camera-selector option");
const values = Array.from(options).map(
(opt) => (opt as HTMLOptionElement).value,
);
assert.ok(values.includes("perspective"), "Should have perspective option");
assert.ok(values.includes("ortho-top"), "Should have ortho-top option");
assert.ok(values.includes("ortho-front"), "Should have ortho-front option");
assert.ok(values.includes("ortho-side"), "Should have ortho-side option");
});
it("should update store when selection changes", async () => {
await act(async () => {
root.render();
});
const select = container.querySelector(
"select.camera-selector",
) as HTMLSelectElement;
await act(async () => {
select.value = "ortho-top";
select.dispatchEvent(new Event("change", { bubbles: true }));
});
assert.strictEqual(useStore.getState().cameraView, "ortho-top");
});
it("should be positioned as overlay", async () => {
await act(async () => {
root.render();
});
const wrapper = container.querySelector(".camera-selector-wrapper");
assert.ok(wrapper, "Should have wrapper for positioning");
});
it("should reflect store camera view state", async () => {
useStore.setState({ cameraView: "ortho-front" });
await act(async () => {
root.render();
});
const select = container.querySelector(
"select.camera-selector",
) as HTMLSelectElement;
assert.strictEqual(select?.value, "ortho-front");
});
});