test(workflow): add governance regression and activation PG coverage
Cover public auth config, catalog policy, official main workflow activation on Postgres, and conn-busy metadata writeback fixes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
weichen
co-authored by
Cursor
parent
47984f4863
commit
ad6e38d11a
@@ -0,0 +1,99 @@
|
||||
package projectinstance_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"chat-agent-system/internal/projectinstance"
|
||||
"chat-agent-system/internal/projectworkflow"
|
||||
"chat-agent-system/internal/workflowdef"
|
||||
)
|
||||
|
||||
// TestPG_ActivateOfficialWorkflowRuntimeMetadata 回归激活链路:
|
||||
// ActivateInstance.applyRuntimeMetadata 会遍历文档任务实例并逐条 UPDATE。
|
||||
// 若在同一事务连接上 rows 未读完时就执行 Exec,pgx 会返回 "conn busy"。
|
||||
// 本测试使用正式商务对接流程(3 阶段 7 任务)覆盖该路径。
|
||||
func TestPG_ActivateOfficialWorkflowRuntimeMetadata(t *testing.T) {
|
||||
pool := openPGPool(t)
|
||||
defer pool.Close()
|
||||
ctx := context.Background()
|
||||
|
||||
wfStore := workflowdef.NewStore(pool)
|
||||
def, err := workflowdef.LoadManifestDefinition("main.v2.json")
|
||||
if err != nil {
|
||||
t.Fatalf("load main.v2 manifest: %v", err)
|
||||
}
|
||||
if err := wfStore.UpsertPublishedSeed(ctx, workflowdef.CreateDefinitionInput{
|
||||
Key: workflowdef.OfficialKeyMain,
|
||||
Name: "商务对接流程",
|
||||
Definition: def,
|
||||
}, 1); err != nil {
|
||||
t.Fatalf("seed official main workflow: %v", err)
|
||||
}
|
||||
|
||||
pwStore := projectworkflow.NewStore(pool)
|
||||
instStore := projectinstance.NewStore(pool)
|
||||
svc := projectinstance.NewService(instStore, wfStore, pwStore, nil)
|
||||
|
||||
var projectID int64
|
||||
code := "pg-official-" + time.Now().Format("150405.000")
|
||||
err = pool.QueryRow(ctx, `
|
||||
INSERT INTO projects (code, name, status, creator_user_id, lifecycle_status, active_workflow_key, workflow_selection_version, workflow_plan_revision)
|
||||
VALUES ($1, 'PG Official Activation Test', 'active', 1, 'planning', '', 1, 0) RETURNING id
|
||||
`, code).Scan(&projectID)
|
||||
if err != nil {
|
||||
t.Fatalf("insert project: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(context.Background(), `DELETE FROM projects WHERE id = $1`, projectID)
|
||||
})
|
||||
|
||||
plan, err := svc.BuildDefaultPlan(ctx, workflowdef.OfficialKeyMain, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("default plan: %v", err)
|
||||
}
|
||||
for i := range plan.Stages {
|
||||
for j := range plan.Stages[i].DocTasks {
|
||||
plan.Stages[i].DocTasks[j].Duties = projectinstance.DocDuty{
|
||||
AuthorUserID: 1, ReviewerUserID: 2, ApproverUserID: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := svc.SaveWorkflowPlan(ctx, projectID, 1, true, projectinstance.SavePlanInput{
|
||||
Plan: *plan, ExpectedPlanRevision: 0, ExpectedSelectionVersion: 1,
|
||||
}); err != nil {
|
||||
t.Fatalf("save plan: %v", err)
|
||||
}
|
||||
preview, err := svc.ActivationPreview(ctx, projectID, 1, true)
|
||||
if err != nil {
|
||||
t.Fatalf("preview: %v", err)
|
||||
}
|
||||
activated, err := svc.Activate(ctx, projectID, 1, true, projectinstance.ActivateInput{
|
||||
ConfirmationToken: preview.ConfirmationToken,
|
||||
ExpectedProjectVersion: preview.ExpectedProjectVersion,
|
||||
ExpectedPlanRevision: preview.ExpectedPlanRevision,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("activate: %v", err)
|
||||
}
|
||||
if activated.Instance.Status != projectinstance.InstanceActive {
|
||||
t.Fatalf("expected active instance, got %q", activated.Instance.Status)
|
||||
}
|
||||
|
||||
// 运行时元数据应写回文档任务实例(回归 applyRuntimeMetadata 的逐条 UPDATE)。
|
||||
var executorKey string
|
||||
err = pool.QueryRow(ctx, `
|
||||
SELECT dti.executor_key
|
||||
FROM project_doc_task_instances dti
|
||||
JOIN project_stage_instances si ON si.id = dti.stage_instance_id
|
||||
WHERE si.workflow_instance_id = $1 AND dti.task_key = 'intake'
|
||||
`, activated.Instance.ID).Scan(&executorKey)
|
||||
if err != nil {
|
||||
t.Fatalf("query runtime metadata: %v", err)
|
||||
}
|
||||
if executorKey != "bizdev.intake.v1" {
|
||||
t.Fatalf("expected executor_key bizdev.intake.v1, got %q", executorKey)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user