332 lines
12 KiB
Go
332 lines
12 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"testing"
|
|
|
|
archivalDomain "git.nakama.town/fmartingr/hako/internal/archival/domain"
|
|
authDomain "git.nakama.town/fmartingr/hako/internal/auth/domain"
|
|
"git.nakama.town/fmartingr/hako/internal/server/middleware"
|
|
"git.nakama.town/fmartingr/hako/internal/testutil"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestHandleLogin_Success(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Initialize domains
|
|
deps.Dependencies.Domains().SetLinks(archivalDomain.NewLinkDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetArchives(archivalDomain.NewArchiveDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetCategories(archivalDomain.NewCategoryDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetAuth(authDomain.NewAuthDomain(deps.Dependencies))
|
|
|
|
// Create a test user first
|
|
_, _, err := testutil.NewTestUser(t, deps.Dependencies, "test@example.com", "testpassword123")
|
|
require.NoError(t, err)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Create login request
|
|
loginReq := map[string]string{
|
|
"email": "test@example.com",
|
|
"password": "testpassword123",
|
|
}
|
|
body, _ := json.Marshal(loginReq)
|
|
|
|
// Perform request
|
|
w := testutil.PerformRequest(authHandler.HandleLogin, http.MethodPost, "/api/v1/auth/login",
|
|
testutil.WithBody(string(body)),
|
|
testutil.WithHeader("Content-Type", "application/json"),
|
|
)
|
|
|
|
// Assert response
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusOK)
|
|
|
|
// Check response structure
|
|
tokenValue := resp.AssertJSONContainsKey(t, "token")
|
|
require.NotEmpty(t, tokenValue)
|
|
|
|
userValue := resp.AssertJSONContainsKey(t, "user")
|
|
userMap, ok := userValue.(map[string]any)
|
|
require.True(t, ok)
|
|
require.Equal(t, "test@example.com", userMap["email"])
|
|
// Verify role is returned (should default to "user")
|
|
require.Equal(t, "user", userMap["role"])
|
|
}
|
|
|
|
func TestHandleLogin_InvalidCredentials(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Initialize domains
|
|
deps.Dependencies.Domains().SetLinks(archivalDomain.NewLinkDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetArchives(archivalDomain.NewArchiveDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetCategories(archivalDomain.NewCategoryDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetAuth(authDomain.NewAuthDomain(deps.Dependencies))
|
|
|
|
// Create a test user first
|
|
_, _, err := testutil.NewTestUser(t, deps.Dependencies, "test@example.com", "testpassword123")
|
|
require.NoError(t, err)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Create login request with wrong password
|
|
loginReq := map[string]string{
|
|
"email": "test@example.com",
|
|
"password": "wrongpassword",
|
|
}
|
|
body, _ := json.Marshal(loginReq)
|
|
|
|
// Perform request
|
|
w := testutil.PerformRequest(authHandler.HandleLogin, http.MethodPost, "/api/v1/auth/login",
|
|
testutil.WithBody(string(body)),
|
|
testutil.WithHeader("Content-Type", "application/json"),
|
|
)
|
|
|
|
// Assert response
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusUnauthorized)
|
|
resp.AssertBodyContains(t, "Invalid credentials")
|
|
}
|
|
|
|
func TestHandleLogin_MissingFields(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Test with empty email
|
|
loginReq := map[string]string{
|
|
"email": "",
|
|
"password": "testpassword123",
|
|
}
|
|
body, _ := json.Marshal(loginReq)
|
|
|
|
w := testutil.PerformRequest(authHandler.HandleLogin, http.MethodPost, "/api/v1/auth/login",
|
|
testutil.WithBody(string(body)),
|
|
testutil.WithHeader("Content-Type", "application/json"),
|
|
)
|
|
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusBadRequest)
|
|
resp.AssertBodyContains(t, "Email and password are required")
|
|
|
|
// Test with empty password
|
|
loginReq = map[string]string{
|
|
"email": "test@example.com",
|
|
"password": "",
|
|
}
|
|
body, _ = json.Marshal(loginReq)
|
|
|
|
w = testutil.PerformRequest(authHandler.HandleLogin, http.MethodPost, "/api/v1/auth/login",
|
|
testutil.WithBody(string(body)),
|
|
testutil.WithHeader("Content-Type", "application/json"),
|
|
)
|
|
|
|
resp = testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusBadRequest)
|
|
resp.AssertBodyContains(t, "Email and password are required")
|
|
}
|
|
|
|
func TestHandleLogin_InvalidMethod(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Try GET instead of POST
|
|
w := testutil.PerformRequest(authHandler.HandleLogin, http.MethodGet, "/api/v1/auth/login")
|
|
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusMethodNotAllowed)
|
|
resp.AssertBodyContains(t, "Method not allowed")
|
|
}
|
|
|
|
func TestHandleGetCurrentUser_Success(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Initialize domains
|
|
deps.Dependencies.Domains().SetLinks(archivalDomain.NewLinkDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetArchives(archivalDomain.NewArchiveDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetCategories(archivalDomain.NewCategoryDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetAuth(authDomain.NewAuthDomain(deps.Dependencies))
|
|
|
|
// Create a test user and get token
|
|
user, token, err := testutil.NewTestUser(t, deps.Dependencies, "test@example.com", "testpassword123")
|
|
require.NoError(t, err)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Create handlers with new middleware pattern
|
|
// Global auth middleware sets context if token is present
|
|
globalAuthMiddleware := middleware.AuthMiddleware(deps.Dependencies.GetJWTService(), deps.Dependencies.UserStore)
|
|
// Require auth middleware blocks if not authenticated
|
|
requireAuthMiddleware := middleware.RequireAuthMiddleware()
|
|
handler := globalAuthMiddleware(requireAuthMiddleware(http.HandlerFunc(authHandler.HandleGetCurrentUser)))
|
|
|
|
// Perform authenticated request
|
|
w := testutil.PerformRequestWithHandler(handler, http.MethodGet, "/api/v1/auth/me",
|
|
testutil.WithAuthToken(token),
|
|
)
|
|
|
|
// Assert response
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusOK)
|
|
|
|
// Check response structure
|
|
emailValue := resp.AssertJSONContainsKey(t, "email")
|
|
require.Equal(t, user.Email, emailValue)
|
|
// Verify role is returned
|
|
roleValue := resp.AssertJSONContainsKey(t, "role")
|
|
require.Equal(t, "user", roleValue)
|
|
}
|
|
|
|
func TestHandleGetCurrentUser_Unauthorized(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Create handlers with new middleware pattern
|
|
globalAuthMiddleware := middleware.AuthMiddleware(deps.Dependencies.GetJWTService(), deps.Dependencies.UserStore)
|
|
requireAuthMiddleware := middleware.RequireAuthMiddleware()
|
|
handler := globalAuthMiddleware(requireAuthMiddleware(http.HandlerFunc(authHandler.HandleGetCurrentUser)))
|
|
|
|
// Perform request without token
|
|
w := testutil.PerformRequestWithHandler(handler, http.MethodGet, "/api/v1/auth/me")
|
|
|
|
// Assert response
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusUnauthorized)
|
|
resp.AssertBodyContains(t, "Authorization required")
|
|
}
|
|
|
|
func TestHandleGetCurrentUser_InvalidToken(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Create handlers with new middleware pattern
|
|
globalAuthMiddleware := middleware.AuthMiddleware(deps.Dependencies.GetJWTService(), deps.Dependencies.UserStore)
|
|
requireAuthMiddleware := middleware.RequireAuthMiddleware()
|
|
handler := globalAuthMiddleware(requireAuthMiddleware(http.HandlerFunc(authHandler.HandleGetCurrentUser)))
|
|
|
|
// Perform request with invalid token
|
|
w := testutil.PerformRequestWithHandler(handler, http.MethodGet, "/api/v1/auth/me",
|
|
testutil.WithAuthToken("invalid-token"),
|
|
)
|
|
|
|
// Assert response
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusUnauthorized)
|
|
resp.AssertBodyContains(t, "Authorization required")
|
|
}
|
|
|
|
func TestHandleGetCurrentUser_InvalidMethod(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Try POST instead of GET
|
|
w := testutil.PerformRequest(authHandler.HandleGetCurrentUser, http.MethodPost, "/api/v1/auth/me")
|
|
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusMethodNotAllowed)
|
|
resp.AssertBodyContains(t, "Method not allowed")
|
|
}
|
|
|
|
func TestHandleLogin_ReturnsRole(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Initialize domains
|
|
deps.Dependencies.Domains().SetLinks(archivalDomain.NewLinkDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetArchives(archivalDomain.NewArchiveDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetCategories(archivalDomain.NewCategoryDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetAuth(authDomain.NewAuthDomain(deps.Dependencies))
|
|
|
|
// Create a test admin user
|
|
_, _, err := testutil.NewTestAdminUser(t, deps.Dependencies, "admin@example.com", "adminpassword123")
|
|
require.NoError(t, err)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Create login request
|
|
loginReq := map[string]string{
|
|
"email": "admin@example.com",
|
|
"password": "adminpassword123",
|
|
}
|
|
body, _ := json.Marshal(loginReq)
|
|
|
|
// Perform request
|
|
w := testutil.PerformRequest(authHandler.HandleLogin, http.MethodPost, "/api/v1/auth/login",
|
|
testutil.WithBody(string(body)),
|
|
testutil.WithHeader("Content-Type", "application/json"),
|
|
)
|
|
|
|
// Assert response
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusOK)
|
|
|
|
// Check response structure
|
|
userValue := resp.AssertJSONContainsKey(t, "user")
|
|
userMap, ok := userValue.(map[string]any)
|
|
require.True(t, ok)
|
|
require.Equal(t, "admin@example.com", userMap["email"])
|
|
require.Equal(t, "admin", userMap["role"])
|
|
}
|
|
|
|
func TestHandleGetCurrentUser_ReturnsRole(t *testing.T) {
|
|
ctx := context.Background()
|
|
deps := testutil.GetTestConfigurationAndDependencies(t, ctx)
|
|
|
|
// Initialize domains
|
|
deps.Dependencies.Domains().SetLinks(archivalDomain.NewLinkDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetArchives(archivalDomain.NewArchiveDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetCategories(archivalDomain.NewCategoryDomain(deps.Dependencies))
|
|
deps.Dependencies.Domains().SetAuth(authDomain.NewAuthDomain(deps.Dependencies))
|
|
|
|
// Create a test admin user and get token
|
|
user, token, err := testutil.NewTestAdminUser(t, deps.Dependencies, "admin@example.com", "adminpassword123")
|
|
require.NoError(t, err)
|
|
|
|
// Create auth handler
|
|
authHandler := NewAuthHandler(deps.Dependencies)
|
|
|
|
// Create handlers with new middleware pattern
|
|
globalAuthMiddleware := middleware.AuthMiddleware(deps.Dependencies.GetJWTService(), deps.Dependencies.UserStore)
|
|
requireAuthMiddleware := middleware.RequireAuthMiddleware()
|
|
handler := globalAuthMiddleware(requireAuthMiddleware(http.HandlerFunc(authHandler.HandleGetCurrentUser)))
|
|
|
|
// Perform authenticated request
|
|
w := testutil.PerformRequestWithHandler(handler, http.MethodGet, "/api/v1/auth/me",
|
|
testutil.WithAuthToken(token),
|
|
)
|
|
|
|
// Assert response
|
|
resp := testutil.NewTestResponse(w)
|
|
resp.AssertStatus(t, http.StatusOK)
|
|
|
|
// Check response structure
|
|
emailValue := resp.AssertJSONContainsKey(t, "email")
|
|
require.Equal(t, user.Email, emailValue)
|
|
// Verify admin role is returned
|
|
roleValue := resp.AssertJSONContainsKey(t, "role")
|
|
require.Equal(t, "admin", roleValue)
|
|
}
|