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>
100 lines
3.4 KiB
Go
100 lines
3.4 KiB
Go
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)
|
||
}
|
||
}
|