141 lines
4.2 KiB
Go
141 lines
4.2 KiB
Go
package coordinator
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"chat-agent-system/internal/intent"
|
|
)
|
|
|
|
func TestClassifyRejectUtterance(t *testing.T) {
|
|
cases := []struct {
|
|
in string
|
|
want RejectUtteranceIntent
|
|
}{
|
|
{"注册路径可行性评估报告被驳回的原因是什么", RejectUtteranceQuery},
|
|
{"为什么被退回了", RejectUtteranceQuery},
|
|
{"把调研报告审核驳回,意见为:缺少抗扰度", RejectUtteranceExecute},
|
|
{"请驳回这份文档", RejectUtteranceExecute},
|
|
{"驳回了吗", RejectUtteranceOther},
|
|
}
|
|
for _, c := range cases {
|
|
got := ClassifyRejectUtterance(c.in)
|
|
if got != c.want {
|
|
t.Errorf("%q: got %s want %s", c.in, got, c.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestResolveRejectCard_AuthorQuery(t *testing.T) {
|
|
res := ResolveRejectCard("author", "drafting", "doc-feas", "可行性报告", "",
|
|
"缺少 YY 9706.102 电磁兼容专项", RejectUtteranceQuery)
|
|
if res.Kind != "reject_reason_info" {
|
|
t.Fatalf("kind=%s", res.Kind)
|
|
}
|
|
if res.Card == nil || res.Card.CardType != "REMINDER_NOTICE" {
|
|
t.Fatalf("expected REMINDER_NOTICE card")
|
|
}
|
|
for _, a := range res.Card.Actions {
|
|
if a.ActionID == "confirm_reject" {
|
|
t.Fatal("author query card must not include confirm_reject")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestResolveRejectCard_ReviewerExecute(t *testing.T) {
|
|
res := ResolveRejectCard("reviewer", "reviewing", "doc-002", "调研", "第3节",
|
|
"缺少抗扰度", RejectUtteranceExecute)
|
|
if res.Kind != "reject_confirm_review" {
|
|
t.Fatalf("kind=%s", res.Kind)
|
|
}
|
|
if res.Card == nil || len(res.Card.Actions) < 2 {
|
|
t.Fatal("expected confirm card with actions")
|
|
}
|
|
if res.Card.Actions[0].Label != "确认驳回退回编制" {
|
|
t.Errorf("label=%s", res.Card.Actions[0].Label)
|
|
}
|
|
if res.Card.Actions[1].Label != "放弃驳回" {
|
|
t.Errorf("cancel label=%s", res.Card.Actions[1].Label)
|
|
}
|
|
}
|
|
|
|
func TestResolveRejectCard_AuthorExecuteDenied(t *testing.T) {
|
|
res := ResolveRejectCard("author", "reviewing", "doc-feas", "可行性报告", "",
|
|
"", RejectUtteranceExecute)
|
|
if res.Kind != "deny_text" {
|
|
t.Fatalf("kind=%s", res.Kind)
|
|
}
|
|
if res.Card != nil {
|
|
t.Fatal("expected no card")
|
|
}
|
|
if !strings.Contains(res.Reply, "不具备") {
|
|
t.Errorf("reply=%s", res.Reply)
|
|
}
|
|
}
|
|
|
|
func TestHandleDocGovReject_UnauthorizedAuthor(t *testing.T) {
|
|
engine := NewCoordinatorEngine(nil)
|
|
userCtx := &UserProjectContext{
|
|
User: UserInfo{ID: "u1", Name: "张工", Role: "author", ProjectRole: "author"},
|
|
Project: ProjectInfo{Name: "NeuroPulse"},
|
|
}
|
|
recRes := &intent.IntentRecognitionResult{
|
|
TopIntent: &intent.CandidateIntent{
|
|
Intent: intent.IntentDocGovReviewReject,
|
|
FilledSlots: map[string]string{
|
|
intent.SlotTargetDoc: "doc-feas",
|
|
intent.SlotRejectReason: "测试意见",
|
|
},
|
|
},
|
|
}
|
|
res, err := engine.ProcessIntent(context.Background(), recRes, userCtx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if res.Status != StatusRejected {
|
|
t.Fatalf("status=%s", res.Status)
|
|
}
|
|
if res.InteractiveCard != nil {
|
|
t.Fatal("unauthorized must not mount reject confirm card")
|
|
}
|
|
if res.RejectReason != "UNAUTHORIZED_REJECT_ROLE" {
|
|
t.Errorf("RejectReason=%s", res.RejectReason)
|
|
}
|
|
}
|
|
|
|
func TestHandleQueryRejectReason_AuthorInfoCard(t *testing.T) {
|
|
engine := NewCoordinatorEngine(nil)
|
|
userCtx := &UserProjectContext{
|
|
User: UserInfo{ID: "u1", Name: "张工", Role: "author", ProjectRole: "author"},
|
|
Project: ProjectInfo{Name: "NeuroPulse"},
|
|
BlackboardFacts: map[string]string{
|
|
"last_reject_reason": "缺少 YY 9706.102 电磁兼容专项与听神经保护方案,退回修改",
|
|
},
|
|
}
|
|
recRes := &intent.IntentRecognitionResult{
|
|
TopIntent: &intent.CandidateIntent{
|
|
Intent: intent.IntentQueryRejectReason,
|
|
FilledSlots: map[string]string{intent.SlotTargetDoc: "可行性报告"},
|
|
},
|
|
}
|
|
res, err := engine.ProcessIntent(context.Background(), recRes, userCtx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if res.Status != StatusAccepted {
|
|
t.Fatalf("status=%s", res.Status)
|
|
}
|
|
if res.InteractiveCard == nil || res.InteractiveCard.CardType != "REMINDER_NOTICE" {
|
|
t.Fatalf("expected info card, got %+v", res.InteractiveCard)
|
|
}
|
|
for _, a := range res.InteractiveCard.Actions {
|
|
if a.ActionID == "confirm_reject" {
|
|
t.Fatal("must not expose confirm_reject")
|
|
}
|
|
}
|
|
if !strings.Contains(res.NaturalReply, "YY 9706.102") {
|
|
t.Errorf("reply=%s", res.NaturalReply)
|
|
}
|
|
}
|