mirror of
https://github.com/DeBrosOfficial/network.git
synced 2026-01-30 20:53:04 +00:00
335 lines
6.5 KiB
Go
335 lines
6.5 KiB
Go
package httputil
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
func TestExtractBearerToken(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
header string
|
|
want string
|
|
}{
|
|
{
|
|
name: "valid bearer token",
|
|
header: "Bearer abc123",
|
|
want: "abc123",
|
|
},
|
|
{
|
|
name: "case insensitive",
|
|
header: "bearer xyz789",
|
|
want: "xyz789",
|
|
},
|
|
{
|
|
name: "with extra spaces",
|
|
header: "Bearer token-with-spaces ",
|
|
want: "token-with-spaces",
|
|
},
|
|
{
|
|
name: "no bearer scheme",
|
|
header: "Basic abc123",
|
|
want: "",
|
|
},
|
|
{
|
|
name: "empty header",
|
|
header: "",
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
if tt.header != "" {
|
|
req.Header.Set("Authorization", tt.header)
|
|
}
|
|
|
|
if got := ExtractBearerToken(req); got != tt.want {
|
|
t.Errorf("ExtractBearerToken() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractAPIKey(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
header string
|
|
xapi string
|
|
query string
|
|
want string
|
|
}{
|
|
{
|
|
name: "X-API-Key header (priority)",
|
|
xapi: "key-from-header",
|
|
want: "key-from-header",
|
|
},
|
|
{
|
|
name: "ApiKey scheme",
|
|
header: "ApiKey my-api-key",
|
|
want: "my-api-key",
|
|
},
|
|
{
|
|
name: "Bearer with non-JWT token",
|
|
header: "Bearer simple-token",
|
|
want: "simple-token",
|
|
},
|
|
{
|
|
name: "Bearer with JWT (should skip)",
|
|
header: "Bearer eyJ.abc.xyz",
|
|
want: "",
|
|
},
|
|
{
|
|
name: "query parameter api_key",
|
|
query: "?api_key=query-key",
|
|
want: "query-key",
|
|
},
|
|
{
|
|
name: "query parameter token",
|
|
query: "?token=token-key",
|
|
want: "token-key",
|
|
},
|
|
{
|
|
name: "X-API-Key takes priority over Authorization",
|
|
xapi: "xapi-key",
|
|
header: "Bearer bearer-key",
|
|
want: "xapi-key",
|
|
},
|
|
{
|
|
name: "no auth",
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
url := "/"
|
|
if tt.query != "" {
|
|
url += tt.query
|
|
}
|
|
req := httptest.NewRequest(http.MethodGet, url, nil)
|
|
|
|
if tt.header != "" {
|
|
req.Header.Set("Authorization", tt.header)
|
|
}
|
|
if tt.xapi != "" {
|
|
req.Header.Set("X-API-Key", tt.xapi)
|
|
}
|
|
|
|
if got := ExtractAPIKey(req); got != tt.want {
|
|
t.Errorf("ExtractAPIKey() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsJWT(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
token string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "valid JWT structure",
|
|
token: "header.payload.signature",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "real JWT",
|
|
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "not a JWT - no dots",
|
|
token: "simple-token",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "not a JWT - one dot",
|
|
token: "part1.part2",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "not a JWT - three dots",
|
|
token: "a.b.c.d",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "empty string",
|
|
token: "",
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := IsJWT(tt.token); got != tt.want {
|
|
t.Errorf("IsJWT(%q) = %v, want %v", tt.token, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractNamespaceHeader(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
header string
|
|
want string
|
|
}{
|
|
{
|
|
name: "valid namespace",
|
|
header: "my-namespace",
|
|
want: "my-namespace",
|
|
},
|
|
{
|
|
name: "with whitespace",
|
|
header: " my-namespace ",
|
|
want: "my-namespace",
|
|
},
|
|
{
|
|
name: "empty header",
|
|
header: "",
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
if tt.header != "" {
|
|
req.Header.Set("X-Namespace", tt.header)
|
|
}
|
|
|
|
if got := ExtractNamespaceHeader(req); got != tt.want {
|
|
t.Errorf("ExtractNamespaceHeader() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractWalletHeader(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
header string
|
|
want string
|
|
}{
|
|
{
|
|
name: "valid wallet",
|
|
header: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbC",
|
|
want: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbC",
|
|
},
|
|
{
|
|
name: "with whitespace",
|
|
header: " 0x742d35Cc ",
|
|
want: "0x742d35Cc",
|
|
},
|
|
{
|
|
name: "empty header",
|
|
header: "",
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
if tt.header != "" {
|
|
req.Header.Set("X-Wallet", tt.header)
|
|
}
|
|
|
|
if got := ExtractWalletHeader(req); got != tt.want {
|
|
t.Errorf("ExtractWalletHeader() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasAuthHeader(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
header string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "has auth header",
|
|
header: "Bearer token",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "no auth header",
|
|
header: "",
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
if tt.header != "" {
|
|
req.Header.Set("Authorization", tt.header)
|
|
}
|
|
|
|
if got := HasAuthHeader(req); got != tt.want {
|
|
t.Errorf("HasAuthHeader() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractBasicAuth(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
header string
|
|
wantUsername string
|
|
wantPassword string
|
|
wantOK bool
|
|
}{
|
|
{
|
|
name: "valid basic auth",
|
|
header: "Basic " + basicAuth("user", "pass"),
|
|
wantUsername: "user",
|
|
wantPassword: "pass",
|
|
wantOK: true,
|
|
},
|
|
{
|
|
name: "no auth header",
|
|
header: "",
|
|
wantOK: false,
|
|
},
|
|
{
|
|
name: "bearer token",
|
|
header: "Bearer token",
|
|
wantOK: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
if tt.header != "" {
|
|
req.Header.Set("Authorization", tt.header)
|
|
}
|
|
|
|
username, password, ok := ExtractBasicAuth(req)
|
|
if ok != tt.wantOK {
|
|
t.Errorf("ExtractBasicAuth() ok = %v, want %v", ok, tt.wantOK)
|
|
}
|
|
if ok {
|
|
if username != tt.wantUsername {
|
|
t.Errorf("ExtractBasicAuth() username = %v, want %v", username, tt.wantUsername)
|
|
}
|
|
if password != tt.wantPassword {
|
|
t.Errorf("ExtractBasicAuth() password = %v, want %v", password, tt.wantPassword)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Helper function to create basic auth header
|
|
func basicAuth(username, password string) string {
|
|
return EncodeBase64([]byte(username + ":" + password))
|
|
}
|