Files
Agent-System/internal/server/chat_document_reader_test.go
T
weichenandCursor 976f8d30b8 feat(server): allow weighted cross-workflow reads after a view check
Exact out-of-workflow documents can be summarized when WORKFLOW_SCOPE_MODE=weighted and the caller can still view the active instance; writes stay blocked.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-21 09:11:47 +00:00

122 lines
4.2 KiB
Go

package server
import (
"errors"
"strings"
"testing"
"chat-agent-system/internal/coordinator"
"chat-agent-system/internal/docgov"
"chat-agent-system/internal/projectinstance"
"chat-agent-system/internal/workflowscope"
)
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)
}
}
func TestSelectReadableWeightedAllowsExactCrossRead(t *testing.T) {
workflowscope.SetModeForTest(workflowscope.ModeWeighted)
t.Cleanup(workflowscope.ResetModeForTest)
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}
doc, err := selectReadableWorkflowDocument(docs, "项目建议书", "main", scope)
if err != nil {
t.Fatalf("weighted cross read: %v", err)
}
if doc.TaskKey != "rd_proposal" {
t.Fatalf("want rd_proposal, got %s", doc.TaskKey)
}
inScope, err := selectReadableWorkflowDocument(docs, "调研报告", "main", scope)
if err != nil || inScope.TaskKey != "bd_research" {
t.Fatalf("in-scope still wins: %v %v", inScope, err)
}
}
func TestCrossWorkflowTaskVisible(t *testing.T) {
open := &projectinstance.StageAccess{
Restricted: true,
ViewableTaskKeys: map[string]bool{"bd_research": true},
}
scope := map[string]bool{"bd_research": true, "bd_hidden": true}
if !crossWorkflowTaskVisible(open, scope, "rd_proposal") {
t.Fatal("foreign key should be readable when the caller can view the active instance")
}
if crossWorkflowTaskVisible(open, scope, "bd_hidden") {
t.Fatal("in-scope but not viewable must be denied")
}
closed := &projectinstance.StageAccess{Restricted: true, ViewableTaskKeys: map[string]bool{}}
if crossWorkflowTaskVisible(closed, scope, "rd_proposal") {
t.Fatal("closed instance must deny cross read")
}
if !crossWorkflowTaskVisible(nil, scope, "rd_proposal") {
t.Fatal("unrestricted access must allow")
}
}