Files
nexarch/ai/internal/summaryapi/summaryapi_test.go
2026-09-26 01:06:17 +00:00

121 lines
4.2 KiB
Go

package summaryapi_test
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"gitea.perlbach24.de/scripte/nexarch/ai/internal/provider"
"gitea.perlbach24.de/scripte/nexarch/ai/internal/summarize"
"gitea.perlbach24.de/scripte/nexarch/ai/internal/summaryapi"
"gitea.perlbach24.de/scripte/nexarch/ai/internal/threadsummarize"
)
type fixedProvider struct{ summary string }
func (p *fixedProvider) Chat(context.Context, provider.ChatRequest) (provider.ChatResponse, error) {
return provider.ChatResponse{Message: provider.Message{Content: p.summary}}, nil
}
func (p *fixedProvider) Complete(context.Context, provider.CompletionRequest) (provider.CompletionResponse, error) {
return provider.CompletionResponse{}, nil
}
func (p *fixedProvider) Embed(context.Context, provider.EmbeddingRequest) (provider.EmbeddingResponse, error) {
return provider.EmbeddingResponse{}, nil
}
func newTestServer() *summaryapi.Server {
prov := &fixedProvider{summary: "Kurzfassung des Textes."}
docSum := &summarize.Summarizer{Provider: prov, Model: "test-model"}
threadSum := &threadsummarize.Summarizer{Provider: prov, Model: "test-model"}
return summaryapi.NewServer(docSum, threadSum, "geheimes-token")
}
// AK1 (Dokument): eine gueltige Anfrage mit Service-Token liefert eine
// Zusammenfassung.
func TestHandleDocumentSummarize_ReturnsSummary(t *testing.T) {
mux := http.NewServeMux()
newTestServer().RegisterRoutes(mux)
body, _ := json.Marshal(map[string]any{"text": "Ein Beispieldokument mit Inhalt.", "max_words": 50})
req := httptest.NewRequest(http.MethodPost, "/documents/summarize", bytes.NewReader(body))
req.Header.Set("X-Service-Token", "geheimes-token")
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("erwartet 200, bekommen %d: %s", rec.Code, rec.Body.String())
}
var resp map[string]any
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
t.Fatalf("antwort nicht json: %v", err)
}
if resp["summary"] != "Kurzfassung des Textes." {
t.Fatalf("unerwartete zusammenfassung: %v", resp["summary"])
}
}
func TestHandleDocumentSummarize_RequiresServiceToken(t *testing.T) {
mux := http.NewServeMux()
newTestServer().RegisterRoutes(mux)
body, _ := json.Marshal(map[string]any{"text": "Text"})
req := httptest.NewRequest(http.MethodPost, "/documents/summarize", bytes.NewReader(body))
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusUnauthorized {
t.Fatalf("erwartet 401 ohne service-token, bekommen %d", rec.Code)
}
}
// AK1 (Thread): eine gueltige Thread-Anfrage liefert eine Zusammenfassung
// samt Referenz auf die letzte Nachricht (Grundlage fuer den Rueckbezug,
// AK2, in der Oberflaeche).
func TestHandleThreadSummarize_ReturnsSummaryWithLastMessageRef(t *testing.T) {
mux := http.NewServeMux()
newTestServer().RegisterRoutes(mux)
body, _ := json.Marshal(map[string]any{
"messages": []map[string]any{
{"id": "msg-1", "from": "a@example.com", "body": "Erste Nachricht"},
{"id": "msg-2", "from": "b@example.com", "body": "Zweite Nachricht"},
},
})
req := httptest.NewRequest(http.MethodPost, "/threads/summarize", bytes.NewReader(body))
req.Header.Set("X-Service-Token", "geheimes-token")
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("erwartet 200, bekommen %d: %s", rec.Code, rec.Body.String())
}
var resp map[string]any
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
t.Fatalf("antwort nicht json: %v", err)
}
if resp["last_message_id"] != "msg-2" {
t.Fatalf("erwartet last_message_id msg-2, bekommen %v", resp["last_message_id"])
}
if resp["message_count"] != float64(2) {
t.Fatalf("erwartet message_count 2, bekommen %v", resp["message_count"])
}
}
func TestHandleThreadSummarize_EmptyThreadIsRejected(t *testing.T) {
mux := http.NewServeMux()
newTestServer().RegisterRoutes(mux)
body, _ := json.Marshal(map[string]any{"messages": []map[string]any{}})
req := httptest.NewRequest(http.MethodPost, "/threads/summarize", bytes.NewReader(body))
req.Header.Set("X-Service-Token", "geheimes-token")
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusBadRequest {
t.Fatalf("erwartet 400 bei leerem thread, bekommen %d", rec.Code)
}
}