Files
Agent-System/internal/projectinstance/workflow_scope_test.go
T
weichenandCursor 0912efdbd9 feat(coordinator+server): narrow document match pool to active workflow
- 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>
2026-09-21 08:05:44 +00:00

46 lines
1.4 KiB
Go

package projectinstance_test
import (
"context"
"testing"
"chat-agent-system/internal/projectinstance"
)
func TestActiveWorkflowScope_NoLiveInstanceReturnsEmpty(t *testing.T) {
store := projectinstance.NewMemoryStore()
if err := projectinstance.SeedProjectMeta(store, 99, projectinstance.LifecyclePlanning, "", 1, 0); err != nil {
t.Fatalf("seed: %v", err)
}
svc := projectinstance.NewService(store, projectinstance.TestResolver(), nil, nil)
key, tasks, err := svc.ActiveWorkflowScope(context.Background(), 99)
if err != nil {
t.Fatalf("scope: %v", err)
}
if key != "" || tasks != nil {
t.Fatalf("unactivated project must return empty scope, got key=%q tasks=%v", key, tasks)
}
}
func TestTaskKeyInScope_EmptyAllowsAll(t *testing.T) {
if !projectinstance.TaskKeyInScope(nil, "anything") {
t.Fatal("nil scope must allow")
}
if !projectinstance.TaskKeyInScope(map[string]bool{}, "anything") {
t.Fatal("empty scope must allow")
}
}
func TestTaskKeyInScope_CanonicalAlias(t *testing.T) {
scope := map[string]bool{"bd_research": true, "research": true}
if !projectinstance.TaskKeyInScope(scope, "research") {
t.Fatal("legacy alias research should be in scope")
}
if !projectinstance.TaskKeyInScope(scope, "bd_research") {
t.Fatal("canonical bd_research should be in scope")
}
if projectinstance.TaskKeyInScope(scope, "rd_proposal") {
t.Fatal("rd_proposal must be out of scope")
}
}