import { cleanup, render, waitFor } from "@testing-library/react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { encodeToolcraftModelDocument } from "../../model-import/canonical/model-document-codec"; import { createValidModelDocument } from "../../model-import/canonical/model-document-test-support"; import { createHydrationModelAsset } from "../../model-import/model-persistence-hydration-test-support"; import { defineToolcraft } from "../../schema/define-toolcraft"; import { ToolcraftRoot } from "../app-shell/toolcraft-root"; import type { ToolcraftModelRenderBinding } from "./model-render-binding"; import { ToolcraftModelCanvasLayers } from "./model-canvas-layer"; import { ToolcraftModelRenderProvider } from "./model-render-provider"; type TestResource = { id: number }; function createBinding(): ToolcraftModelRenderBinding { let sequence = 0; return { create: vi.fn(() => ({ id: ++sequence })), dispose: vi.fn(), disposePreparedPreview: vi.fn(), hitTest: vi.fn(() => true), preparePreview: vi.fn(), renderExport: vi.fn(), renderPreview: vi.fn(), update: vi.fn(), }; } afterEach(() => { cleanup(); }); describe("ToolcraftModelCanvasLayer infinite canvas", () => { it("uses each model frame as the render and orbit surface in infinite mode", async () => { const binding = createBinding(); const bytes = encodeToolcraftModelDocument(createValidModelDocument()); const schema = defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: {}, }, modules: [], }); const view = render( bytes} standardBinding={createBinding()} > , ); const layer = await waitFor(() => { const element = view.container.querySelector( '[data-canvas-model-layer="layer-1"]', ); expect(element).not.toBeNull(); return element as HTMLElement; }); expect(layer.style.left).toBe("-70px"); expect(layer.style.top).toBe("-140px"); expect(layer.style.width).toBe("300px"); expect(layer.style.height).toBe("200px"); await waitFor(() => expect(binding.create).toHaveBeenCalledWith( expect.objectContaining({ displayFit: expect.objectContaining({ viewport: { height: 200, width: 300 }, }), }), expect.anything(), ), ); }); });