Files
ai-gateway-go/internal/factcheck/service_integration_test.go
superidou 5759c1862e AI Gateway Go 0.10.0 源码快照 + 旗舰版需求规划报告
M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。
含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-12 11:45:54 +08:00

101 lines
3.7 KiB
Go

package factcheck
import (
"context"
"encoding/json"
"os"
"testing"
"aigateway.local/core/internal/platform/config"
"aigateway.local/core/internal/platform/database"
)
func TestFactCheckPostgreSQLLifecycle(t *testing.T) {
databaseURL := os.Getenv("FACTCHECK_TEST_DATABASE_URL")
if databaseURL == "" {
t.Skip("FACTCHECK_TEST_DATABASE_URL is not set")
}
ctx := context.Background()
pool, err := database.Open(ctx, config.Database{URL: databaseURL, MaxConns: 4})
if err != nil {
t.Fatal(err)
}
defer pool.Close()
const actorID = "33333333-3333-4333-8333-333333333333"
const knowledgeBaseID = "44444444-4444-4444-8444-444444444444"
const eventID = "55555555-5555-4555-8555-555555555555"
_, err = pool.Exec(ctx, `INSERT INTO gateway.admin_accounts(id,username,password_hash,role)
VALUES($1,'factcheck-test-admin','test','superadmin') ON CONFLICT(id) DO NOTHING`, actorID)
if err != nil {
t.Fatal(err)
}
cleanup := func() {
_, _ = pool.Exec(ctx, `DELETE FROM gateway.fact_check_events WHERE id=$1`, eventID)
_, _ = pool.Exec(ctx, `DELETE FROM gateway.fact_check_policies WHERE scope='global'`)
_, _ = pool.Exec(ctx, `DELETE FROM gateway.knowledge_bases WHERE id=$1`, knowledgeBaseID)
_, _ = pool.Exec(ctx, `UPDATE gateway.fact_check_settings SET provider_id=NULL,model='',updated_by=NULL`)
_, _ = pool.Exec(ctx, `DELETE FROM gateway.admin_accounts WHERE id=$1`, actorID)
}
cleanup()
_, err = pool.Exec(ctx, `INSERT INTO gateway.admin_accounts(id,username,password_hash,role)
VALUES($1,'factcheck-test-admin','test','superadmin') ON CONFLICT(id) DO NOTHING`, actorID)
if err != nil {
t.Fatal(err)
}
defer cleanup()
_, err = pool.Exec(ctx, `INSERT INTO gateway.knowledge_bases(id,name,retrieval_mode,chunk_size,chunk_overlap,created_by)
VALUES($1,'factcheck-test-kb','postgres_fts',800,100,$2)`, knowledgeBaseID, actorID)
if err != nil {
t.Fatal(err)
}
service := NewService(pool)
settings, err := service.SaveSettings(ctx, Settings{TimeoutSeconds: 17}, actorID)
if err != nil || settings.TimeoutSeconds != 17 || settings.ProviderID != nil {
t.Fatalf("settings=%#v err=%v", settings, err)
}
policy, err := service.SavePolicy(ctx, Policy{
Scope: "global",
Enabled: true,
Mode: "sync",
Action: "annotate",
KnowledgeBaseIDs: []string{knowledgeBaseID},
}, actorID)
if err != nil {
t.Fatal(err)
}
if policy.Revision != 1 || policy.TopK != 4 || policy.SupportThreshold != 70 {
t.Fatalf("unexpected policy defaults: %#v", policy)
}
policy.Action = "block"
updated, err := service.SavePolicy(ctx, policy, actorID)
if err != nil || updated.Revision != 2 || updated.Action != "block" {
t.Fatalf("updated=%#v err=%v", updated, err)
}
claims := json.RawMessage(`[{"text":"Go gateway"}]`)
evidence := json.RawMessage(`[{"source":"kb"}]`)
_, err = pool.Exec(ctx, `INSERT INTO gateway.fact_check_events
(id,policy_id,request_id,model,mode,action,verdict,support_score,latency_ms,question,answer,claims,evidence)
VALUES($1,$2,'factcheck-request','test-model','sync','block','supported',92,12,'question','answer',$3,$4)`,
eventID, policy.ID, claims, evidence)
if err != nil {
t.Fatal(err)
}
events, err := service.Events(ctx, "supported", 10)
if err != nil || len(events) != 1 {
t.Fatalf("events=%#v err=%v", events, err)
}
if events[0].Question != "" || events[0].Answer != "" || events[0].Claims != nil {
t.Fatalf("event list leaked payload: %#v", events[0])
}
detail, err := service.Event(ctx, eventID)
if err != nil || detail.Question != "question" || len(detail.Evidence) == 0 {
t.Fatalf("detail=%#v err=%v", detail, err)
}
if err = service.DeletePolicy(ctx, policy.ID); err != nil {
t.Fatal(err)
}
}