Files
arcrun-collector/extract_workersai_test.go
T
Leo 5a140faf1f fix(collector): 機器寫進筆記庫的檔案一律帶前綴,不再跟使用者的頁面撞名(arcrun-rag#60)
leo 2026-08-12:「我的 Logseq 又被覆蓋⋯⋯**不只是加上 journal,可能所有的檔案都加一個前後綴,比如「wiki」**。」

不是資料被蓋掉,是機器產出用了跟他一樣的命名空間(status.md、日期檔那些)
⇒ 他打開資料夾分不出哪些是自己的。**心理上的覆蓋跟實際覆蓋一樣糟。**
2026-08-12 14:57:32 +08:00

105 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// extract_workersai_test.go — arcrun-rag#60workers-ai 是預設/主線萃取路(t181),
// 同一套 vault 保護要對這條路也成立,不能只顧 gemma。
package collector
import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
func workersAIStub(t *testing.T, handler http.HandlerFunc) (url string, closeFn func()) {
t.Helper()
srv := httptest.NewServer(handler)
return srv.URL, srv.Close
}
func TestExtractWithWorkersAI_VaultRedirectsAndDoesNotClobber(t *testing.T) {
root := t.TempDir()
mustMkdir(t, filepath.Join(root, ".obsidian")) // Obsidian vault
srcRel := "note.md"
if err := os.WriteFile(filepath.Join(root, srcRel), []byte("# 原稿"), 0o644); err != nil {
t.Fatal(err)
}
// 隱藏卡片目錄裡先放一份既有內容,驗證不會被無聲蓋掉。
// 檔名帶 arcrun- 前綴=第二輪之後卡片真正的名字(machinemark.go)。
cardDir := filepath.Join(root, ".arcrun-rag", "wiki", "cards")
mustMkdir(t, cardDir)
preexisting := "# note\n既有內容"
if err := os.WriteFile(filepath.Join(cardDir, "arcrun-note.md"), []byte(preexisting), 0o644); err != nil {
t.Fatal(err)
}
url, closeFn := workersAIStub(t, func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("X-Arcrun-API-Key") != "key123" {
t.Errorf("api key 未帶到 header")
}
_ = json.NewEncoder(w).Encode(map[string]any{
"success": true,
"card": "# note\n## 一句話定義\n新卡\n",
})
})
defer closeFn()
cards, err := ExtractWithWorkersAI(url, "key123", root, srcRel)
if err != nil {
t.Fatal(err)
}
if len(cards) != 1 || cards[0] != ".arcrun-rag/wiki/cards/arcrun-note.md" {
t.Fatalf("vault 目標的卡片路徑不對:%vwant [.arcrun-rag/wiki/cards/arcrun-note.md]", cards)
}
// pages/.obsidian 之外沒有新增任何非隱藏 .mdObsidian 不掃描 .arcrun-rag/)。
topLevel := countMD(t, root)
if topLevel != 1 { // 只有原本的 srcRel
t.Fatalf("vault 根目錄多出非預期的 .mdcount=%d", topLevel)
}
// 既有卡片必須被備份,不能無聲覆蓋。
entries, err := os.ReadDir(cardDir)
if err != nil {
t.Fatal(err)
}
var foundBackup bool
for _, e := range entries {
if strings.HasPrefix(e.Name(), "arcrun-note.md.bak-") {
foundBackup = true
}
}
if !foundBackup {
t.Fatalf("既有卡片沒有被備份,目錄內容:%v", entries)
}
}
// 非 vault:卡片仍落 system-dev/wiki/cards/(目錄不變),但檔名同樣帶標記。
//
// 🔴 第二輪刻意讓「vault 與非 vault 用同一條命名規則」:紅線是「前綴只准一種、
// 不要一部分加一部分不加」。若只在 vault 加前綴,一般資料夾的使用者照樣分不出
// 哪些檔是機器寫的——而 system-dev/wiki/cards/ 在他的檔案總管裡是**看得見**的。
func TestExtractWithWorkersAI_NonVaultUnchanged(t *testing.T) {
root := t.TempDir()
srcRel := "note.md"
if err := os.WriteFile(filepath.Join(root, srcRel), []byte("# 原稿"), 0o644); err != nil {
t.Fatal(err)
}
url, closeFn := workersAIStub(t, func(w http.ResponseWriter, r *http.Request) {
_ = json.NewEncoder(w).Encode(map[string]any{
"success": true,
"card": "# note\n## 一句話定義\n新卡\n",
})
})
defer closeFn()
cards, err := ExtractWithWorkersAI(url, "key123", root, srcRel)
if err != nil {
t.Fatal(err)
}
if len(cards) != 1 || cards[0] != "system-dev/wiki/cards/arcrun-note.md" {
t.Fatalf("非 vault 卡片路徑不對:%vwant [system-dev/wiki/cards/arcrun-note.md]", cards)
}
}