61 lines
2.4 KiB
Go
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 + `"`
|
|
}
|