- ActiveWorkflowScope resolves live instance task keys for the project - chat document reader matches inside the active pool; cross-flow hits return ErrWrongWorkflow with switch guidance - enrichSessionWorkflowStage injects ActiveWorkflowKey into UserCtx - TRIGGER_TASK (coordinator + task-run API) blocks out-of-scope task keys Co-authored-by: Cursor <cursoragent@cursor.com>
76 lines
2.4 KiB
Go
76 lines
2.4 KiB
Go
package server
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"chat-agent-system/internal/coordinator"
|
|
"chat-agent-system/internal/docgov"
|
|
)
|
|
|
|
func TestSelectReadableWorkflowDocumentMatchesInitialRequirementsAlias(t *testing.T) {
|
|
docs := []docgov.WorkflowDocumentSummary{
|
|
{DocID: "doc_proj143_intake", TaskKey: "intake", Title: "用户初始需求收集表"},
|
|
{DocID: "doc_proj143_research", TaskKey: "research", Title: "技术与市场调研报告"},
|
|
}
|
|
doc, err := selectReadableWorkflowDocument(docs, "用户初始需求表", "", nil)
|
|
if err != nil {
|
|
t.Fatalf("select: %v", err)
|
|
}
|
|
if doc.DocID != "doc_proj143_intake" {
|
|
t.Fatalf("doc=%s", doc.DocID)
|
|
}
|
|
}
|
|
|
|
func TestSelectReadableWorkflowDocumentDoesNotGuessWhenTargetMissing(t *testing.T) {
|
|
docs := []docgov.WorkflowDocumentSummary{
|
|
{DocID: "doc_a", TaskKey: "intake", Title: "用户初始需求收集表"},
|
|
{DocID: "doc_b", TaskKey: "research", Title: "调研报告"},
|
|
}
|
|
if _, err := selectReadableWorkflowDocument(docs, "", "", nil); err == nil {
|
|
t.Fatal("expected target-required error")
|
|
}
|
|
}
|
|
|
|
func TestSelectReadableWorkflowDocumentScopesToActiveWorkflow(t *testing.T) {
|
|
docs := []docgov.WorkflowDocumentSummary{
|
|
{DocID: "doc_proj1_research", TaskKey: "bd_research", Title: "调研报告"},
|
|
{DocID: "doc_proj1_proposal", TaskKey: "rd_proposal", Title: "项目建议书"},
|
|
}
|
|
scope := map[string]bool{"bd_research": true, "research": true}
|
|
|
|
doc, err := selectReadableWorkflowDocument(docs, "调研报告", "main", scope)
|
|
if err != nil {
|
|
t.Fatalf("in-scope select: %v", err)
|
|
}
|
|
if doc.TaskKey != "bd_research" {
|
|
t.Fatalf("want bd_research, got %s", doc.TaskKey)
|
|
}
|
|
|
|
_, err = selectReadableWorkflowDocument(docs, "项目建议书", "main", scope)
|
|
if err == nil {
|
|
t.Fatal("expected wrong-workflow error")
|
|
}
|
|
var wrong *coordinator.ErrWrongWorkflow
|
|
if !errors.As(err, &wrong) {
|
|
t.Fatalf("want ErrWrongWorkflow, got %T %v", err, err)
|
|
}
|
|
if !strings.Contains(wrong.Message, "切换") {
|
|
t.Fatalf("guidance should mention 切换, got %q", wrong.Message)
|
|
}
|
|
}
|
|
|
|
func TestSelectReadableWorkflowDocumentNoScopeKeepsLegacy(t *testing.T) {
|
|
docs := []docgov.WorkflowDocumentSummary{
|
|
{DocID: "doc_proj1_proposal", TaskKey: "rd_proposal", Title: "项目建议书"},
|
|
}
|
|
doc, err := selectReadableWorkflowDocument(docs, "项目建议书", "", nil)
|
|
if err != nil {
|
|
t.Fatalf("legacy passthrough: %v", err)
|
|
}
|
|
if doc.TaskKey != "rd_proposal" {
|
|
t.Fatalf("want rd_proposal, got %s", doc.TaskKey)
|
|
}
|
|
}
|