aboutsummaryrefslogtreecommitdiff
path: root/src/components/Sidebar.test.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/Sidebar.test.tsx')
-rw-r--r--src/components/Sidebar.test.tsx104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/components/Sidebar.test.tsx b/src/components/Sidebar.test.tsx
new file mode 100644
index 0000000..c85d0a6
--- /dev/null
+++ b/src/components/Sidebar.test.tsx
@@ -0,0 +1,104 @@
+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 { Sidebar } from "./Sidebar.tsx";
+import { useStore } from "../store/store.ts";
+
+describe("Sidebar", () => {
+ 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: [
+ { id: "servbot", name: "Servbot", url: "/models/servbot.gltf" },
+ { id: "megaman", name: "Megaman", url: "/models/megaman_volnutt.gltf" },
+ { id: "tron", name: "Tron Bonne", url: "/models/tron_bonne.gltf" },
+ ],
+ });
+ });
+
+ afterEach(() => {
+ act(() => {
+ root.unmount();
+ });
+ container.remove();
+ });
+
+ it("should render available models list", async () => {
+ await act(async () => {
+ root.render(<Sidebar />);
+ });
+
+ const sidebar = container.querySelector(".sidebar");
+ assert.ok(sidebar, "Sidebar should be rendered");
+
+ const modelItems = container.querySelectorAll(".model-item");
+ assert.strictEqual(modelItems.length, 3, "Should render 3 model items");
+ });
+
+ it("should display model names", async () => {
+ await act(async () => {
+ root.render(<Sidebar />);
+ });
+
+ const modelNames = container.querySelectorAll(".model-name");
+ const names = Array.from(modelNames).map((item) => item.textContent);
+
+ assert.ok(names.includes("Servbot"), "Should display Servbot");
+ assert.ok(names.includes("Megaman"), "Should display Megaman");
+ assert.ok(names.includes("Tron Bonne"), "Should display Tron Bonne");
+ });
+
+ it("should have Add buttons for each model", async () => {
+ await act(async () => {
+ root.render(<Sidebar />);
+ });
+
+ const addButtons = container.querySelectorAll(".add-model-btn");
+ assert.strictEqual(addButtons.length, 3, "Should have 3 Add buttons");
+
+ addButtons.forEach((btn) => {
+ assert.strictEqual(btn.textContent, "Add", 'Button should say "Add"');
+ });
+ });
+
+ it("should add model to scene when Add button is clicked", async () => {
+ await act(async () => {
+ root.render(<Sidebar />);
+ });
+
+ const addButtons = container.querySelectorAll(".add-model-btn");
+ const firstAddButton = addButtons[0] as HTMLButtonElement;
+
+ await act(async () => {
+ firstAddButton.click();
+ });
+
+ const models = useStore.getState().models;
+ assert.strictEqual(models.length, 1, "Should have 1 model in scene");
+ assert.strictEqual(models[0].sourceId, "servbot", "Should be a servbot");
+ });
+
+ it("should have a title", async () => {
+ await act(async () => {
+ root.render(<Sidebar />);
+ });
+
+ const title = container.querySelector(".sidebar-title");
+ assert.ok(title, "Should have a title");
+ assert.ok(
+ title?.textContent?.includes("Models"),
+ 'Title should contain "Models"',
+ );
+ });
+});