// The Lucia project. // Copyright 2026-2026 DSP, inc. All rights reserved. // Authors: // imacat.yang@dsp.im (imacat), 2026/03/06 import { describe, it, expect, beforeEach, vi } from "vitest"; import { setActivePinia, createPinia } from "pinia"; // Mock allMapData store (used by createInsightWithPath / createPaths) vi.mock("@/stores/allMapData", () => ({ default: () => ({ insights: {} }), })); // Mock SVG asset imports vi.mock("@/assets/capsule1-glow.svg", () => ({ default: "glow1" })); vi.mock("@/assets/capsule2-glow.svg", () => ({ default: "glow2" })); vi.mock("@/assets/capsule3-glow.svg", () => ({ default: "glow3" })); vi.mock("@/assets/capsule4-glow.svg", () => ({ default: "glow4" })); vi.mock("@/assets/capsule1.svg", () => ({ default: "cap1" })); vi.mock("@/assets/capsule2.svg", () => ({ default: "cap2" })); vi.mock("@/assets/capsule3.svg", () => ({ default: "cap3" })); vi.mock("@/assets/capsule4.svg", () => ({ default: "cap4" })); import { useMapPathStore } from "@/stores/mapPathStore"; /** * Creates a mock Cytoscape node. */ function mockNode(label, level = 0) { const nodeData = { label, level, nodeImageUrl: "" }; const classes = new Set(); const node = { data: vi.fn((key, value) => { if (value !== undefined) { nodeData[key] = value; return node; } return nodeData[key]; }), addClass: vi.fn((cls) => { classes.add(cls); return node; }), removeClass: vi.fn((cls) => { classes.delete(cls); return node; }), hasClass: (cls) => classes.has(cls), outgoers: vi.fn(() => mockCollection([])), incomers: vi.fn(() => mockCollection([])), edgesTo: vi.fn(() => mockCollection([])), edgesWith: vi.fn(() => mockCollection([])), _nodeData: nodeData, _classes: classes, }; return node; } /** * Creates a mock Cytoscape edge. */ function mockEdge() { const classes = new Set(); const edge = { addClass: vi.fn((cls) => { classes.add(cls); return edge; }), removeClass: vi.fn((cls) => { classes.delete(cls); return edge; }), source: vi.fn(() => mockNode("src")), target: vi.fn(() => mockNode("tgt")), _classes: classes, }; return edge; } /** * Creates a mock Cytoscape collection. */ function mockCollection(items) { const col = { forEach: (fn) => items.forEach(fn), map: (fn) => items.map(fn), filter: (fn) => mockCollection(items.filter(fn)), addClass: vi.fn(() => col), removeClass: vi.fn(() => col), length: items.length, }; return col; } /** * Creates a mock Cytoscape instance. */ function mockCytoscape(nodes = [], edges = []) { return { nodes: vi.fn(() => mockCollection(nodes)), edges: vi.fn(() => mockCollection(edges)), }; } describe("mapPathStore", () => { let store; beforeEach(() => { setActivePinia(createPinia()); store = useMapPathStore(); vi.clearAllMocks(); }); it("has correct default state", () => { expect(store.processOrBPMN).toBe("process"); expect(store.curveType).toBe("curved"); expect(store.directionType).toBe("horizontal"); expect(store.isBPMNOn).toBe(false); expect(store.allPaths).toEqual([]); expect(store.activeTrace).toBe(0); expect(store.lastClickedNode).toBeNull(); }); it("setIsBPMNOn updates state", () => { store.setIsBPMNOn(true); expect(store.isBPMNOn).toBe(true); store.setIsBPMNOn(false); expect(store.isBPMNOn).toBe(false); }); describe("clearAllHighlight", () => { it("removes highlight classes from all nodes and edges", () => { const node1 = mockNode("A", 0); const edge1 = mockEdge(); const cy = mockCytoscape([node1], [edge1]); store.cytoscape.process.curved.horizontal = cy; store.clearAllHighlight(); expect(cy.edges).toHaveBeenCalled(); expect(cy.nodes).toHaveBeenCalled(); }); it("does not throw when cytoscape is null", () => { store.cytoscape.process.curved.horizontal = null; expect(() => store.clearAllHighlight()).not.toThrow(); }); }); describe("onNodeClickHighlightEdges", () => { it("highlights clicked node and its edges", () => { const node = mockNode("Activity", 1); const outEdge = mockEdge(); const inEdge = mockEdge(); node.outgoers.mockReturnValue(mockCollection([outEdge])); node.incomers.mockReturnValue(mockCollection([inEdge])); store.cytoscape.process.curved.horizontal = mockCytoscape(); store.onNodeClickHighlightEdges(node); expect(node.addClass).toHaveBeenCalledWith("highlight-node"); expect(outEdge.addClass).toHaveBeenCalledWith("highlight-edge"); expect(inEdge.addClass).toHaveBeenCalledWith("highlight-edge"); expect(store.lastClickedNode).toStrictEqual(node); }); }); describe("onEdgeClickHighlightNodes", () => { it("highlights source and target nodes of clicked edge", () => { const src = mockNode("Start", 0); const tgt = mockNode("End", 2); const edge = mockEdge(); edge.source.mockReturnValue(src); edge.target.mockReturnValue(tgt); store.cytoscape.process.curved.horizontal = mockCytoscape(); store.onEdgeClickHighlightNodes(edge); expect(src.addClass).toHaveBeenCalledWith("highlight-node"); expect(tgt.addClass).toHaveBeenCalledWith("highlight-node"); expect(edge.addClass).toHaveBeenCalledWith("highlight-edge"); }); }); });