starnet/client_test.go

224 lines
5.0 KiB
Go
Raw Normal View History

2026-03-08 20:19:40 +08:00
package starnet
import (
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestNewClient(t *testing.T) {
client, err := NewClient()
if err != nil {
t.Fatalf("NewClient() error: %v", err)
}
if client == nil {
t.Fatal("NewClient() returned nil")
}
}
func TestNewClientNoErr(t *testing.T) {
client := NewClientNoErr()
if client == nil {
t.Fatal("NewClientNoErr() returned nil")
}
}
func TestNewClientFromHTTP(t *testing.T) {
httpClient := &http.Client{
Timeout: 10 * time.Second,
}
client, err := NewClientFromHTTP(httpClient)
if err != nil {
t.Fatalf("NewClientFromHTTP() error: %v", err)
}
if client == nil {
t.Fatal("NewClientFromHTTP() returned nil")
}
// Test with nil client
_, err = NewClientFromHTTP(nil)
if err == nil {
t.Error("NewClientFromHTTP(nil) should return error")
}
}
func TestClientOptions(t *testing.T) {
client := NewClientNoErr()
// Set options
client.SetOptions(WithTimeout(5 * time.Second))
opts := client.RequestOptions()
if len(opts) != 1 {
t.Errorf("RequestOptions() length = %v; want 1", len(opts))
}
// Add options
client.AddOptions(WithUserAgent("TestAgent"))
opts = client.RequestOptions()
if len(opts) != 2 {
t.Errorf("RequestOptions() length = %v; want 2", len(opts))
}
}
func TestClientClone(t *testing.T) {
client := NewClientNoErr(WithTimeout(5 * time.Second))
cloned := client.Clone()
if cloned == nil {
t.Fatal("Clone() returned nil")
}
// 修改克隆的 client
cloned.SetOptions(WithTimeout(10 * time.Second))
origOpts := client.RequestOptions()
clonedOpts := cloned.RequestOptions()
// 原 client 应该还是 1 个选项
if len(origOpts) != 1 {
t.Errorf("Original client options = %v; want 1", len(origOpts))
}
// 克隆的 client 应该是 1 个选项(被 SetOptions 覆盖)
if len(clonedOpts) != 1 {
t.Errorf("Cloned client options = %v; want 1", len(clonedOpts))
}
}
func TestClientHTTPMethods(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(r.Method))
}))
defer server.Close()
client := NewClientNoErr()
tests := []struct {
name string
method func(string, ...RequestOpt) (*Response, error)
want string
}{
{"GET", client.Get, "GET"},
{"POST", client.Post, "POST"},
{"PUT", client.Put, "PUT"},
{"DELETE", client.Delete, "DELETE"},
{"PATCH", client.Patch, "PATCH"},
{"HEAD", client.Head, "HEAD"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resp, err := tt.method(server.URL)
if err != nil {
t.Fatalf("%s() error: %v", tt.name, err)
}
defer resp.Close()
if tt.want != "HEAD" {
body, _ := resp.Body().String()
if body != tt.want {
t.Errorf("Body = %v; want %v", body, tt.want)
}
}
})
}
}
func TestClientRedirect(t *testing.T) {
redirectCount := 0
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if redirectCount < 2 {
redirectCount++
http.Redirect(w, r, "/redirected", http.StatusFound)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("final"))
}))
defer server.Close()
// Test with redirect enabled (default)
client := NewClientNoErr()
resp, err := client.Get(server.URL)
if err != nil {
t.Fatalf("Get() error: %v", err)
}
resp.Close()
if redirectCount != 2 {
t.Errorf("Redirect count = %v; want 2", redirectCount)
}
// Test with redirect disabled
redirectCount = 0
client.DisableRedirect()
resp2, err := client.Get(server.URL)
if err != nil {
t.Fatalf("Get() error: %v", err)
}
defer resp2.Close()
if resp2.StatusCode != http.StatusFound {
t.Errorf("StatusCode = %v; want %v", resp2.StatusCode, http.StatusFound)
}
}
func TestClientTLSConfig(t *testing.T) {
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
}))
defer server.Close()
// Without skip verify (should fail with self-signed cert)
client := NewClientNoErr()
_, err := client.Get(server.URL)
if err == nil {
t.Error("Expected TLS error with self-signed cert, got nil")
}
// With skip verify
client.SetDefaultSkipTLSVerify(true)
resp, err := client.Get(server.URL)
if err != nil {
t.Fatalf("Get() with skip verify error: %v", err)
}
defer resp.Close()
if resp.StatusCode != http.StatusOK {
t.Errorf("StatusCode = %v; want %v", resp.StatusCode, http.StatusOK)
}
}
func TestClientNewSimpleRequest(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
}))
defer server.Close()
client := NewClientNoErr()
req := client.NewSimpleRequest(server.URL, "GET", WithHeader("X-Test", "v"))
if req == nil {
t.Fatal("NewSimpleRequest returned nil")
}
if req.Err() != nil {
t.Fatalf("NewSimpleRequest err: %v", req.Err())
}
resp, err := req.Do()
if err != nil {
t.Fatalf("Do() error: %v", err)
}
defer resp.Close()
body, _ := resp.Body().String()
if body != "OK" {
t.Errorf("Body = %v; want OK", body)
}
}