Files
cmautobuy/admin/service/ai_specmatch_client_test.go
T

61 lines
2.4 KiB
Go

package service
import (
"context"
"io"
"net/http"
"strings"
"testing"
"cmautobuy/admin/model"
)
type staticAIResponseDoer struct {
status int
body string
seen *http.Request
}
func (d *staticAIResponseDoer) Do(request *http.Request) (*http.Response, error) {
d.seen = request
return &http.Response{StatusCode: d.status, Body: io.NopCloser(strings.NewReader(d.body))}, nil
}
func TestOpenAICompatibleModelClient_解析严格JSON且不把密钥放进正文(t *testing.T) {
doer := &staticAIResponseDoer{status: 200, body: `{"choices":[{"message":{"content":"{\"conclusion\":\"match\",\"candidate_id\":\"C01\",\"confidence_bps\":9300,\"reason\":\"规格一致\",\"conflict_dimensions\":[],\"missing_dimensions\":[]}"}}]}`}
client := NewOpenAICompatibleModelClient(doer)
const fakeSecret = "fake-secret-not-production"
result, err := client.Match(context.Background(), model.AIProviderConfig{BaseURL: "https://api.example.com/v1", Model: "fake"}, fakeSecret,
AIModelMatchRequest{ProductTitle: "测试商品", SourceSpec: "黑色,M", Candidates: []AIModelCandidate{{ID: "C01", Label: "黑色/M"}}})
if err != nil || result.CandidateID != "C01" || result.ConfidenceBPS != 9300 {
t.Fatalf("解析结果=%+v err=%v", result, err)
}
body, _ := io.ReadAll(doer.seen.Body)
if strings.Contains(string(body), fakeSecret) {
t.Fatal("API Key 只能放 Authorization,不能进入请求正文")
}
if got := doer.seen.Header.Get("Authorization"); got != "Bearer "+fakeSecret {
t.Fatalf("Authorization=%q", got)
}
}
func TestOpenAICompatibleModelClient_拒绝无效或多余模型字段(t *testing.T) {
for _, content := range []string{
`not-json`,
`{"conclusion":"match","candidate_id":"C01","confidence_bps":9000,"reason":"x","conflict_dimensions":[],"missing_dimensions":[],"option_key":"forged"}`,
} {
doer := &staticAIResponseDoer{status: 200, body: `{"choices":[{"message":{"content":` + quoteJSONString(content) + `}}]}`}
client := NewOpenAICompatibleModelClient(doer)
if _, err := client.Match(context.Background(), model.AIProviderConfig{BaseURL: "https://api.example.com/v1", Model: "fake"}, "fake-secret",
AIModelMatchRequest{Candidates: []AIModelCandidate{{ID: "C01"}}}); err == nil {
t.Fatalf("无效结论应被拒绝: %s", content)
}
}
}
func quoteJSONString(value string) string {
value = strings.ReplaceAll(value, `\`, `\\`)
value = strings.ReplaceAll(value, `"`, `\"`)
return `"` + value + `"`
}