151 lines
3.5 KiB
Go
151 lines
3.5 KiB
Go
package server
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"chat-agent-system/internal/bizdev"
|
|
"chat-agent-system/internal/chat"
|
|
"chat-agent-system/internal/config"
|
|
"chat-agent-system/internal/stream"
|
|
)
|
|
|
|
func newTestServer() *Server {
|
|
cfg := &config.Config{
|
|
Env: "test",
|
|
AgentBackend: "stub",
|
|
DataDir: "./data/test",
|
|
KbDbPort: 5432,
|
|
}
|
|
svc := bizdev.NewService(cfg)
|
|
return NewServer(cfg, svc)
|
|
}
|
|
|
|
func TestServer_Health(t *testing.T) {
|
|
srv := newTestServer()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/health", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
srv.Routes().ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", w.Code)
|
|
}
|
|
|
|
var resp HealthResponse
|
|
if err := json.NewDecoder(w.Body).Decode(&resp); err != nil {
|
|
t.Fatalf("decode response failed: %v", err)
|
|
}
|
|
|
|
if resp.Status != "ok" || resp.Env != "test" {
|
|
t.Errorf("unexpected health response: %+v", resp)
|
|
}
|
|
}
|
|
|
|
func TestServer_ChatBlocking(t *testing.T) {
|
|
srv := newTestServer()
|
|
|
|
chatReq := ChatRequest{
|
|
SessionID: "test_sess_01",
|
|
Message: "查一下当前进展",
|
|
ProjectName: "内窥镜研发项目",
|
|
CustomerName: "水木东方",
|
|
}
|
|
body, _ := json.Marshal(chatReq)
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/chat", bytes.NewReader(body))
|
|
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 chat response failed: %v", err)
|
|
}
|
|
|
|
if resp.ReplyText == "" {
|
|
t.Errorf("expected non-empty reply text")
|
|
}
|
|
}
|
|
|
|
func TestServer_ChatSSEStream(t *testing.T) {
|
|
srv := newTestServer()
|
|
|
|
chatReq := StreamChatRequest{
|
|
SessionID: "test_sess_sse",
|
|
Message: "查一下当前进展",
|
|
IncludeDetails: false,
|
|
ProjectName: "内窥镜研发项目",
|
|
CustomerName: "水木东方",
|
|
}
|
|
body, _ := json.Marshal(chatReq)
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/chat/stream", bytes.NewReader(body))
|
|
w := httptest.NewRecorder()
|
|
|
|
srv.Routes().ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", w.Code)
|
|
}
|
|
|
|
contentType := w.Header().Get("Content-Type")
|
|
if !strings.Contains(contentType, "text/event-stream") {
|
|
t.Fatalf("expected Content-Type text/event-stream, got %s", contentType)
|
|
}
|
|
|
|
// 解析 SSE 事件流
|
|
scanner := bufio.NewScanner(w.Body)
|
|
var currentEvent string
|
|
var eventsReceived []string
|
|
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if strings.HasPrefix(line, "event: ") {
|
|
currentEvent = strings.TrimPrefix(line, "event: ")
|
|
} else if strings.HasPrefix(line, "data: ") {
|
|
dataStr := strings.TrimPrefix(line, "data: ")
|
|
var ev stream.StreamEvent
|
|
if err := json.Unmarshal([]byte(dataStr), &ev); err == nil {
|
|
eventsReceived = append(eventsReceived, currentEvent)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(eventsReceived) == 0 {
|
|
t.Fatalf("expected to receive SSE events, got 0")
|
|
}
|
|
|
|
hasPhase := false
|
|
hasStatus := false
|
|
hasDone := false
|
|
|
|
for _, et := range eventsReceived {
|
|
switch et {
|
|
case "phase":
|
|
hasPhase = true
|
|
case "status":
|
|
hasStatus = true
|
|
case "done":
|
|
hasDone = true
|
|
}
|
|
}
|
|
|
|
if !hasPhase {
|
|
t.Errorf("expected phase event in SSE stream")
|
|
}
|
|
if !hasStatus {
|
|
t.Errorf("expected status event in SSE stream")
|
|
}
|
|
if !hasDone {
|
|
t.Errorf("expected done event in SSE stream")
|
|
}
|
|
}
|