Composition roots copy Parts once so HTTP/CLI handlers stop calling locator getters on every request. Co-authored-by: Cursor <cursoragent@cursor.com>
128 lines
4.1 KiB
Go
128 lines
4.1 KiB
Go
package bizdev
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"chat-agent-system/internal/config"
|
|
"chat-agent-system/internal/docrevision"
|
|
)
|
|
|
|
func activityTitles(t *testing.T, svc *Service, projectID int64) []string {
|
|
t.Helper()
|
|
pCtx, err := svc.ctxMgr.GetProjectContext(context.Background(), projectID)
|
|
if err != nil {
|
|
t.Fatalf("GetProjectContext: %v", err)
|
|
}
|
|
var titles []string
|
|
for _, a := range pCtx.AllActivities {
|
|
titles = append(titles, a.Title)
|
|
}
|
|
return titles
|
|
}
|
|
|
|
func TestExecuteTask_MaterializeFailure_DoesNotRecordCompletedActivity(t *testing.T) {
|
|
svc := MustNewService(t, &config.Config{DataDir: t.TempDir(), AgentBackend: "stub"})
|
|
ctx := context.Background()
|
|
svc.docRev.AgentCommit = false
|
|
projectID := int64(5601)
|
|
|
|
res, err := svc.ExecuteTask(ctx, TaskRunRequest{
|
|
TaskKey: "research", ProjectID: projectID, ProjectName: "P",
|
|
CustomerName: "C", DeviceType: "医疗器械", Backend: "stub",
|
|
Timeout: 10 * time.Second, DocID: "doc-act-fail", UserID: 1,
|
|
})
|
|
if err == nil || res == nil || res.Success {
|
|
t.Fatalf("want materialize failure, err=%v res=%+v", err, res)
|
|
}
|
|
for _, title := range activityTitles(t, svc, projectID) {
|
|
if strings.Contains(title, "完成交付物") {
|
|
t.Fatalf("must not record completion activity on materialize failure: %q", title)
|
|
}
|
|
if strings.Contains(title, "待编制人确认") {
|
|
t.Fatalf("must not record pending activity on materialize failure: %q", title)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestExecuteTask_PendingConfirmation_RecordsAwaitingNotCompleted(t *testing.T) {
|
|
dataDir := t.TempDir()
|
|
svc := MustNewService(t, &config.Config{DataDir: dataDir, AgentBackend: "stub"})
|
|
ctx := context.Background()
|
|
projectID := int64(5602)
|
|
docID := "doc_act_pending"
|
|
workDir := filepath.Join(dataDir, "ws-act-pending")
|
|
if err := os.MkdirAll(workDir, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
base := "# base\n\n法规引用 GB9706\n"
|
|
if _, err := svc.docRev.OpenTemplateVersion(ctx, docID, base, docrevision.ActorSnapshot{DisplayName: "t"}, projectID, workDir); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := svc.docGov.CreateOrGetDocument(ctx, docID, projectID, "research", "调研报告", "V0.5", workDir, 1, "a", 2, "r", 3, "p"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Stub output omits 法规 → deterministic high risk → needs_confirmation.
|
|
res, err := svc.ExecuteTask(ctx, TaskRunRequest{
|
|
TaskKey: "research", ProjectID: projectID, ProjectName: "P",
|
|
CustomerName: "C", DeviceType: "医疗器械", Backend: "stub",
|
|
Timeout: 10 * time.Second, DocID: docID, UserID: 1, WorkDir: workDir,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("ExecuteTask: %v", err)
|
|
}
|
|
if res == nil || !res.AwaitsAgentConfirmation() {
|
|
t.Fatalf("want pending confirmation, got success=%v pending=%d reason=%s",
|
|
res != nil && res.Success, res.PendingAgentCandidateID, res.ErrorReason)
|
|
}
|
|
|
|
titles := activityTitles(t, svc, projectID)
|
|
foundPending, foundCompleted := false, false
|
|
for _, title := range titles {
|
|
if strings.Contains(title, "待编制人确认") {
|
|
foundPending = true
|
|
}
|
|
if strings.Contains(title, "完成交付物") {
|
|
foundCompleted = true
|
|
}
|
|
}
|
|
if !foundPending {
|
|
t.Fatalf("expected pending activity, titles=%v", titles)
|
|
}
|
|
if foundCompleted {
|
|
t.Fatalf("pending must not record 完成交付物, titles=%v", titles)
|
|
}
|
|
}
|
|
|
|
func TestExecuteTask_Committed_RecordsCompletedActivity(t *testing.T) {
|
|
svc := MustNewService(t, &config.Config{DataDir: t.TempDir(), AgentBackend: "stub"})
|
|
ctx := context.Background()
|
|
projectID := int64(5603)
|
|
res, err := svc.ExecuteTask(ctx, TaskRunRequest{
|
|
TaskKey: "intake", ProjectID: projectID, ProjectName: "P",
|
|
CustomerName: "C", DeviceType: "医疗器械", Backend: "stub",
|
|
Timeout: 10 * time.Second, DocID: "doc_act_ok", UserID: 1,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("ExecuteTask: %v reason=%v", err, res)
|
|
}
|
|
if res.AwaitsAgentConfirmation() {
|
|
t.Fatal("first-gen intake should auto-commit, not pending")
|
|
}
|
|
found := false
|
|
for _, title := range activityTitles(t, svc, projectID) {
|
|
if strings.Contains(title, "完成交付物") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected 完成交付物 after committed materialize")
|
|
}
|
|
}
|