From ec01248346a93a9ca13f86970998e239c62132e4 Mon Sep 17 00:00:00 2001
From: ai_xiaopei <xiaopei@aisim.cn>
Date: Thu, 03 Sep 2026 14:15:59 +0800
Subject: [PATCH] feat(draft): draft list 支持按一级目录过滤,Type 改从路径提取

---
 internal/index/sqlite_test.go |  131 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/internal/index/sqlite_test.go b/internal/index/sqlite_test.go
index f83b4bb..e0430ee 100644
--- a/internal/index/sqlite_test.go
+++ b/internal/index/sqlite_test.go
@@ -64,3 +64,134 @@
 		t.Errorf("node count = %d, want 1", count)
 	}
 }
+
+func TestGetNodeLinks(t *testing.T) {
+	tmpDir := t.TempDir()
+	dbPath := filepath.Join(tmpDir, "test.db")
+
+	store, err := Open(dbPath)
+	if err != nil {
+		t.Fatalf("Open failed: %v", err)
+	}
+	defer store.Close()
+
+	// 插入测试节点
+	node1 := &graph.Node{
+		Path:    "FAQ/001-测试.md",
+		Title:   "测试文档",
+		Section: "FAQ",
+		Content: "# 测试\n\n内容",
+	}
+	node2 := &graph.Node{
+		Path:    "FAQ/002-相关.md",
+		Title:   "相关文档",
+		Section: "FAQ",
+		Content: "# 相关\n\n内容",
+	}
+
+	id1, err := store.InsertNode(node1)
+	if err != nil {
+		t.Fatalf("InsertNode node1 failed: %v", err)
+	}
+
+	id2, err := store.InsertNode(node2)
+	if err != nil {
+		t.Fatalf("InsertNode node2 failed: %v", err)
+	}
+
+	// 插入 wikilink 边
+	edge := &graph.Edge{
+		FromNode: id1,
+		ToNode:   id2,
+		Relation: "wikilink",
+		Label:    "相关文档",
+	}
+	if err := store.InsertEdge(edge); err != nil {
+		t.Fatalf("InsertEdge failed: %v", err)
+	}
+
+	// 测试获取链接
+	links, err := store.GetNodeLinks(id1)
+	if err != nil {
+		t.Fatalf("GetNodeLinks failed: %v", err)
+	}
+	if len(links) != 1 {
+		t.Errorf("links count = %d, want 1", len(links))
+	}
+	if len(links) > 0 && links[0] != "FAQ/002-相关.md" {
+		t.Errorf("links[0] = %q, want %q", links[0], "FAQ/002-相关.md")
+	}
+
+	// 测试无链接的节点
+	links, err = store.GetNodeLinks(id2)
+	if err != nil {
+		t.Fatalf("GetNodeLinks for node2 failed: %v", err)
+	}
+	if len(links) != 0 {
+		t.Errorf("links count = %d, want 0", len(links))
+	}
+}
+
+func TestNodeTypeSeparation(t *testing.T) {
+	tmpDir := t.TempDir()
+	store, err := Open(filepath.Join(tmpDir, "test.db"))
+	if err != nil {
+		t.Fatalf("Open failed: %v", err)
+	}
+	defer store.Close()
+
+	// 插入文件节点 + tag 节点
+	fileID, err := store.InsertNode(&graph.Node{
+		Path: "FAQ/001-测试.md", Title: "测试文档", Section: "FAQ", NodeType: "file",
+		Tags: []string{"电磁阀"},
+	})
+	if err != nil {
+		t.Fatalf("InsertNode file failed: %v", err)
+	}
+	tagID, err := store.InsertNode(&graph.Node{
+		Path: "tag:电磁阀", Title: "电磁阀", NodeType: "tag",
+	})
+	if err != nil {
+		t.Fatalf("InsertNode tag failed: %v", err)
+	}
+
+	// tag 节点不进 FTS
+	if err := store.CreateFTS(); err != nil {
+		t.Fatalf("CreateFTS failed: %v", err)
+	}
+	if err := store.PopulateFTS(); err != nil {
+		t.Fatalf("PopulateFTS failed: %v", err)
+	}
+	res, err := store.FTSSearch([]string{"测试"}, 10)
+	if err != nil {
+		t.Fatalf("FTSSearch failed: %v", err)
+	}
+	for _, r := range res {
+		if r.ID == tagID {
+			t.Error("FTS result contains tag node")
+		}
+	}
+
+	// FindNodesByKeyword 不返回 tag 节点
+	nodes, err := store.FindNodesByKeyword("电磁阀")
+	if err != nil {
+		t.Fatalf("FindNodesByKeyword failed: %v", err)
+	}
+	for _, n := range nodes {
+		if n.ID == tagID {
+			t.Error("FindNodesByKeyword returned tag node")
+		}
+	}
+
+	// GetAllNodes 只返回 file 节点
+	all, err := store.GetAllNodes()
+	if err != nil {
+		t.Fatalf("GetAllNodes failed: %v", err)
+	}
+	for _, n := range all {
+		if n.ID == tagID {
+			t.Error("GetAllNodes returned tag node")
+		}
+	}
+	_ = fileID
+}

--
Gitblit v1.10.0