Files
Agent-System/internal/server/chat_search_and_digest_api_test.go
T
weichenandCursor 3f42149457 feat(bizdev): snapshot collaborators onto Runtime and Server ports
Composition roots copy Parts once so HTTP/CLI handlers stop calling locator getters on every request.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 13:00:33 +00:00

114 lines
3.3 KiB
Go

package server_test
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"chat-agent-system/internal/bizdev"
"chat-agent-system/internal/config"
"chat-agent-system/internal/ctxmgr"
"chat-agent-system/internal/server"
)
func TestServer_ChatSearchAndDigestAPIs(t *testing.T) {
cfg := &config.Config{
Env: "dev",
HTTPHost: "127.0.0.1",
HTTPPort: 8890,
DataDir: t.TempDir(),
}
svc := bizdev.MustNewService(t, cfg)
srv := server.NewServer(cfg, svc)
handler := srv.Routes()
sessID := "sess_api_search_digest_001"
dayKey := "2026-09-09"
// 注入种子消息
ctx := t.Context()
ctxMgr := bizdev.Snapshot(svc).Ctx
_, _ = ctxMgr.RecordUserMessageWithID(ctx, sessID, 1, "user", "我们启动超声探头研发预算,计划投入150万元", "TRIGGER_TASK", "", map[string]any{
"day_key": dayKey,
})
_, _ = ctxMgr.RecordUserMessageWithID(ctx, sessID, 0, "assistant", "已确认150万预算,主攻探头阵元与外壳生物相容性测试", "DOCGOV_REVIEW", "", map[string]any{
"day_key": dayKey,
"milestone": true,
"doc_title": "超声探头立项规格书",
})
t.Run("GET /api/v1/chat/search 正常检索", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/api/v1/chat/search?session_id="+sessID+"&q=150万", nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200 OK, got %d: %s", w.Code, w.Body.String())
}
var hits []ctxmgr.ChatSearchHit
if err := json.NewDecoder(w.Body).Decode(&hits); err != nil {
t.Fatalf("decode hits failed: %v", err)
}
if len(hits) != 2 {
t.Fatalf("expected 2 hits, got %d", len(hits))
}
})
t.Run("GET /api/v1/chat/search 缺少参数400拦截", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/api/v1/chat/search?session_id="+sessID, nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusBadRequest {
t.Errorf("expected 400 Bad Request for missing q, got %d", w.Code)
}
})
t.Run("POST /api/v1/chat/digests/generate 触发生成", func(t *testing.T) {
body := map[string]string{
"session_id": sessID,
"day_key": dayKey,
}
jsonBytes, _ := json.Marshal(body)
req := httptest.NewRequest(http.MethodPost, "/api/v1/chat/digests/generate", bytes.NewReader(jsonBytes))
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200 OK, got %d: %s", w.Code, w.Body.String())
}
var res map[string]any
if err := json.NewDecoder(w.Body).Decode(&res); err != nil {
t.Fatalf("decode generate response failed: %v", err)
}
if res["queued"] != true {
t.Errorf("expected queued=true, got %v", res["queued"])
}
})
t.Run("GET /api/v1/chat/digests 查询列表", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/api/v1/chat/digests?session_id="+sessID, nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200 OK, got %d: %s", w.Code, w.Body.String())
}
var digests []ctxmgr.DailyDigest
if err := json.NewDecoder(w.Body).Decode(&digests); err != nil {
t.Fatalf("decode digests failed: %v", err)
}
if len(digests) != 1 {
t.Fatalf("expected 1 digest, got %d", len(digests))
}
if digests[0].DayKey != dayKey {
t.Errorf("expected dayKey %s, got %s", dayKey, digests[0].DayKey)
}
})
}