watch-party/backend/internal/http/middleware_test.go

123 lines
3.0 KiB
Go

package httpapi
import (
"context"
"errors"
"net/http"
"net/http/httptest"
"testing"
fbauth "firebase.google.com/go/v4/auth"
"github.com/gin-gonic/gin"
)
type fakeVerifier struct {
token *fbauth.Token
err error
}
func (f fakeVerifier) Verify(_ context.Context, _ string) (*fbauth.Token, error) {
return f.token, f.err
}
func TestAuthMiddleware_MissingHeader(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(AuthMiddleware(fakeVerifier{}))
r.GET("/", func(c *gin.Context) {})
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusUnauthorized {
t.Fatalf("expected status %d, got %d", http.StatusUnauthorized, w.Code)
}
}
func TestAuthMiddleware_InvalidToken(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(AuthMiddleware(fakeVerifier{err: errors.New("boom")}))
r.GET("/", func(c *gin.Context) {})
req := httptest.NewRequest(http.MethodGet, "/", nil)
req.Header.Set("Authorization", "Bearer invalid")
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusUnauthorized {
t.Fatalf("expected status %d, got %d", http.StatusUnauthorized, w.Code)
}
}
func TestAuthMiddleware_Success(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(AuthMiddleware(fakeVerifier{token: &fbauth.Token{UID: "user-123"}}))
r.GET("/", func(c *gin.Context) {
c.Status(http.StatusOK)
})
req := httptest.NewRequest(http.MethodGet, "/", nil)
req.Header.Set("Authorization", "Bearer validtoken")
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d", http.StatusOK, w.Code)
}
}
func TestAdminOnly_MissingToken(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(AdminOnly())
r.GET("/", func(c *gin.Context) {})
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusUnauthorized {
t.Fatalf("expected status %d, got %d", http.StatusUnauthorized, w.Code)
}
}
func TestAdminOnly_Forbidden(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(func(c *gin.Context) {
c.Set("firebaseToken", &fbauth.Token{Claims: map[string]interface{}{"admin": false}})
})
r.Use(AdminOnly())
r.GET("/", func(c *gin.Context) {})
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusForbidden {
t.Fatalf("expected status %d, got %d", http.StatusForbidden, w.Code)
}
}
func TestAdminOnly_Success(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.New()
r.Use(func(c *gin.Context) {
c.Set("firebaseToken", &fbauth.Token{Claims: map[string]interface{}{"admin": true}})
})
r.Use(AdminOnly())
r.GET("/", func(c *gin.Context) { c.Status(http.StatusOK) })
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d", http.StatusOK, w.Code)
}
}