fix(openai-gateway): address PR review — probe URL /v1 prefix, Create trigger, tests
Fix four issues flagged by copilot-pull-request-reviewer on PR #2143: 1. Probe URL missing /v1 prefix (openai_apikey_responses_probe.go) Replaced bare TrimSuffix + "/responses" with buildOpenAIResponsesURL(), which handles bare domain → /v1/responses correctly. Affected: - ProbeOpenAIAPIKeyResponsesSupport (probe URL) - TestAccount endpoint (apiURL for APIKey accounts) 2. Create endpoint not triggering probe (account_handler.go) Capture created account from idempotent closure and call scheduleOpenAIResponsesProbe after success, same pattern as BatchCreate and Update. 3. Tests (openai_gateway_chat_completions_raw_test.go) Added TestBuildOpenAIChatCompletionsURL (7 cases covering bare domain, /v1 suffix, trailing slash, third-party domains, whitespace) and TestBuildOpenAIResponsesURL_ProbeURL (6 cases locking the probe URL construction for bare-domain inputs). All unit tests pass; go build ./cmd/server/ clean.
This commit is contained in:
@@ -564,7 +564,7 @@ func (s *AccountTestService) testOpenAIAccountConnection(c *gin.Context, account
|
||||
"账号本身可正常使用,但当前测试接口仅支持 Responses API 路径。请直接通过实际 API 调用验证。",
|
||||
)
|
||||
}
|
||||
apiURL = strings.TrimSuffix(normalizedBaseURL, "/") + "/responses"
|
||||
apiURL = buildOpenAIResponsesURL(normalizedBaseURL)
|
||||
} else {
|
||||
return s.sendErrorAndEnd(c, fmt.Sprintf("Unsupported account type: %s", account.Type))
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ func (s *AccountTestService) ProbeOpenAIAPIKeyResponsesSupport(ctx context.Conte
|
||||
return
|
||||
}
|
||||
|
||||
probeURL := strings.TrimSuffix(normalizedBaseURL, "/") + "/responses"
|
||||
probeURL := buildOpenAIResponsesURL(normalizedBaseURL)
|
||||
|
||||
probeCtx, cancel := context.WithTimeout(ctx, openaiResponsesProbeTimeout)
|
||||
defer cancel()
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
//go:build unit
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestBuildOpenAIChatCompletionsURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
base string
|
||||
want string
|
||||
}{
|
||||
// 已是 /chat/completions:原样返回
|
||||
{"already chat/completions", "https://api.openai.com/v1/chat/completions", "https://api.openai.com/v1/chat/completions"},
|
||||
// 以 /v1 结尾:追加 /chat/completions
|
||||
{"bare /v1", "https://api.openai.com/v1", "https://api.openai.com/v1/chat/completions"},
|
||||
// 其他情况:追加 /v1/chat/completions
|
||||
{"bare domain", "https://api.openai.com", "https://api.openai.com/v1/chat/completions"},
|
||||
{"domain with trailing slash", "https://api.openai.com/", "https://api.openai.com/v1/chat/completions"},
|
||||
// 第三方上游常见形式
|
||||
{"third-party bare domain", "https://api.deepseek.com", "https://api.deepseek.com/v1/chat/completions"},
|
||||
{"third-party with path prefix", "https://api.gptgod.online/api", "https://api.gptgod.online/api/v1/chat/completions"},
|
||||
// 带空白字符
|
||||
{"whitespace trimmed", " https://api.openai.com/v1 ", "https://api.openai.com/v1/chat/completions"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := buildOpenAIChatCompletionsURL(tt.base)
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestBuildOpenAIResponsesURL_ProbeURL 锁定 probe/测试端点使用的 URL 构建逻辑,
|
||||
// 确保 buildOpenAIResponsesURL 对标准 OpenAI base_url 格式均拼出 `/v1/responses`。
|
||||
func TestBuildOpenAIResponsesURL_ProbeURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
base string
|
||||
want string
|
||||
}{
|
||||
{"bare domain", "https://api.openai.com", "https://api.openai.com/v1/responses"},
|
||||
{"domain trailing slash", "https://api.openai.com/", "https://api.openai.com/v1/responses"},
|
||||
{"bare /v1", "https://api.openai.com/v1", "https://api.openai.com/v1/responses"},
|
||||
{"already /responses", "https://api.openai.com/v1/responses", "https://api.openai.com/v1/responses"},
|
||||
{"third-party bare domain", "https://api.deepseek.com", "https://api.deepseek.com/v1/responses"},
|
||||
{"only domain, no scheme", "api.gptgod.online", "api.gptgod.online/v1/responses"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := buildOpenAIResponsesURL(tt.base)
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user