Files
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

45 lines
1.6 KiB
Go

package contentpolicy
import (
"io"
"net/http"
"strings"
"testing"
)
func testEngine(t *testing.T, action string) *Engine {
t.Helper()
policy := Policy{ID: "p1", Name: "secret", Action: action, Rules: []Rule{{Name: "token", Pattern: `sk-[A-Za-z0-9]{8,}`, Replacement: "[MASKED]"}}, Enabled: true}
compiled, err := compilePolicy(policy)
if err != nil {
t.Fatal(err)
}
engine := &Engine{}
engine.current.Store(&snapshot{policies: []compiledPolicy{compiled}})
return engine
}
func TestApplyRedactsOnlyTextualPromptFields(t *testing.T) {
request, _ := http.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{"model":"gpt-5","messages":[{"content":"use sk-12345678"}],"tools":[{"description":"keep sk-abcdefgh"}]}`))
result, err := testEngine(t, "redact").Apply(request, 1<<20, "key")
if err != nil || !result.Redacted || result.Blocked {
t.Fatalf("unexpected result %#v: %v", result, err)
}
body, _ := io.ReadAll(request.Body)
text := string(body)
if strings.Contains(text, "sk-12345678") || !strings.Contains(text, "keep sk-abcdefgh") {
t.Fatalf("unexpected redaction: %s", text)
}
}
func TestApplyBlocksWithoutReturningMatchedSecret(t *testing.T) {
request, _ := http.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{"input":"sk-12345678"}`))
result, err := testEngine(t, "block").Apply(request, 1<<20, "")
if err != nil || !result.Blocked || len(result.Matches) != 1 {
t.Fatalf("unexpected result %#v: %v", result, err)
}
if strings.Contains(result.Matches[0].Rules[0], "12345678") {
t.Fatal("match metadata leaked secret")
}
}