161 lines
5.4 KiB
Go
161 lines
5.4 KiB
Go
package claudemask
|
||
|
||
import (
|
||
"net/http"
|
||
"testing"
|
||
|
||
"github.com/Wei-Shaw/sub2api/internal/pkg/claude"
|
||
)
|
||
|
||
func TestValidateNodeEmulation_ValidRequest(t *testing.T) {
|
||
req, _ := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", nil)
|
||
|
||
// 设置所有必需的 Node.js 头
|
||
req.Header.Set("User-Agent", claude.DefaultUserAgent())
|
||
req.Header.Set("X-Stainless-Lang", claude.DefaultStainlessLang)
|
||
req.Header.Set("X-Stainless-Runtime", claude.DefaultStainlessRuntime)
|
||
req.Header.Set("X-Stainless-Runtime-Version", claude.DefaultStainlessRuntimeVersion)
|
||
req.Header.Set("X-Stainless-Package-Version", claude.DefaultStainlessPackageVersion)
|
||
req.Header.Set("X-Stainless-OS", claude.DefaultStainlessOS)
|
||
req.Header.Set("X-Stainless-Arch", claude.DefaultStainlessArch)
|
||
req.Header.Set("anthropic-version", claude.DefaultAnthropicVersion)
|
||
|
||
isValid, errors := ValidateNodeEmulation(req)
|
||
|
||
if !isValid {
|
||
t.Errorf("expected valid emulation, got errors: %v", errors)
|
||
}
|
||
if len(errors) > 0 {
|
||
t.Errorf("expected no errors, got: %v", errors)
|
||
}
|
||
}
|
||
|
||
func TestValidateNodeEmulation_MissingHeaders(t *testing.T) {
|
||
req, _ := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", nil)
|
||
|
||
// 只设置部分头
|
||
req.Header.Set("User-Agent", claude.DefaultUserAgent())
|
||
|
||
isValid, errors := ValidateNodeEmulation(req)
|
||
|
||
if isValid {
|
||
t.Error("expected invalid emulation due to missing headers")
|
||
}
|
||
if len(errors) == 0 {
|
||
t.Error("expected validation errors")
|
||
}
|
||
if len(errors) < 7 {
|
||
t.Errorf("expected at least 7 missing headers, got %d errors", len(errors))
|
||
}
|
||
}
|
||
|
||
func TestValidateNodeEmulation_InvalidRuntime(t *testing.T) {
|
||
req, _ := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", nil)
|
||
|
||
// 设置所有必需的头,但 runtime 错误
|
||
req.Header.Set("User-Agent", claude.DefaultUserAgent())
|
||
req.Header.Set("X-Stainless-Lang", claude.DefaultStainlessLang)
|
||
req.Header.Set("X-Stainless-Runtime", "go") // ❌ 应为 "node"
|
||
req.Header.Set("X-Stainless-Runtime-Version", claude.DefaultStainlessRuntimeVersion)
|
||
req.Header.Set("X-Stainless-Package-Version", claude.DefaultStainlessPackageVersion)
|
||
req.Header.Set("X-Stainless-OS", claude.DefaultStainlessOS)
|
||
req.Header.Set("X-Stainless-Arch", claude.DefaultStainlessArch)
|
||
req.Header.Set("anthropic-version", claude.DefaultAnthropicVersion)
|
||
|
||
isValid, errs := ValidateNodeEmulation(req)
|
||
|
||
if isValid {
|
||
t.Error("expected invalid due to runtime=go")
|
||
}
|
||
if len(errs) == 0 {
|
||
t.Error("expected validation error for runtime")
|
||
}
|
||
}
|
||
|
||
func TestValidateNodeEmulation_GoClientUA(t *testing.T) {
|
||
req, _ := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", nil)
|
||
|
||
// User-Agent 包含 Go 指示
|
||
req.Header.Set("User-Agent", "Go-http-client/2.0") // ❌ 包含 Go 指示
|
||
|
||
isValid, _ := ValidateNodeEmulation(req)
|
||
|
||
if isValid {
|
||
t.Error("expected invalid due to Go-http-client in User-Agent")
|
||
}
|
||
}
|
||
|
||
func TestValidateNodeEmulation_MissingUserAgent(t *testing.T) {
|
||
req, _ := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", nil)
|
||
|
||
// 不设置 User-Agent
|
||
req.Header.Set("X-Stainless-Lang", claude.DefaultStainlessLang)
|
||
req.Header.Set("X-Stainless-Runtime", claude.DefaultStainlessRuntime)
|
||
req.Header.Set("X-Stainless-Runtime-Version", claude.DefaultStainlessRuntimeVersion)
|
||
req.Header.Set("X-Stainless-Package-Version", claude.DefaultStainlessPackageVersion)
|
||
req.Header.Set("X-Stainless-OS", claude.DefaultStainlessOS)
|
||
req.Header.Set("X-Stainless-Arch", claude.DefaultStainlessArch)
|
||
req.Header.Set("anthropic-version", claude.DefaultAnthropicVersion)
|
||
|
||
isValid, errs := ValidateNodeEmulation(req)
|
||
|
||
if isValid {
|
||
t.Error("expected invalid due to missing User-Agent")
|
||
}
|
||
if len(errs) == 0 {
|
||
t.Error("expected validation error for missing User-Agent")
|
||
}
|
||
}
|
||
|
||
func TestCleanRequest_FixesGoUserAgent(t *testing.T) {
|
||
req, _ := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", nil)
|
||
|
||
// 设置不正确的 User-Agent
|
||
req.Header.Set("User-Agent", "Go-http-client/2.0")
|
||
|
||
CleanRequest(req)
|
||
|
||
ua := req.Header.Get("User-Agent")
|
||
if ua != claude.DefaultUserAgent() {
|
||
t.Errorf("expected fixed User-Agent, got: %s", ua)
|
||
}
|
||
}
|
||
|
||
func TestCleanRequest_FixesMissingUserAgent(t *testing.T) {
|
||
req, _ := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", nil)
|
||
|
||
// 不设置 User-Agent
|
||
CleanRequest(req)
|
||
|
||
ua := req.Header.Get("User-Agent")
|
||
if ua != claude.DefaultUserAgent() {
|
||
t.Errorf("expected User-Agent to be set, got: %s", ua)
|
||
}
|
||
}
|
||
|
||
func TestValidateAndClean(t *testing.T) {
|
||
req, _ := http.NewRequest("POST", "https://api.anthropic.com/v1/messages", nil)
|
||
|
||
// 设置带有 Go 指示的 User-Agent,其他头正确
|
||
req.Header.Set("User-Agent", "Go-http-client/2.0")
|
||
req.Header.Set("X-Stainless-Lang", claude.DefaultStainlessLang)
|
||
req.Header.Set("X-Stainless-Runtime", claude.DefaultStainlessRuntime)
|
||
req.Header.Set("X-Stainless-Runtime-Version", claude.DefaultStainlessRuntimeVersion)
|
||
req.Header.Set("X-Stainless-Package-Version", claude.DefaultStainlessPackageVersion)
|
||
req.Header.Set("X-Stainless-OS", claude.DefaultStainlessOS)
|
||
req.Header.Set("X-Stainless-Arch", claude.DefaultStainlessArch)
|
||
req.Header.Set("anthropic-version", claude.DefaultAnthropicVersion)
|
||
|
||
isValid, errors := ValidateAndClean(req)
|
||
|
||
// 清理后应该有效
|
||
if !isValid {
|
||
t.Errorf("expected valid after cleaning, got errors: %v", errors)
|
||
}
|
||
|
||
ua := req.Header.Get("User-Agent")
|
||
if ua != claude.DefaultUserAgent() {
|
||
t.Errorf("expected cleaned User-Agent, got: %s", ua)
|
||
}
|
||
}
|