Files
query-orchestration/internal/rbac/middleware_test.go
T
2025-03-19 12:51:24 -07:00

129 lines
4.0 KiB
Go

package rbac_test
import (
"crypto/rsa"
"math/big"
"net/http"
"net/http/httptest"
"testing"
"queryorchestration/internal/rbac"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
)
// mockKeyProvider is a mock implementation of the KeyProvider interface
type mockKeyProvider struct{}
// GetPublicKey returns a mock public key
func (m *mockKeyProvider) GetPublicKey(kid string) (*rsa.PublicKey, error) {
// Create a mock RSA public key with minimal valid structure
return &rsa.PublicKey{
N: big.NewInt(123), // Just a dummy value
E: 65537, // Common RSA exponent
}, nil
}
// createMockKeyProvider creates a mock KeyProvider for testing
func createMockKeyProvider() rbac.KeyProvider {
return &mockKeyProvider{}
}
// TestDefaultErrorHandler tests the defaultErrorHandler function
func TestDefaultErrorHandler(t *testing.T) {
// Create a new Echo instance
e := echo.New()
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
// Create a test error
//testErr := errors.New("test error")
// Access the defaultErrorHandler function directly
// In a real implementation, you might use an exported test helper function like:
// err := rbac.DefaultErrorHandlerTest(c, testErr)
// In this case, we'll test the error handler through the Echo middleware
// by creating a config with our own error handler that logs what was called
var capturedError error
customErrorHandler := func(c echo.Context, err error) error {
capturedError = err
return echo.NewHTTPError(http.StatusUnauthorized, "captured: "+err.Error())
}
config := rbac.JWTConfig{
KeyProvider: createMockKeyProvider(),
ErrorHandler: customErrorHandler,
}
// Create middleware with our config
middleware := rbac.JWTWithConfig(config)
// Create a handler that should never be called
handler := func(c echo.Context) error {
return c.String(http.StatusOK, "success")
}
// Call the middleware with a bad request (no Authorization header)
middlewareHandler := middleware(handler)
err := middlewareHandler(c)
// Verify that our error handler was called
assert.NotNil(t, capturedError)
assert.NotNil(t, err)
// The error should be an HTTP error
httpErr, ok := err.(*echo.HTTPError)
assert.True(t, ok)
assert.Equal(t, http.StatusUnauthorized, httpErr.Code)
}
// TestJWT tests the JWT function which creates middleware with default config
func TestJWT(t *testing.T) {
// Create a new Echo instance
e := echo.New()
// Create a simple test endpoint with the JWT middleware
e.GET("/protected", func(c echo.Context) error {
return c.String(http.StatusOK, "success")
}, rbac.JWT(createMockKeyProvider()))
// Create a test request with an invalid token (format doesn't matter for this test)
// The mock key provider will accept any token
req := httptest.NewRequest(http.MethodGet, "/protected", nil)
req.Header.Set("Authorization", "Bearer valid-token")
rec := httptest.NewRecorder()
// Process the request (this will fail because our mock doesn't properly validate)
e.ServeHTTP(rec, req)
// The response status should reflect whether validation succeeded
// In a real test, this would depend on token validity
// Here, we expect an error because our mock key provider doesn't correctly
// validate the token structure
assert.Equal(t, http.StatusUnauthorized, rec.Code)
}
// TestJWTWithMissingHeader tests JWT middleware with a missing Authorization header
func TestJWTWithMissingHeader(t *testing.T) {
// Create a new Echo instance
e := echo.New()
// Create a simple test endpoint with the JWT middleware
e.GET("/protected", func(c echo.Context) error {
return c.String(http.StatusOK, "success")
}, rbac.JWT(createMockKeyProvider()))
// Create a test request with no Authorization header
req := httptest.NewRequest(http.MethodGet, "/protected", nil)
rec := httptest.NewRecorder()
// Process the request
e.ServeHTTP(rec, req)
// This should fail with a 401 Unauthorized
assert.Equal(t, http.StatusUnauthorized, rec.Code)
}