175 lines
4.0 KiB
Go
175 lines
4.0 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"terminalShop/pkg/auth"
|
|
)
|
|
|
|
const testSecret = "middleware-test-secret"
|
|
|
|
func newTestJWTManager() *auth.JWTManager {
|
|
return auth.NewJWTManager(testSecret, 30*time.Minute)
|
|
}
|
|
|
|
// captureHandler is a dummy handler that records whether it was called
|
|
// and what userID was in the context.
|
|
type captureHandler struct {
|
|
called bool
|
|
userID uint
|
|
}
|
|
|
|
func (h *captureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
h.called = true
|
|
h.userID = UserIDFromContext(r.Context())
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func TestAuthNoHeader(t *testing.T) {
|
|
mgr := newTestJWTManager()
|
|
capture := &captureHandler{}
|
|
|
|
handler := Auth(mgr)(capture)
|
|
|
|
req := httptest.NewRequest("GET", "/test", nil)
|
|
w := httptest.NewRecorder()
|
|
handler.ServeHTTP(w, req)
|
|
|
|
if !capture.called {
|
|
t.Fatal("expected handler to be called")
|
|
}
|
|
if capture.userID != 0 {
|
|
t.Errorf("expected userID 0 (no auth), got %d", capture.userID)
|
|
}
|
|
}
|
|
|
|
func TestAuthMalformedHeader(t *testing.T) {
|
|
mgr := newTestJWTManager()
|
|
capture := &captureHandler{}
|
|
|
|
handler := Auth(mgr)(capture)
|
|
|
|
req := httptest.NewRequest("GET", "/test", nil)
|
|
req.Header.Set("Authorization", "NotBearer some-token")
|
|
w := httptest.NewRecorder()
|
|
handler.ServeHTTP(w, req)
|
|
|
|
if !capture.called {
|
|
t.Fatal("expected handler to be called")
|
|
}
|
|
if capture.userID != 0 {
|
|
t.Errorf("expected userID 0 for malformed header, got %d", capture.userID)
|
|
}
|
|
}
|
|
|
|
func TestAuthInvalidToken(t *testing.T) {
|
|
mgr := newTestJWTManager()
|
|
capture := &captureHandler{}
|
|
|
|
handler := Auth(mgr)(capture)
|
|
|
|
req := httptest.NewRequest("GET", "/test", nil)
|
|
req.Header.Set("Authorization", "Bearer totally-invalid-token")
|
|
w := httptest.NewRecorder()
|
|
handler.ServeHTTP(w, req)
|
|
|
|
if !capture.called {
|
|
t.Fatal("expected handler to be called (soft auth)")
|
|
}
|
|
if capture.userID != 0 {
|
|
t.Errorf("expected userID 0 for invalid token, got %d", capture.userID)
|
|
}
|
|
}
|
|
|
|
func TestAuthValidToken(t *testing.T) {
|
|
mgr := newTestJWTManager()
|
|
capture := &captureHandler{}
|
|
|
|
handler := Auth(mgr)(capture)
|
|
|
|
token, err := mgr.GenerateToken(99, "test@example.com", "testuser")
|
|
if err != nil {
|
|
t.Fatalf("failed to generate token: %v", err)
|
|
}
|
|
|
|
req := httptest.NewRequest("GET", "/test", nil)
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
w := httptest.NewRecorder()
|
|
handler.ServeHTTP(w, req)
|
|
|
|
if !capture.called {
|
|
t.Fatal("expected handler to be called")
|
|
}
|
|
if capture.userID != 99 {
|
|
t.Errorf("expected userID 99, got %d", capture.userID)
|
|
}
|
|
}
|
|
|
|
func TestRequireAuthWithUser(t *testing.T) {
|
|
capture := &captureHandler{}
|
|
|
|
handler := RequireAuth(capture)
|
|
|
|
req := httptest.NewRequest("GET", "/test", nil)
|
|
ctx := ContextWithUserID(req.Context(), 42)
|
|
req = req.WithContext(ctx)
|
|
w := httptest.NewRecorder()
|
|
handler.ServeHTTP(w, req)
|
|
|
|
if !capture.called {
|
|
t.Fatal("expected handler to be called when user is present")
|
|
}
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestRequireAuthWithoutUser(t *testing.T) {
|
|
capture := &captureHandler{}
|
|
|
|
handler := RequireAuth(capture)
|
|
|
|
req := httptest.NewRequest("GET", "/test", nil)
|
|
w := httptest.NewRecorder()
|
|
handler.ServeHTTP(w, req)
|
|
|
|
if capture.called {
|
|
t.Fatal("expected handler to NOT be called when no user")
|
|
}
|
|
if w.Code != http.StatusUnauthorized {
|
|
t.Errorf("expected 401, got %d", w.Code)
|
|
}
|
|
|
|
var resp struct {
|
|
Success bool `json:"success"`
|
|
Error struct {
|
|
Code string `json:"code"`
|
|
} `json:"error"`
|
|
}
|
|
if err := json.NewDecoder(w.Body).Decode(&resp); err != nil {
|
|
t.Fatalf("failed to decode response: %v", err)
|
|
}
|
|
if resp.Error.Code != "UNAUTHORIZED" {
|
|
t.Errorf("expected error code UNAUTHORIZED, got %s", resp.Error.Code)
|
|
}
|
|
}
|
|
|
|
func TestUserIDFromContextEmpty(t *testing.T) {
|
|
ctx := context.Background()
|
|
if id := UserIDFromContext(ctx); id != 0 {
|
|
t.Errorf("expected 0 from empty context, got %d", id)
|
|
}
|
|
}
|
|
|
|
func TestUserIDFromContextSet(t *testing.T) {
|
|
ctx := ContextWithUserID(context.Background(), 42)
|
|
if id := UserIDFromContext(ctx); id != 42 {
|
|
t.Errorf("expected 42, got %d", id)
|
|
}
|
|
}
|