win 435ae221bc
Some checks failed
CI / test (push) Failing after 1m32s
CI / golangci-lint (push) Failing after 31s
Security Scan / backend-security (push) Failing after 1m32s
Security Scan / frontend-security (push) Failing after 9s
x
2026-04-16 19:11:47 +08:00

161 lines
5.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}