From deaec82a7cb5ff1c6ce9e8420adae4078f000d65 Mon Sep 17 00:00:00 2001 From: weichen Date: Sun, 13 Sep 2026 04:29:17 +0000 Subject: [PATCH] test(chat): cover readonly summary HTTP path --- internal/server/server_test.go | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/internal/server/server_test.go b/internal/server/server_test.go index aadb09c1..748ea870 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -3,9 +3,14 @@ package server import ( "bufio" "bytes" + "context" + "crypto/sha256" "encoding/json" + "fmt" "net/http" "net/http/httptest" + "os" + "path/filepath" "strings" "testing" @@ -80,6 +85,57 @@ func TestServer_ChatBlocking(t *testing.T) { } } +func TestServer_ChatDocumentSummaryReadsExistingDocumentWithoutWriteAction(t *testing.T) { + srv := newTestServer(t) + ctx := context.Background() + workDir := t.TempDir() + markdown := []byte("# 用户初始需求收集表\n\n## 核心需求\n确认临床使用场景。\n\n## 待确认\n目标市场尚待确认。\n") + if err := os.WriteFile(filepath.Join(workDir, "output.md"), markdown, 0o644); err != nil { + t.Fatalf("write output.md: %v", err) + } + if _, err := srv.svc.DocGov().CreateOrGetDocument( + ctx, "doc_proj143_intake", 143, "intake", "用户初始需求收集表", "V0.1_triage", workDir, + 1, "编制人", 1, "审核人", 1, "批准人", + ); err != nil { + t.Fatalf("create document: %v", err) + } + hash := fmt.Sprintf("%x", sha256.Sum256(markdown)) + if err := srv.svc.DocGov().MarkDocumentContentUpdated(ctx, "doc_proj143_intake", hash, false); err != nil { + t.Fatalf("mark content: %v", err) + } + + body, _ := json.Marshal(ChatRequest{ + SessionID: "fixture-doc-summary", + Message: "总结一下用户初始需求表", + ProjectID: 143, + ProjectName: "隔离验收项目", + }) + req := httptest.NewRequest(http.MethodPost, "/api/v1/chat", bytes.NewReader(body)) + withBearerAuth(req, loginTestAdmin(t, srv)) + w := httptest.NewRecorder() + srv.Routes().ServeHTTP(w, req) + if w.Code != http.StatusOK { + t.Fatalf("expected status 200, got %d: %s", w.Code, w.Body.String()) + } + + var resp chat.ChatResponse + if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { + t.Fatalf("decode response: %v", err) + } + if resp.IntentResult == nil || resp.IntentResult.TopIntent == nil || resp.IntentResult.TopIntent.Intent != "QUERY_DOC_STATUS" { + t.Fatalf("unexpected intent: %+v", resp.IntentResult) + } + if got := resp.IntentResult.TopIntent.FilledSlots["query_topic"]; got != "doc_summary" { + t.Fatalf("query_topic=%q", got) + } + if resp.CoordinationResult == nil || resp.CoordinationResult.PendingAction != nil { + t.Fatalf("summary must not expose a write action: %+v", resp.CoordinationResult) + } + if !strings.Contains(resp.ReplyText, "目标市场") || !strings.Contains(resp.ReplyText, "用户初始需求收集表") { + t.Fatalf("reply does not summarize existing content: %s", resp.ReplyText) + } +} + func TestServer_ChatSSEStream(t *testing.T) { srv := newTestServer(t)