diff options
| author | Ruben Beltran del Rio <jj@r.bdr.sh> | 2026-01-30 11:31:24 +0100 |
|---|---|---|
| committer | Ruben Beltran del Rio <jj@r.bdr.sh> | 2026-01-30 13:05:48 +0100 |
| commit | 0d4b61993cba37c180ac91e40a0fb362711de8de (patch) | |
| tree | f41dd68420b51766c1ca6fc1ee2c20dc5df830d1 /src/components/CameraSelector.test.tsx | |
Initial implementation
Diffstat (limited to 'src/components/CameraSelector.test.tsx')
| -rw-r--r-- | src/components/CameraSelector.test.tsx | 107 |
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"); + }); +}); |