Files
arcrun-collector/sourcerepair_test.go
T

141 lines
4.3 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.
package collector
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
const legacyCard = `---
tags: [測試]
gloss: 測試卡
created: 2026-08-01
updated: 2026-08-01
---
# 小果被AFTEE詐貸
← [[00-INDEX]]
## 摘要
一段摘要。
## 重點
- 一條重點
## 實體
- **小果**(人物)— 當事人
## 關聯
### 內文知識關係
- 小果 >` + `> 被詐貸 >` + `> AFTEE
### 卡片關係
- [[小果被AFTEE詐貸]] >` + `> 整理出 >` + `> [[貸款爭議]]
### 出處
- ` + "`../小果被AFTEE詐貸.pdf`" + ` >` + `> 提及 >` + `> 小果被AFTEE詐貸
`
// TestRepairCardSourceBlocks 驗既有資料的處置:舊形出處就地改寫+原樣重推。
// 這是票 `inkstone/Arcrun#167` 驗收條件「不能只修新的」的機械閘。
func TestRepairCardSourceBlocks(t *testing.T) {
root := t.TempDir()
cardRel := "子資料夾/.wiki/小果被AFTEE詐貸.md"
if err := os.MkdirAll(filepath.Join(root, "子資料夾", ".wiki"), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(root, filepath.FromSlash(cardRel)), []byte(legacyCard), 0o644); err != nil {
t.Fatal(err)
}
wm := &wikiManifest{Version: 1, Docs: []wikiDoc{{
Node: "子資料夾", Path: "小果被AFTEE詐貸.pdf", Status: "extracted",
Card: "小果被AFTEE詐貸", Cards: []string{cardRel},
}}}
if err := saveWikiManifest(root, wm); err != nil {
t.Fatal(err)
}
var got map[string]any
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
b, _ := io.ReadAll(r.Body)
_ = json.Unmarshal(b, &got)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"success":true}`))
}))
defer srv.Close()
cfg := &DirectConfig{
CypherURL: srv.URL, APIKey: "k", Namespace: "ns",
CardIngestWF: "rag_ingest_card",
MachineLabel: "教育部 Leo 的 Mac",
}
m := &Manifest{Root: root, Entries: map[string]*ManifestEntry{}}
res := repairCardSourceBlocks(cfg, root, m, false, false, time.Now())
if res == nil || res.Repushed != 1 {
t.Fatalf("沒有重推:%+v", res)
}
// ① 本機卡不再有內部相對路徑,且定位得到子資料夾。
fixed, err := os.ReadFile(filepath.Join(root, filepath.FromSlash(cardRel)))
if err != nil {
t.Fatal(err)
}
card := string(fixed)
if strings.Contains(card, "../") {
t.Fatalf("本機卡仍帶 `../`\n%s", card)
}
if !strings.Contains(card, "子資料夾/小果被AFTEE詐貸.pdf") {
t.Fatalf("本機卡的出處定位不到子資料夾:\n%s", card)
}
if !strings.Contains(card, "教育部 Leo 的 Mac") {
t.Fatalf("本機卡的出處沒有機器標記:\n%s", card)
}
// ② 出處以外一字不動(重萃會讓內容變樣,就地修不會)。
if !strings.Contains(card, "## 摘要\n一段摘要。") || !strings.Contains(card, "- **小果**(人物)— 當事人") {
t.Fatalf("出處以外的內容被動到了:\n%s", card)
}
// ③ 送上雲的 payload 與 direct.go 送新卡時同一組欄位,且路徑是**庫內完整路徑**。
if got["path"] != "子資料夾/小果被AFTEE詐貸.pdf" {
t.Fatalf("重推的 path 不對:%v", got["path"])
}
if got["page_name"] != "小果被AFTEE詐貸" {
t.Fatalf("重推的 page_name 不對:%v", got["page_name"])
}
if s, _ := got["card_content"].(string); strings.Contains(s, "../") {
t.Fatalf("送上雲的卡片內容仍帶 `../`\n%s", s)
}
// ④ 修完蓋章 ⇒ 不會每輪重掃、更不會每輪重推。
if m.SourceOriginRepairedAt == 0 {
t.Fatal("修完沒蓋章,會變成每輪都跑的背景工作")
}
got = nil
if again := repairCardSourceBlocks(cfg, root, m, false, false, time.Now()); again != nil {
t.Fatalf("蓋章後又跑了一次:%+v", again)
}
if got != nil {
t.Fatal("蓋章後又重推了一次")
}
}
// TestRewriteSourceBlockLeavesNewShapeAlone:已經是新形的卡不該被再動一次
//(避免「每輪都改一點」讓使用者的檔案 mtime 無故跳動)。
func TestRewriteSourceBlockLeavesNewShapeAlone(t *testing.T) {
o := SourceOrigin{MachineLabel: "m", Library: "kb", LibraryPath: "a/b.md"}
var b strings.Builder
renderSourceLine(&b, o, "卡")
card := "## 關聯\n### 卡片關係\n" + b.String()
if hasLegacySourceLine(card) {
t.Fatalf("新形被誤判成舊形:\n%s", card)
}
if rewriteSourceBlock(card, o, "卡") != card {
t.Fatal("新形卡被重寫了")
}
}