Files
Agent-System/internal/chat/action_executor_test.go
weichen b5a782bb38 feat(chat): dialogue triggers for comments/reopen/pending-supplements with mistouch guards
Wire intent→coordinator DocResolver confirm cards→action_executor kinds for comment, reopen, pending-supplements query, and real submit-review execution.
2026-09-25 20:14:10 +00:00

161 lines
4.9 KiB
Go

package chat
import (
"context"
"fmt"
"strings"
"testing"
"chat-agent-system/internal/bizdev"
"chat-agent-system/internal/config"
"chat-agent-system/internal/coordinator"
"chat-agent-system/internal/docgov"
)
func TestExecuteAction_DocGovReviewApprove(t *testing.T) {
cfg := &config.Config{DataDir: t.TempDir()}
svc := bizdev.MustNewService(t, cfg)
docGov := bizdev.Snapshot(svc).Gov
ctx := context.Background()
docID := "doc_proj1_research"
_, err := docGov.CreateOrGetDocument(
ctx, docID, 1, "research", "调研报告", "V0.5", "",
1, "张工", 2, "李主管", 3, "王总监",
)
if err != nil {
t.Fatalf("CreateOrGetDocument: %v", err)
}
_ = docGov.MarkDocumentContentUpdated(ctx, docID, "hash1", false)
_, _ = docGov.SubmitForReview(ctx, docID, 1, docgov.RoleAuthor, "张工")
sess := &Session{
UserID: 2,
Actions: &ActionServices{DocGov: docGov},
}
action := &coordinator.PendingAction{
Kind: "docgov.review_approve",
DocID: docID,
Comment: "同意",
}
userCtx := &coordinator.UserProjectContext{
User: coordinator.UserInfo{ID: "2", Name: "李主管"},
}
result, err := sess.executeAction(ctx, action, userCtx)
if err != nil {
t.Fatalf("executeAction failed: %v", err)
}
if result.DocState != string(docgov.StateApproving) {
t.Fatalf("expected approving state, got %s", result.DocState)
}
reply := renderActionReply(action, result, nil)
if reply == "" {
t.Fatal("expected non-empty reply")
}
}
func TestExecuteAction_SubmitReviewAndComment(t *testing.T) {
cfg := &config.Config{DataDir: t.TempDir()}
svc := bizdev.MustNewService(t, cfg)
docGov := bizdev.Snapshot(svc).Gov
ctx := context.Background()
docID := "doc_proj1_intake"
_, err := docGov.CreateOrGetDocument(
ctx, docID, 1, "intake", "需求收集表", "V0.1", "",
1, "张工", 2, "李主管", 3, "王总监",
)
if err != nil {
t.Fatalf("create: %v", err)
}
_ = docGov.MarkDocumentContentUpdated(ctx, docID, "hash1", false)
sess := &Session{UserID: 1, ProjectID: 1, Actions: &ActionServices{DocGov: docGov}}
userCtx := &coordinator.UserProjectContext{User: coordinator.UserInfo{ID: "1", Name: "张工"}}
res, err := sess.executeAction(ctx, &coordinator.PendingAction{Kind: "docgov.submit_review", DocID: docID}, userCtx)
if err != nil {
t.Fatalf("submit: %v", err)
}
if res.DocState != string(docgov.StateReviewing) {
t.Fatalf("state=%s", res.DocState)
}
_, err = sess.executeAction(ctx, &coordinator.PendingAction{
Kind: "docgov.comment_add", DocID: docID, Role: "reviewer", Section: "s1",
Comment: "请补充风险", Reason: "suggestion",
}, &coordinator.UserProjectContext{User: coordinator.UserInfo{ID: "2", Name: "李主管"}})
if err != nil {
// author can also comment in reviewing; use reviewer id
t.Fatalf("comment add: %v", err)
}
sess.UserID = 2
_, err = sess.executeAction(ctx, &coordinator.PendingAction{
Kind: "docgov.comment_resolve", DocID: docID, Role: "reviewer", Section: "s1",
}, &coordinator.UserProjectContext{User: coordinator.UserInfo{ID: "2", Name: "李主管"}})
if err != nil {
t.Fatalf("comment resolve: %v", err)
}
}
type stubReopen struct {
reqErr error
aprErr error
}
func (s *stubReopen) ListPendingReopens(context.Context, int64) ([]ReopenRequestView, error) {
return nil, nil
}
func (s *stubReopen) RequestReopenByDoc(context.Context, int64, string, string, int64) (ReopenRequestView, error) {
if s.reqErr != nil {
return ReopenRequestView{}, s.reqErr
}
return ReopenRequestView{ID: 9, Status: "pending"}, nil
}
func (s *stubReopen) ApproveReopenByID(context.Context, int64, int64, int64) (ReopenRequestView, error) {
if s.aprErr != nil {
return ReopenRequestView{}, s.aprErr
}
return ReopenRequestView{ID: 9, Status: "approved"}, nil
}
func TestExecuteAction_ReopenPaths(t *testing.T) {
sess := &Session{
UserID: 1, ProjectID: 1,
Actions: &ActionServices{Reopens: &stubReopen{}},
}
userCtx := &coordinator.UserProjectContext{User: coordinator.UserInfo{ID: "1", Name: "A"}}
res, err := sess.executeAction(context.Background(), &coordinator.PendingAction{
Kind: "docgov.reopen_request", TaskKey: "intake", Reason: "需补充",
}, userCtx)
if err != nil {
t.Fatal(err)
}
if res.Message == "" {
t.Fatal("expected message")
}
res, err = sess.executeAction(context.Background(), &coordinator.PendingAction{
Kind: "docgov.reopen_approve", RequestID: 9,
}, userCtx)
if err != nil {
t.Fatal(err)
}
if res.Message == "" {
t.Fatal("expected approve message")
}
sess.Actions.Reopens = &stubReopen{reqErr: fmt.Errorf("无权申请重开")}
_, err = sess.executeAction(context.Background(), &coordinator.PendingAction{
Kind: "docgov.reopen_request", TaskKey: "intake", Reason: "x",
}, userCtx)
if err == nil {
t.Fatal("expected permission failure")
}
reply := renderActionReply(&coordinator.PendingAction{Kind: "docgov.reopen_request", DocID: "d"}, nil, err)
if reply == "" || !strings.Contains(reply, "无权") {
t.Fatalf("reply=%s", reply)
}
}