Files
user-system/internal/service/auth_login_test.go

286 lines
7.1 KiB
Go

package service_test
import (
"context"
"testing"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/service"
)
// =============================================================================
// Auth Login Tests - Phase 1
// =============================================================================
func TestAuthService_Login(t *testing.T) {
env := setupAuthTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
t.Run("Login success", func(t *testing.T) {
// Register user first
req := &service.RegisterRequest{
Username: "loginuser",
Password: "Test123!",
Email: "login@test.com",
}
_, err := env.authSvc.Register(ctx, req)
if err != nil {
t.Fatalf("Register failed: %v", err)
}
// Login
resp, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "loginuser",
Password: "Test123!",
}, "127.0.0.1")
if err != nil {
t.Fatalf("Login failed: %v", err)
}
if resp.AccessToken == "" {
t.Error("Expected access token")
}
if resp.User.Username != "loginuser" {
t.Errorf("Expected username 'loginuser', got %s", resp.User.Username)
}
})
t.Run("Login with wrong password", func(t *testing.T) {
_, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "loginuser",
Password: "wrongpassword",
}, "127.0.0.1")
if err == nil {
t.Error("Expected error for wrong password")
}
})
t.Run("Login with non-existent user", func(t *testing.T) {
_, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "nonexistent",
Password: "Test123!",
}, "127.0.0.1")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("Login with empty username", func(t *testing.T) {
_, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "",
Password: "Test123!",
}, "127.0.0.1")
if err == nil {
t.Error("Expected error for empty username")
}
})
t.Run("Login with empty password", func(t *testing.T) {
_, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "loginuser",
Password: "",
}, "127.0.0.1")
if err == nil {
t.Error("Expected error for empty password")
}
})
t.Run("Login with nil request", func(t *testing.T) {
_, err := env.authSvc.Login(ctx, nil, "127.0.0.1")
if err == nil {
t.Error("Expected error for nil request")
}
})
t.Run("Login for locked user", func(t *testing.T) {
// Register and lock user
req := &service.RegisterRequest{
Username: "lockeduser",
Password: "Test123!",
}
resp, _ := env.authSvc.Register(ctx, req)
env.userSvc.UpdateStatus(ctx, resp.ID, domain.UserStatusLocked)
// Try to login
_, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "lockeduser",
Password: "Test123!",
}, "127.0.0.1")
if err == nil {
t.Error("Expected error for locked user")
}
})
t.Run("Login for disabled user", func(t *testing.T) {
req := &service.RegisterRequest{
Username: "disableduser",
Password: "Test123!",
}
resp, _ := env.authSvc.Register(ctx, req)
env.userSvc.UpdateStatus(ctx, resp.ID, domain.UserStatusDisabled)
_, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "disableduser",
Password: "Test123!",
}, "127.0.0.1")
if err == nil {
t.Error("Expected error for disabled user")
}
})
t.Run("Login for inactive user", func(t *testing.T) {
req := &service.RegisterRequest{
Username: "inactiveuser",
Password: "Test123!",
}
resp, _ := env.authSvc.Register(ctx, req)
env.userSvc.UpdateStatus(ctx, resp.ID, domain.UserStatusInactive)
_, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "inactiveuser",
Password: "Test123!",
}, "127.0.0.1")
if err == nil {
t.Error("Expected error for inactive user")
}
})
t.Run("nil service Login", func(t *testing.T) {
var nilSvc *service.AuthService
_, err := nilSvc.Login(ctx, &service.LoginRequest{
Username: "test",
Password: "test",
}, "127.0.0.1")
if err == nil {
t.Error("nil service should return error")
}
})
t.Run("login with totp enabled returns temporary challenge token", func(t *testing.T) {
req := &service.RegisterRequest{
Username: "totploginuser",
Password: "Test123!",
Email: "totplogin@test.com",
}
user, err := env.authSvc.Register(ctx, req)
if err != nil {
t.Fatalf("Register failed: %v", err)
}
if err := env.db.Model(&domain.User{}).Where("id = ?", user.ID).Updates(map[string]interface{}{
"totp_enabled": true,
"totp_secret": "JBSWY3DPEHPK3PXP",
}).Error; err != nil {
t.Fatalf("enable totp failed: %v", err)
}
resp, err := env.authSvc.Login(ctx, &service.LoginRequest{
Username: "totploginuser",
Password: "Test123!",
}, "127.0.0.1")
if err != nil {
t.Fatalf("Login failed: %v", err)
}
if !resp.RequiresTOTP {
t.Fatal("expected requires_totp response")
}
if resp.TempToken == "" {
t.Fatal("expected temp_token for second-factor challenge")
}
if resp.AccessToken != "" || resp.RefreshToken != "" {
t.Fatal("totp challenge should not mint full session tokens before second factor verification")
}
})
}
func TestAuthService_Register(t *testing.T) {
env := setupAuthTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
t.Run("Register success", func(t *testing.T) {
req := &service.RegisterRequest{
Username: "newuser",
Password: "Test123!",
Email: "new@test.com",
Nickname: "New User",
}
resp, err := env.authSvc.Register(ctx, req)
if err != nil {
t.Fatalf("Register failed: %v", err)
}
if resp.Username != "newuser" {
t.Errorf("Expected username 'newuser', got %s", resp.Username)
}
})
t.Run("Register with duplicate username", func(t *testing.T) {
req := &service.RegisterRequest{
Username: "dupuser",
Password: "Test123!",
}
env.authSvc.Register(ctx, req)
// Try again
_, err := env.authSvc.Register(ctx, req)
if err == nil {
t.Error("Expected error for duplicate username")
}
})
t.Run("Register with empty username", func(t *testing.T) {
req := &service.RegisterRequest{
Username: "",
Password: "Test123!",
}
_, err := env.authSvc.Register(ctx, req)
if err == nil {
t.Error("Expected error for empty username")
}
})
t.Run("Register with empty password", func(t *testing.T) {
req := &service.RegisterRequest{
Username: "nopass",
Password: "",
}
_, err := env.authSvc.Register(ctx, req)
if err == nil {
t.Error("Expected error for empty password")
}
})
t.Run("Register with weak password", func(t *testing.T) {
req := &service.RegisterRequest{
Username: "weakpass",
Password: "123",
}
_, err := env.authSvc.Register(ctx, req)
if err == nil {
t.Error("Expected error for weak password")
}
})
t.Run("Register with nil request", func(t *testing.T) {
_, err := env.authSvc.Register(ctx, nil)
if err == nil {
t.Error("Expected error for nil request")
}
})
t.Run("nil service Register", func(t *testing.T) {
var nilSvc *service.AuthService
req := &service.RegisterRequest{
Username: "test",
Password: "Test123!",
}
_, err := nilSvc.Register(ctx, req)
if err == nil {
t.Error("nil service should return error")
}
})
}