import assert from "node:assert/strict"; import test from "node:test"; import { createMapWorkspaceState, mapWorkspaceReducer } from "../apps/catalog/src/mapWorkspaceState.mjs"; const rect = (x, y, width = 280, height = 260) => ({ x, y, width, height }); const subjectStates = { positions: { bindingId: "positions", visible: true, filters: {}, window: { open: false, rect: rect(24, 56), maximized: false, zIndex: 20 }, }, zones: { bindingId: "zones", visible: true, filters: {}, window: { open: false, rect: rect(52, 84), maximized: false, zIndex: 21 }, }, }; function initialState() { return createMapWorkspaceState({ subjectStates: structuredClone(subjectStates), sectorWindowRect: rect(24, 72, 380, 530), subjectCardRect: rect(940, 72, 390, 520), }); } test("one reducer owns the complete floating-window stack", () => { const opened = mapWorkspaceReducer(initialState(), { type: "open-subject-window", bindingId: "positions" }); assert.equal(opened.subjectStates.positions.window.open, true); assert.equal(opened.activeWindowId, "binding:positions"); assert.ok(opened.subjectStates.positions.window.zIndex > opened.sector.window.zIndex); const activatedCard = mapWorkspaceReducer(opened, { type: "select-entity", entityId: "nodedc-runtime:positions:map.moving_object:unit-1", validTabIds: ["overview", "position"], defaultTabId: "overview", }); assert.equal(activatedCard.subjectCard.open, true); assert.equal(activatedCard.activeWindowId, "subject-card"); assert.ok(activatedCard.subjectCard.zIndex > opened.subjectStates.positions.window.zIndex); // Re-activating the active window is stable and does not inflate z-index. assert.equal( mapWorkspaceReducer(activatedCard, { type: "activate-window", windowId: "subject-card" }), activatedCard, ); }); test("selecting a domain subject never clears the active grid sector", () => { const sector = { id: "grid/local/sector", lod: 2, mode: "3d" }; const withSector = mapWorkspaceReducer(initialState(), { type: "select-sector", selection: sector }); const withSubject = mapWorkspaceReducer(withSector, { type: "select-entity", entityId: "nodedc-runtime:positions:map.moving_object:unit-1", validTabIds: ["overview"], defaultTabId: "overview", }); assert.equal(withSubject.selectedSector, sector); assert.equal(withSubject.selectedEntityId, "nodedc-runtime:positions:map.moving_object:unit-1"); }); test("sector deactivation clears only sector scope and keeps subject UI state", () => { let state = mapWorkspaceReducer(initialState(), { type: "select-sector", selection: { id: "sector", lod: 1, mode: "3d" } }); state = mapWorkspaceReducer(state, { type: "set-sector-scope-enabled", dimension: "binding", value: "positions", enabled: false }); state = mapWorkspaceReducer(state, { type: "open-subject-window", bindingId: "positions" }); state = mapWorkspaceReducer(state, { type: "deactivate-sector" }); assert.equal(state.selectedSector, null); assert.deepEqual(state.sector.scope, { excludedBindingIds: [], excludedProviders: [], excludedObjectKinds: [], }); assert.equal(state.subjectStates.positions.window.open, true); assert.equal(state.subjectStates.positions.visible, true); }); test("search reveal state is applied atomically without replacing window geometry", () => { const state = initialState(); const originalWindow = state.subjectStates.positions.window; const revealedSubject = { ...state.subjectStates.positions, visible: true, filters: { signal_state: ["inactive"] }, }; const next = mapWorkspaceReducer(state, { type: "reveal-subject", bindingId: "positions", subjectState: revealedSubject, hideOutsideSector: false, scope: { excludedBindingIds: [], excludedProviders: ["other"], excludedObjectKinds: [] }, }); assert.deepEqual(next.subjectStates.positions.window, originalWindow); assert.deepEqual(next.subjectStates.positions.filters, { signal_state: ["inactive"] }); assert.deepEqual(next.sector.scope.excludedProviders, ["other"]); });