aboutsummaryrefslogtreecommitdiff
path: root/src/components/CameraSelector.test.tsx
diff options
context:
space:
mode:
authorRuben Beltran del Rio <jj@r.bdr.sh>2026-01-30 11:31:24 +0100
committerRuben Beltran del Rio <jj@r.bdr.sh>2026-01-30 13:05:48 +0100
commit0d4b61993cba37c180ac91e40a0fb362711de8de (patch)
treef41dd68420b51766c1ca6fc1ee2c20dc5df830d1 /src/components/CameraSelector.test.tsx
Initial implementation
Diffstat (limited to 'src/components/CameraSelector.test.tsx')
-rw-r--r--src/components/CameraSelector.test.tsx107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/components/CameraSelector.test.tsx b/src/components/CameraSelector.test.tsx
new file mode 100644
index 0000000..90968b7
--- /dev/null
+++ b/src/components/CameraSelector.test.tsx
@@ -0,0 +1,107 @@
+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(<CameraSelector />);
+ });
+
+ 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(<CameraSelector />);
+ });
+
+ 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(<CameraSelector />);
+ });
+
+ 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(<CameraSelector />);
+ });
+
+ 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(<CameraSelector />);
+ });
+
+ 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(<CameraSelector />);
+ });
+
+ const select = container.querySelector(
+ "select.camera-selector",
+ ) as HTMLSelectElement;
+ assert.strictEqual(select?.value, "ortho-front");
+ });
+});