package docgov_test import ( "context" "testing" "time" "chat-agent-system/internal/docgov" ) func TestListWorkflowDocumentsIncludesActiveLease(t *testing.T) { engine := docgov.NewGovernanceEngine(nil) ctx := context.Background() const docID = "doc_project_docs_lease" if _, err := engine.CreateOrGetDocument( ctx, docID, 143, "intake", "用户初始需求收集表", "V0.1", "", 9, "编制人", 2, "审核人", 3, "批准人", ); err != nil { t.Fatal(err) } if _, err := engine.AcquireLease(ctx, docgov.LeaseAcquireRequest{ DocID: docID, HolderType: docgov.LeaseHolderSquad, HolderID: "run-visible", TTL: time.Minute, }); err != nil { t.Fatal(err) } docs, err := engine.ListWorkflowDocumentsByProject(ctx, 143) if err != nil { t.Fatal(err) } if len(docs) != 1 { t.Fatalf("documents=%d", len(docs)) } if docs[0].LeaseHolderType != docgov.LeaseHolderSquad || docs[0].LeaseHolderID != "run-visible" { t.Fatalf("lease not projected: %+v", docs[0]) } if docs[0].LeaseExpiresAt == nil || docs[0].LeaseHeartbeatAt == nil { t.Fatalf("lease timestamps missing: %+v", docs[0]) } } func TestListWorkflowDocumentsIncludesAuthoritativeDuties(t *testing.T) { engine := docgov.NewGovernanceEngine(nil) ctx := context.Background() const ( docID = "doc_proj143_intake" authorID = int64(9) reviewerID = int64(2) approverID = int64(3) ) if _, err := engine.CreateOrGetDocument( ctx, docID, 143, "intake", "用户初始需求收集表", "V0.1", "", authorID, "编制人A", reviewerID, "审核人B", approverID, "批准人C", ); err != nil { t.Fatal(err) } docs, err := engine.ListWorkflowDocumentsByProject(ctx, 143) if err != nil { t.Fatal(err) } if len(docs) != 1 { t.Fatalf("documents=%d", len(docs)) } got := docs[0] if got.AuthorID != authorID || got.AuthorName != "编制人A" { t.Fatalf("author not projected: id=%d name=%q", got.AuthorID, got.AuthorName) } if got.ReviewerID != reviewerID || got.ReviewerName != "审核人B" { t.Fatalf("reviewer not projected: id=%d name=%q", got.ReviewerID, got.ReviewerName) } if got.ApproverID != approverID || got.ApproverName != "批准人C" { t.Fatalf("approver not projected: id=%d name=%q", got.ApproverID, got.ApproverName) } if got.AuthorID == reviewerID { t.Fatalf("reviewer B must not become author: %+v", got) } if got.AuthorID == 99 { t.Fatalf("stranger must not become author: %+v", got) } } func TestListWorkflowDocumentsCollapsesLegacyAlias(t *testing.T) { engine := docgov.NewGovernanceEngine(nil) ctx := context.Background() const projectID = int64(6579) seeds := []struct { docID string taskKey string title string }{ {"doc_proj6579_intake", "intake", "用户初始需求收集表"}, {"doc_proj6579_bd_intake", "bd_intake", "用户初始需求收集表"}, {"doc_proj6579_bd_research", "bd_research", "调研报告"}, } for _, seed := range seeds { if _, err := engine.CreateOrGetDocument( ctx, seed.docID, projectID, seed.taskKey, seed.title, "V0.1", "", 398, "陈威", 0, "", 0, "", ); err != nil { t.Fatal(err) } } docs, err := engine.ListWorkflowDocumentsByProject(ctx, projectID) if err != nil { t.Fatal(err) } if len(docs) != 2 { t.Fatalf("documents=%d, want bd_intake and bd_research only", len(docs)) } for _, doc := range docs { if doc.TaskKey == "intake" { t.Fatalf("legacy intake row leaked into the list: %+v", doc) } } if docs[0].TaskKey != "bd_intake" || docs[0].DocID != "doc_proj6579_bd_intake" { t.Fatalf("first doc=%+v", docs[0]) } }