Files
httpauth-firebase/httpauth_test.go
Rene Nochebuena 34c5fa7ded fix(httpauth-firebase)!: rename package httpauthfirebase, bump httpauth and rbac to v1.0.0
Rename package from httpauth to httpauthfirebase to follow ecosystem convention
(repo name = package name, hyphens removed). Bump httpauth dependency from
v0.1.0 to v1.0.0 and rbac indirect dependency from v0.9.0 to v1.0.0.

BREAKING CHANGE: import path unchanged (code.nochebuena.dev/go/httpauth-firebase)
but package identifier changes from httpauth to httpauthfirebase — remove any
import alias previously used to disambiguate from code.nochebuena.dev/go/httpauth.
2026-05-07 23:46:59 -06:00

98 lines
2.8 KiB
Go

package httpauthfirebase
import (
"context"
"errors"
"net/http"
"net/http/httptest"
"testing"
"firebase.google.com/go/v4/auth"
)
// --- mocks ---
type mockVerifier struct {
token *auth.Token
err error
}
func (m *mockVerifier) VerifyIDTokenAndCheckRevoked(_ context.Context, _ string) (*auth.Token, error) {
return m.token, m.err
}
func chain(mw func(http.Handler) http.Handler, h http.HandlerFunc) http.Handler {
return mw(h)
}
// --- AuthMiddleware ---
func TestAuthMiddleware_ValidToken(t *testing.T) {
mv := &mockVerifier{token: &auth.Token{UID: "uid123", Claims: map[string]any{"name": "Alice"}}}
reached := false
h := chain(AuthMiddleware(mv, nil), func(w http.ResponseWriter, r *http.Request) {
reached = true
w.WriteHeader(http.StatusOK)
})
req := httptest.NewRequest(http.MethodGet, "/api", nil)
req.Header.Set("Authorization", "Bearer valid-token")
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Errorf("want 200, got %d", rec.Code)
}
if !reached {
t.Error("inner handler was not called")
}
}
func TestAuthMiddleware_InvalidToken(t *testing.T) {
mv := &mockVerifier{err: errors.New("token invalid")}
h := chain(AuthMiddleware(mv, nil), func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
req := httptest.NewRequest(http.MethodGet, "/api", nil)
req.Header.Set("Authorization", "Bearer bad-token")
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != http.StatusUnauthorized {
t.Errorf("want 401, got %d", rec.Code)
}
}
func TestAuthMiddleware_MissingHeader(t *testing.T) {
mv := &mockVerifier{}
h := chain(AuthMiddleware(mv, nil), func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
rec := httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/api", nil))
if rec.Code != http.StatusUnauthorized {
t.Errorf("want 401, got %d", rec.Code)
}
}
func TestAuthMiddleware_PublicPath(t *testing.T) {
mv := &mockVerifier{err: errors.New("should not be called")}
h := chain(AuthMiddleware(mv, []string{"/health"}), func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
rec := httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/health", nil))
if rec.Code != http.StatusOK {
t.Errorf("want 200, got %d", rec.Code)
}
}
func TestAuthMiddleware_PublicPathWildcard(t *testing.T) {
mv := &mockVerifier{err: errors.New("should not be called")}
h := chain(AuthMiddleware(mv, []string{"/public/*"}), func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
rec := httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/public/resource", nil))
if rec.Code != http.StatusOK {
t.Errorf("want 200, got %d", rec.Code)
}
}