Files
Agent-System/internal/docgov/project_docs_content_test.go
weichenandCursor c159786a70 fix(docgov): keep markdown hard-breaks and unify content hashes
Semantic-preserving canonicalization, same-byte write paths, structured
content errors, and a dry-run-default migration_repair stop 404s caused
by trimming project-143 hard-breaks and no-op lease hydrations.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:02:53 +00:00

106 lines
3.2 KiB
Go

package docgov_test
import (
"errors"
"os"
"path/filepath"
"testing"
"chat-agent-system/internal/docgov"
)
func TestReadDocumentContent_TypedErrors(t *testing.T) {
ctx := t.Context()
eng := docgov.NewGovernanceEngine(nil)
_, err := eng.ReadDocumentContent(ctx, "doc_missing", t.TempDir())
if !errors.Is(err, docgov.ErrDocumentNotFound) {
t.Fatalf("not-found: %v", err)
}
var nf *docgov.ContentError
if !errors.As(err, &nf) || nf.Code != docgov.ErrCodeDocumentNotFound {
t.Fatalf("not-found code: %v", err)
}
dir := t.TempDir()
if _, err := eng.CreateOrGetDocument(ctx, "doc_nofile", 1, "intake", "t", "V0.1", filepath.Join(dir, "missing-ws"), 1, "a", 2, "r", 3, "p"); err != nil {
t.Fatal(err)
}
_, err = eng.ReadDocumentContent(ctx, "doc_nofile", dir)
var miss *docgov.ContentError
if !errors.As(err, &miss) || miss.Code != docgov.ErrCodeProjectionMissing {
t.Fatalf("missing: %v", err)
}
if !miss.Retryable || !miss.NeedsAdmin {
t.Fatalf("missing flags %+v", miss)
}
emptyDir := filepath.Join(dir, "empty-ws")
if err := os.MkdirAll(emptyDir, 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(emptyDir, "output.md"), nil, 0o644); err != nil {
t.Fatal(err)
}
if _, err := eng.CreateOrGetDocument(ctx, "doc_empty", 1, "intake", "t", "V0.1", emptyDir, 1, "a", 2, "r", 3, "p"); err != nil {
t.Fatal(err)
}
_, err = eng.ReadDocumentContent(ctx, "doc_empty", dir)
var empty *docgov.ContentError
if !errors.As(err, &empty) || empty.Code != docgov.ErrCodeProjectionEmpty {
t.Fatalf("empty: %v", err)
}
ws := filepath.Join(dir, "mismatch-ws")
if err := os.MkdirAll(ws, 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(ws, "output.md"), []byte("file-bytes\n"), 0o644); err != nil {
t.Fatal(err)
}
if _, err := eng.CreateOrGetDocument(ctx, "doc_mismatch", 1, "intake", "t", "V0.1", ws, 1, "a", 2, "r", 3, "p"); err != nil {
t.Fatal(err)
}
if err := eng.MarkDocumentContentUpdated(ctx, "doc_mismatch", "deadbeef", false); err != nil {
t.Fatal(err)
}
_, err = eng.ReadDocumentContent(ctx, "doc_mismatch", dir)
var mm *docgov.ContentError
if !errors.As(err, &mm) || mm.Code != docgov.ErrCodeIntegrityMismatch {
t.Fatalf("mismatch: %v", err)
}
if mm.Retryable || !mm.NeedsAdmin {
t.Fatalf("mismatch flags %+v", mm)
}
}
func TestSaveDocumentContent_CanonicalBytesMatchHash(t *testing.T) {
ctx := t.Context()
dir := t.TempDir()
ws := filepath.Join(dir, "ws")
if err := os.MkdirAll(ws, 0o755); err != nil {
t.Fatal(err)
}
eng := docgov.NewGovernanceEngine(nil)
if _, err := eng.CreateOrGetDocument(ctx, "doc_save", 1, "intake", "t", "V0.1", ws, 9, "a", 2, "r", 3, "p"); err != nil {
t.Fatal(err)
}
res, err := eng.SaveDocumentContent(ctx, docgov.ContentSaveRequest{
DocID: "doc_save", ActorID: 9, ActorRole: docgov.RoleAuthor, ActorName: "a",
MarkdownBody: "标题 \r\n下一行\r\n",
})
if err != nil {
t.Fatal(err)
}
got, err := os.ReadFile(filepath.Join(ws, "output.md"))
if err != nil {
t.Fatal(err)
}
if string(got) != "标题 \n下一行\n" {
t.Fatalf("saved bytes %q", got)
}
if res.ContentSHA256 == "" || res.ContentSHA256 != res.Doc.ContentSHA256 {
t.Fatalf("sha not synced: %+v", res)
}
}