first commit of restructured project

This commit is contained in:
KS Jannette
2026-02-22 15:21:18 -05:00
commit 9fca234606
75 changed files with 8299 additions and 0 deletions

View File

@@ -0,0 +1,187 @@
package api
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestAuthMiddleware_NoKeyConfigured(t *testing.T) {
s := &Server{apiKey: ""}
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler := s.authMiddleware(inner)
req := httptest.NewRequest(http.MethodGet, "/v1/trades/stats", nil)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("expected 200 when no API key configured, got %d", rr.Code)
}
}
func TestAuthMiddleware_HealthBypass(t *testing.T) {
s := &Server{apiKey: "secret123"}
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler := s.authMiddleware(inner)
req := httptest.NewRequest(http.MethodGet, "/health", nil)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("expected 200 for /health without auth, got %d", rr.Code)
}
}
func TestAuthMiddleware_MissingHeader(t *testing.T) {
s := &Server{apiKey: "secret123"}
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler := s.authMiddleware(inner)
req := httptest.NewRequest(http.MethodGet, "/v1/prices/latest", nil)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusUnauthorized {
t.Fatalf("expected 401, got %d", rr.Code)
}
}
func TestAuthMiddleware_WrongKey(t *testing.T) {
s := &Server{apiKey: "secret123"}
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler := s.authMiddleware(inner)
req := httptest.NewRequest(http.MethodGet, "/v1/prices/latest", nil)
req.Header.Set("Authorization", "Bearer wrong_key")
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusUnauthorized {
t.Fatalf("expected 401, got %d", rr.Code)
}
}
func TestAuthMiddleware_CorrectKey(t *testing.T) {
s := &Server{apiKey: "secret123"}
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler := s.authMiddleware(inner)
req := httptest.NewRequest(http.MethodGet, "/v1/prices/latest", nil)
req.Header.Set("Authorization", "Bearer secret123")
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", rr.Code)
}
}
func TestAuthMiddleware_MalformedBearer(t *testing.T) {
s := &Server{apiKey: "secret123"}
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler := s.authMiddleware(inner)
req := httptest.NewRequest(http.MethodGet, "/v1/prices/latest", nil)
req.Header.Set("Authorization", "Basic secret123")
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusUnauthorized {
t.Fatalf("expected 401 for non-Bearer auth, got %d", rr.Code)
}
}
func TestValidateDate(t *testing.T) {
valid := []string{"2024-01-15", "2025-12-31", "2020-02-29"}
for _, d := range valid {
if !validateDate(d) {
t.Fatalf("expected %q to be valid", d)
}
}
invalid := []string{
"", "2024", "01-15-2024", "2024/01/15",
"abcd-ef-gh", "2024-13-01", "2024-01-32",
"2024-1-5", "20240115",
}
for _, d := range invalid {
if validateDate(d) {
t.Fatalf("expected %q to be invalid", d)
}
}
}
func TestParseLimit(t *testing.T) {
cases := []struct {
query string
deflt int
expected int
}{
{"", 100, 100},
{"?limit=50", 100, 50},
{"?limit=0", 100, 100},
{"?limit=-5", 100, 100},
{"?limit=abc", 100, 100},
{"?limit=2000", 100, maxQueryLimit},
{"?limit=1000", 100, 1000},
{"?limit=1", 50, 1},
}
for _, tc := range cases {
req := httptest.NewRequest(http.MethodGet, "/test"+tc.query, nil)
got := parseLimit(req, tc.deflt)
if got != tc.expected {
t.Fatalf("parseLimit(%q, %d) = %d, want %d", tc.query, tc.deflt, got, tc.expected)
}
}
}
func TestCorsMiddleware_Headers(t *testing.T) {
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler := corsMiddleware(inner, "https://myapp.example.com")
req := httptest.NewRequest(http.MethodGet, "/v1/prices/latest", nil)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
origin := rr.Header().Get("Access-Control-Allow-Origin")
if origin != "https://myapp.example.com" {
t.Fatalf("expected custom origin, got %q", origin)
}
allow := rr.Header().Get("Access-Control-Allow-Headers")
if allow == "" {
t.Fatal("expected Allow-Headers to include Authorization")
}
}
func TestCorsMiddleware_Preflight(t *testing.T) {
inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Fatal("inner handler should not be called for OPTIONS")
})
handler := corsMiddleware(inner, "*")
req := httptest.NewRequest(http.MethodOptions, "/v1/prices/latest", nil)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("expected 200 for preflight, got %d", rr.Code)
}
}