224 lines
5.0 KiB
Go
224 lines
5.0 KiB
Go
|
|
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)
|
||
|
|
}
|
||
|
|
}
|