package projectinstance import ( "testing" "chat-agent-system/internal/workflowdef" ) func TestEvaluateStageReadiness_DutyModes(t *testing.T) { t.Parallel() stageDef := &workflowdef.StageDef{ Key: "V0.1_triage", DocTasks: []workflowdef.DocTaskDef{ {Key: "intake", BlockingWhenEnabled: true, CreatorConfigurable: true}, {Key: "research", CreatorConfigurable: true}, }, } plan := StagePlan{ StageKey: "V0.1_triage", Enabled: true, DocTasks: []DocTaskPlan{ {TaskKey: "intake", Enabled: true, Duties: DocDuty{AuthorUserID: 1, ReviewerUserID: 2, ApproverUserID: 3}}, {TaskKey: "research", Enabled: true}, {TaskKey: "skipped", Enabled: false, Duties: DocDuty{AuthorUserID: 1, ReviewerUserID: 2, ApproverUserID: 3}}, }, } ready, issues, items := evaluateStageReadiness(plan, stageDef, map[string]string{"research": "draft"}) if ready { t.Fatal("full blocking doc missing approval must keep the gate closed") } if len(issues) != 1 || issues[0].TaskKey != "intake" { t.Fatalf("only intake should block, got %+v", issues) } var research, intake *DocTaskReadiness for i := range items { switch items[i].TaskKey { case "research": research = &items[i] case "intake": intake = &items[i] case "skipped": t.Fatal("disabled docs must not participate") } } if intake == nil || !intake.ApprovalManaged || !intake.Required { t.Fatalf("full blocking doc: %+v", intake) } if research == nil || research.ApprovalManaged || research.Required || !research.Enabled { t.Fatalf("none doc must stay enabled without approval management: %+v", research) } ready, issues, _ = evaluateStageReadiness(plan, stageDef, map[string]string{"intake": "approved"}) if !ready || len(issues) != 0 { t.Fatalf("approved full + unmanaged none should be ready, issues=%+v", issues) } } func TestEvaluateStageReadiness_AuthorOnlyIsManaged(t *testing.T) { t.Parallel() stageDef := &workflowdef.StageDef{ Key: "V0.1_triage", DocTasks: []workflowdef.DocTaskDef{ {Key: "intake", BlockingWhenEnabled: true, CreatorConfigurable: true}, }, } plan := StagePlan{ StageKey: "V0.1_triage", Enabled: true, DocTasks: []DocTaskPlan{{ TaskKey: "intake", Enabled: true, DutyPolicy: DutyPolicyAuthorOnly, Duties: DocDuty{AuthorUserID: 7}, }}, } ready, issues, items := evaluateStageReadiness(plan, stageDef, map[string]string{}) if ready { t.Fatal("author_only blocking doc without approval must keep gate closed") } if len(issues) != 1 || issues[0].TaskKey != "intake" { t.Fatalf("issues=%+v", issues) } if len(items) != 1 || !items[0].ApprovalManaged || !items[0].Required { t.Fatalf("author_only must be approval-managed: %+v", items) } ready, _, _ = evaluateStageReadiness(plan, stageDef, map[string]string{"intake": "approved"}) if !ready { t.Fatal("approved author_only doc should open the gate") } }