受控小队任务服务端启用修复预算;否定性自检引用不再误报;quality_failed 保持失败且不激活未过门禁稿。 Co-authored-by: Cursor <cursoragent@cursor.com>
113 lines
3.8 KiB
Go
113 lines
3.8 KiB
Go
package bizdev_test
|
||
|
||
import (
|
||
"strings"
|
||
"testing"
|
||
|
||
"chat-agent-system/internal/bizdev"
|
||
"chat-agent-system/internal/docgov"
|
||
"chat-agent-system/internal/squad"
|
||
)
|
||
|
||
func TestTaskRunResult_PendingConfirmation_NotCompleted(t *testing.T) {
|
||
res := &bizdev.TaskRunResult{
|
||
Success: true,
|
||
ArtifactTitle: "用户初始需求收集表",
|
||
TaskKey: "intake",
|
||
RequiresAuthorApproval: true,
|
||
PendingAgentCandidateID: 42,
|
||
PendingChangeReportID: 7,
|
||
PendingRiskLevel: "high",
|
||
PendingConfirmationNote: "高风险变更待编制人确认",
|
||
DocRecord: &docgov.DocumentRecord{DocID: "doc_proj1_intake", ContentSHA256: "abc"},
|
||
}
|
||
if res.TerminalStatus() != bizdev.TaskStatusPendingAuthorConfirmation {
|
||
t.Fatalf("status=%q", res.TerminalStatus())
|
||
}
|
||
if res.IsProposalIntercept() {
|
||
t.Fatal("pending agent must not look like DocGov proposal intercept")
|
||
}
|
||
sum := res.CompletionSummary()
|
||
if strings.Contains(sum, "已完成") || strings.Contains(sum, "正文已保存") {
|
||
t.Fatalf("pending summary must not claim completed/saved: %s", sum)
|
||
}
|
||
if !strings.Contains(sum, "文档候选已生成") || !strings.Contains(sum, "待编制人确认") {
|
||
t.Fatalf("pending summary missing confirmation wording: %s", sum)
|
||
}
|
||
art := res.ArtifactMetadata()
|
||
if art["doc_id"] != "doc_proj1_intake" {
|
||
t.Fatalf("artifact doc_id=%v", art["doc_id"])
|
||
}
|
||
if art["pending_agent_candidate_id"] != int64(42) {
|
||
t.Fatalf("pending candidate meta=%v", art["pending_agent_candidate_id"])
|
||
}
|
||
if art["awaiting_author_confirmation"] != true {
|
||
t.Fatal("expected awaiting_author_confirmation")
|
||
}
|
||
}
|
||
|
||
func TestTaskRunResult_ProposalIntercept_DistinctFromPendingAgent(t *testing.T) {
|
||
res := &bizdev.TaskRunResult{
|
||
Success: false,
|
||
RequiresAuthorApproval: true,
|
||
PendingProposal: &docgov.ChangeProposal{ProposalID: "prop_1"},
|
||
ErrorReason: "认领拦截",
|
||
}
|
||
if !res.IsProposalIntercept() {
|
||
t.Fatal("expected proposal intercept")
|
||
}
|
||
if res.AwaitsAgentConfirmation() {
|
||
t.Fatal("proposal must not look like agent pending confirmation")
|
||
}
|
||
if res.TerminalStatus() != bizdev.TaskStatusFailed {
|
||
t.Fatalf("status=%q", res.TerminalStatus())
|
||
}
|
||
}
|
||
|
||
func TestTaskRunResult_CompletedOnlyWhenCommitted(t *testing.T) {
|
||
res := &bizdev.TaskRunResult{
|
||
Success: true,
|
||
ArtifactTitle: "报价核算表",
|
||
TaskKey: "quote",
|
||
QualityReport: nil,
|
||
DocRecord: &docgov.DocumentRecord{DocID: "doc_proj1_quote"},
|
||
}
|
||
if res.TerminalStatus() != bizdev.TaskStatusCompleted {
|
||
t.Fatalf("status=%q", res.TerminalStatus())
|
||
}
|
||
sum := res.CompletionSummary()
|
||
if !strings.Contains(sum, "已完成") {
|
||
t.Fatalf("completed summary: %s", sum)
|
||
}
|
||
}
|
||
|
||
// 现场:score=40 / quality_failed 不得映射 completed;Success 已清仍保持 quality_failed。
|
||
func TestTaskRunResult_QualityFailed_NotCompleted(t *testing.T) {
|
||
res := &bizdev.TaskRunResult{
|
||
Success: false,
|
||
ArtifactTitle: "用户初始需求收集表",
|
||
TaskKey: "intake",
|
||
QualityReport: &squad.QualityReport{
|
||
Passed: false,
|
||
Score: 40,
|
||
ProhibitedPhrases: []string{"不做展开", "从略", "篇幅有限"},
|
||
Violations: []string{"检测到正文中的省略/敷衍写法(须实质展开;自检勿复述禁用原词)"},
|
||
},
|
||
DocRecord: &docgov.DocumentRecord{DocID: "doc_proj6098_intake"},
|
||
}
|
||
if res.TerminalStatus() != bizdev.TaskStatusQualityFailed {
|
||
t.Fatalf("status=%q want quality_failed", res.TerminalStatus())
|
||
}
|
||
sum := res.CompletionSummary()
|
||
if strings.Contains(sum, "已完成") {
|
||
t.Fatalf("quality_failed summary must not claim completed: %s", sum)
|
||
}
|
||
if !strings.Contains(sum, "质量检查未通过") {
|
||
t.Fatalf("summary missing quality fail wording: %s", sum)
|
||
}
|
||
art := res.ArtifactMetadata()
|
||
if art["quality_passed"] != false {
|
||
t.Fatalf("quality_passed=%v", art["quality_passed"])
|
||
}
|
||
}
|