import { describe, it, expect, vi } from "vitest"; import { buildCandidateNodes, type CandidateNode } from "../../analysis/templateMatching"; import { headingsMatch } from "../../unresolvedLink/linkHelpers"; import type { App } from "obsidian"; import type { IndexedEdge } from "../../analysis/graphIndex"; describe("Debug candidate nodes creation", () => { it("should create candidate node for target with unresolved file path", async () => { const filePath = "03_experience/Geburt unserer Kinder Rouven und Rohan.md"; const markdown = `--- type: experience --- ## Reflexion & Learning (Was lerne ich daraus?) ^learning > [!section] insight ## Nächster Schritt ^next > [!section] decision `; const mockFile = { path: filePath, } as any; const mockApp = { vault: { getAbstractFileByPath: vi.fn((path: string) => { if (path === filePath) return mockFile; if (path === "Geburt unserer Kinder Rouven und Rohan") return mockFile; // Same file return null; }), cachedRead: vi.fn().mockResolvedValue(markdown), }, metadataCache: { getFirstLinkpathDest: vi.fn((target: string, source: string) => { if (target === "Geburt unserer Kinder Rouven und Rohan" && source === filePath) { return mockFile; } return null; }), }, } as unknown as App; const allEdges: IndexedEdge[] = [ { rawEdgeType: "guides", source: { file: filePath, sectionHeading: "Reflexion & Learning (Was lerne ich daraus?) ^learning", }, target: { file: "Geburt unserer Kinder Rouven und Rohan", // No path! heading: "Nächster Schritt ^next", }, scope: "section", evidence: { file: filePath, sectionHeading: "Reflexion & Learning (Was lerne ich daraus?) ^learning", }, }, ]; const candidateNodes: CandidateNode[] = await buildCandidateNodes( mockApp, { file: filePath, heading: "Reflexion & Learning (Was lerne ich daraus?) ^learning" }, allEdges, { includeNoteLinks: true, includeCandidates: true } ); console.log("Candidate nodes created:", candidateNodes.length); console.log("Candidate nodes:", candidateNodes.map((n: CandidateNode) => ({ file: n.nodeKey.file, heading: n.nodeKey.heading }))); // Should have both learning and next nodes (heading may include block-id, e.g. "Nächster Schritt ^next") const learningNode = candidateNodes.find((n: CandidateNode) => n.nodeKey.file === filePath && headingsMatch(n.nodeKey.heading, "Reflexion & Learning (Was lerne ich daraus?) ^learning") ); const nextNode = candidateNodes.find((n: CandidateNode) => n.nodeKey.file === filePath && headingsMatch(n.nodeKey.heading, "Nächster Schritt ^next") ); console.log("Learning node found:", !!learningNode); console.log("Next node found:", !!nextNode); if (nextNode) { console.log("Next node file:", nextNode.nodeKey.file); console.log("Next node heading:", nextNode.nodeKey.heading); } expect(learningNode).toBeDefined(); expect(nextNode).toBeDefined(); }); });