test: add service header util tests

- Add resolveWireCasing tests
- Add setHeaderRaw/addHeaderRaw/getHeaderRaw tests
- Add sortHeadersByWireOrder tests
This commit is contained in:
Your Name
2026-05-29 18:37:52 +08:00
parent 7a20548204
commit 17a46c2770

View File

@@ -3,112 +3,115 @@ package service
import ( import (
"net/http" "net/http"
"testing" "testing"
)
// ============================================================================= "github.com/stretchr/testify/require"
// Header Utility Functions Tests )
// =============================================================================
func TestResolveWireCasing(t *testing.T) { func TestResolveWireCasing(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
key string key string
expected string want string
}{ }{
{"lowercase key", "content-type", "Content-Type"}, {"accept", "Accept", "Accept"},
{"already canonical", "Content-Type", "Content-Type"}, {"user-agent", "User-Agent", "User-Agent"},
{"unknown key", "x-custom-header", "x-custom-header"}, {"x-stainless-retry-count", "X-Stainless-Retry-Count", "X-Stainless-Retry-Count"},
{"anthropic-beta", "anthropic-beta", "anthropic-beta"}, {"anthropic-version", "anthropic-version", "anthropic-version"},
{"unknown-header", "Unknown-Header", "Unknown-Header"},
{"mixed-case", "Mixed-Case", "Mixed-Case"},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
result := resolveWireCasing(tt.key) got := resolveWireCasing(tt.key)
// The expected result depends on the headerWireCasing map require.Equal(t, tt.want, got)
// We just verify the function doesn't panic and returns a string })
if result == "" && tt.key != "" { }
t.Errorf("resolveWireCasing(%q) returned empty string", tt.key) }
}
func TestSetHeaderRaw(t *testing.T) {
h := make(http.Header)
// Test setting header with wire casing
setHeaderRaw(h, "Accept", "application/json")
require.Equal(t, "application/json", h.Get("Accept"))
// Test setting header that needs wire casing resolution
// Note: setHeaderRaw stores with the exact key provided
setHeaderRaw(h, "accept", "text/html")
// The header is stored under "accept" (lowercase), not "Accept"
require.Equal(t, "text/html", h["accept"][0])
// Test overwriting existing header
setHeaderRaw(h, "User-Agent", "TestAgent")
setHeaderRaw(h, "user-agent", "NewAgent")
require.Equal(t, "NewAgent", h["user-agent"][0])
}
func TestAddHeaderRaw(t *testing.T) {
h := make(http.Header)
// Add first value
addHeaderRaw(h, "X-Custom", "value1")
require.Equal(t, []string{"value1"}, h["X-Custom"])
// Add second value
addHeaderRaw(h, "X-Custom", "value2")
require.Equal(t, []string{"value1", "value2"}, h["X-Custom"])
}
func TestGetHeaderRaw(t *testing.T) {
h := make(http.Header)
h.Set("Accept", "application/json")
h.Set("anthropic-version", "2023-06-01")
tests := []struct {
name string
key string
want string
}{
{"exact_match", "Accept", "application/json"},
{"canonical_lookup", "accept", "application/json"},
{"wire_casing_lookup", "Accept", "application/json"},
{"lowercase_header", "anthropic-version", "2023-06-01"},
{"not_exist", "Not-Exist", ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := getHeaderRaw(h, tt.key)
require.Equal(t, tt.want, got)
}) })
} }
} }
func TestSortHeadersByWireOrder(t *testing.T) { func TestSortHeadersByWireOrder(t *testing.T) {
t.Run("sort headers in wire order", func(t *testing.T) { h := make(http.Header)
h := make(http.Header) h.Set("Z-Last", "last")
h.Set("Content-Type", "application/json") h.Set("Accept", "application/json")
h.Set("X-Custom-Header", "value") h.Set("anthropic-version", "2023-06-01")
h.Set("Authorization", "Bearer token") h.Set("User-Agent", "Test")
result := sortHeadersByWireOrder(h) sorted := sortHeadersByWireOrder(h)
if len(result) != 3 {
t.Errorf("Expected 3 headers, got %d", len(result)) // Check that wire-ordered headers come first
} // Note: h.Set() uses canonical key, so "anthropic-version" becomes "Anthropic-Version"
}) require.Contains(t, sorted, "Accept")
require.Contains(t, sorted, "User-Agent")
t.Run("empty headers", func(t *testing.T) { require.Contains(t, sorted, "Anthropic-Version")
h := make(http.Header) require.Contains(t, sorted, "Z-Last")
result := sortHeadersByWireOrder(h)
if len(result) != 0 { // Z-Last should be at the end (not in wire order)
t.Errorf("Expected 0 headers, got %d", len(result)) require.Equal(t, "Z-Last", sorted[len(sorted)-1])
}
})
} }
func TestSetHeaderRaw(t *testing.T) { func TestHeaderWireOrderSet(t *testing.T) {
t.Run("set header", func(t *testing.T) { // Verify headerWireOrderSet is initialized correctly
h := make(http.Header) require.NotNil(t, headerWireOrderSet)
setHeaderRaw(h, "X-Custom-Header", "value1") require.Greater(t, len(headerWireOrderSet), 0)
if h.Get("X-Custom-Header") != "value1" {
t.Errorf("Expected 'value1', got %q", h.Get("X-Custom-Header")) // Check some expected keys exist
} require.Contains(t, headerWireOrderSet, "accept")
}) require.Contains(t, headerWireOrderSet, "user-agent")
require.Contains(t, headerWireOrderSet, "anthropic-version")
t.Run("overwrite header", func(t *testing.T) {
h := make(http.Header)
setHeaderRaw(h, "X-Test", "value1")
setHeaderRaw(h, "X-Test", "value2")
if h.Get("X-Test") != "value2" {
t.Errorf("Expected 'value2', got %q", h.Get("X-Test"))
}
})
}
func TestAddHeaderRaw(t *testing.T) {
t.Run("add single header", func(t *testing.T) {
h := make(http.Header)
addHeaderRaw(h, "X-Add-Header", "value1")
if h.Get("X-Add-Header") != "value1" {
t.Errorf("Expected 'value1', got %q", h.Get("X-Add-Header"))
}
})
t.Run("add multiple values", func(t *testing.T) {
h := make(http.Header)
addHeaderRaw(h, "X-Multi", "value1")
addHeaderRaw(h, "X-Multi", "value2")
values := h.Values("X-Multi")
if len(values) != 2 {
t.Errorf("Expected 2 values, got %d", len(values))
}
})
}
func TestGetHeaderRaw(t *testing.T) {
t.Run("get existing header", func(t *testing.T) {
h := make(http.Header)
h.Set("X-Get-Test", "testvalue")
result := getHeaderRaw(h, "X-Get-Test")
if result != "testvalue" {
t.Errorf("Expected 'testvalue', got %q", result)
}
})
t.Run("get non-existent header", func(t *testing.T) {
h := make(http.Header)
result := getHeaderRaw(h, "X-Nonexistent")
if result != "" {
t.Errorf("Expected empty string, got %q", result)
}
})
} }