103 lines
4.0 KiB
JavaScript
103 lines
4.0 KiB
JavaScript
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"]);
|
|
});
|