Files
Agent-System/internal/engineeringdashboard/docs_test.go
T
weichenandCursor a07ba1065b feat(engineering-dashboard): U2-U4 docs git and runtime collectors
Add allowlisted markdown indexing, read-only git plumbing via injected
runners, and docker/readiness collection with path and loopback guards.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 07:03:32 +00:00

112 lines
3.1 KiB
Go

package engineeringdashboard
import (
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func TestDocs_IndexAndBacklinks(t *testing.T) {
root := t.TempDir()
writeDoc(t, root, ".doc/ops/CURRENT.md", "---\nstatus: in_progress\n---\n# Current\n\nSee [task](./short-term/task.md).\n")
writeDoc(t, root, ".doc/ops/short-term/task.md", "---\ntitle: Demo Task\nstatus: planned\nowner: unassigned\nmutex: demo\n---\n# Demo Task\n\nLink to [current](../CURRENT.md).\n")
writeDoc(t, root, ".doc/ops/short-term/orphan.md", "# Orphan\n\nNo links.\n")
// assets must be skipped
mustMkdir(t, filepath.Join(root, ".doc/test-reports/assets"))
if err := os.WriteFile(filepath.Join(root, ".doc/test-reports/assets/secret.md"), []byte("# secret"), 0o600); err != nil {
t.Fatal(err)
}
now := time.Now().UTC()
res := CollectDocs(root, now)
if res.Source.Status != SourceOK {
t.Fatalf("docs source: %+v", res.Source)
}
var foundAssets bool
var task *DocumentNode
for i := range res.Documents {
if strings.Contains(res.Documents[i].Path, "assets/") {
foundAssets = true
}
if strings.HasSuffix(res.Documents[i].Path, "short-term/task.md") {
task = &res.Documents[i]
}
}
if foundAssets {
t.Fatal("assets markdown must not be indexed as body")
}
if task == nil {
t.Fatal("task doc missing")
}
if len(task.LinksIn) == 0 {
t.Fatalf("expected backlink into task, got %+v", task)
}
var planned bool
for _, tk := range res.Tasks {
if strings.Contains(tk.Path, "task.md") {
if tk.DocStatus != DocStatusPlanned || tk.Claim.Claimed {
t.Fatalf("rdev-like task should stay planned/unclaimed: %+v", tk)
}
planned = true
}
}
if !planned {
t.Fatal("task not parsed into TaskState")
}
}
func TestDocs_BrokenLinkDoesNotFailIndex(t *testing.T) {
root := t.TempDir()
writeDoc(t, root, ".doc/ops/note.md", "# Note\n\n[missing](./nope.md)\n")
res := CollectDocs(root, time.Now().UTC())
if res.Source.Status != SourceOK {
t.Fatalf("index should succeed: %+v", res.Source)
}
found := false
for _, d := range res.Documents {
if strings.HasSuffix(d.Path, "note.md") && len(d.BrokenLinks) > 0 {
found = true
}
}
if !found {
t.Fatal("expected broken link recorded")
}
}
func TestPathSafe_RejectsTraversalAndSymlink(t *testing.T) {
root := t.TempDir()
writeDoc(t, root, ".doc/ops/ok.md", "# ok\n")
if _, err := SafeDocPath(root, ".doc/../.env"); err == nil {
t.Fatal("expected traversal deny")
}
target := filepath.Join(root, ".doc/ops/ok.md")
link := filepath.Join(root, ".doc/ops/link.md")
if err := os.Symlink(target, link); err != nil {
t.Fatal(err)
}
if _, err := SafeDocPath(root, ".doc/ops/link.md"); err == nil {
t.Fatal("expected symlink deny")
}
if _, err := SafeDocPath(root, ".doc/ops/ok.md"); err != nil {
t.Fatal(err)
}
}
func writeDoc(t *testing.T, root, rel, body string) {
t.Helper()
abs := filepath.Join(root, filepath.FromSlash(rel))
mustMkdir(t, filepath.Dir(abs))
if err := os.WriteFile(abs, []byte(body), 0o600); err != nil {
t.Fatal(err)
}
}
func mustMkdir(t *testing.T, dir string) {
t.Helper()
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
}