Files
user-system/internal/service/stats_test.go
long-agent 582ad7a069 test: add comprehensive test coverage and improve code quality
- Add new test files for auth, service, and handler modules
- Improve test organization and coverage
- Refactor code for better maintainability
- Add captcha, settings, stats, and theme handler tests
- Add auth module tests (CAS, OAuth, password, SSO, state)
- Add service layer tests for auth, export, permissions, roles
- All Go tests pass (exit code 0)
- All frontend tests pass (325 tests in 59 files)
2026-04-17 20:43:50 +08:00

135 lines
3.6 KiB
Go

package service_test
import (
"context"
"testing"
"time"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/service"
)
// =============================================================================
// Stats Service Tests - TDD approach
// =============================================================================
// mockStatsUserRepo 模拟用户仓储
type mockStatsUserRepo struct {
totalUsers int64
activeUsers int64
inactiveUsers int64
lockedUsers int64
disabledUsers int64
newUsersToday int64
}
func (m *mockStatsUserRepo) List(ctx context.Context, offset, limit int) ([]*domain.User, int64, error) {
return nil, m.totalUsers, nil
}
func (m *mockStatsUserRepo) ListByStatus(ctx context.Context, status domain.UserStatus, offset, limit int) ([]*domain.User, int64, error) {
switch status {
case domain.UserStatusActive:
return nil, m.activeUsers, nil
case domain.UserStatusInactive:
return nil, m.inactiveUsers, nil
case domain.UserStatusLocked:
return nil, m.lockedUsers, nil
case domain.UserStatusDisabled:
return nil, m.disabledUsers, nil
}
return nil, 0, nil
}
func (m *mockStatsUserRepo) ListCreatedAfter(ctx context.Context, since time.Time, offset, limit int) ([]*domain.User, int64, error) {
return nil, m.newUsersToday, nil
}
// mockStatsLoginLogRepo 模拟登录日志仓储
type mockStatsLoginLogRepo struct {
successCount int64
failedCount int64
weekCount int64
}
func (m *mockStatsLoginLogRepo) CountByResultSince(ctx context.Context, success bool, since time.Time) int64 {
if success {
return m.successCount
}
return m.failedCount
}
func TestStatsService_GetUserStats(t *testing.T) {
ctx := context.Background()
t.Run("获取用户统计", func(t *testing.T) {
userRepo := &mockStatsUserRepo{
totalUsers: 100,
activeUsers: 80,
inactiveUsers: 10,
lockedUsers: 5,
disabledUsers: 5,
newUsersToday: 3,
}
loginLogRepo := &mockStatsLoginLogRepo{}
svc := service.NewStatsService(userRepo, loginLogRepo)
stats, err := svc.GetUserStats(ctx)
if err != nil {
t.Fatalf("GetUserStats failed: %v", err)
}
if stats.TotalUsers != 100 {
t.Errorf("期望 TotalUsers=100, 得到 %d", stats.TotalUsers)
}
if stats.ActiveUsers != 80 {
t.Errorf("期望 ActiveUsers=80, 得到 %d", stats.ActiveUsers)
}
if stats.InactiveUsers != 10 {
t.Errorf("期望 InactiveUsers=10, 得到 %d", stats.InactiveUsers)
}
if stats.LockedUsers != 5 {
t.Errorf("期望 LockedUsers=5, 得到 %d", stats.LockedUsers)
}
if stats.DisabledUsers != 5 {
t.Errorf("期望 DisabledUsers=5, 得到 %d", stats.DisabledUsers)
}
})
}
func TestStatsService_GetDashboardStats(t *testing.T) {
ctx := context.Background()
t.Run("获取仪表盘统计", func(t *testing.T) {
userRepo := &mockStatsUserRepo{
totalUsers: 50,
activeUsers: 40,
inactiveUsers: 5,
lockedUsers: 3,
disabledUsers: 2,
newUsersToday: 2,
}
loginLogRepo := &mockStatsLoginLogRepo{
successCount: 100,
failedCount: 10,
weekCount: 500,
}
svc := service.NewStatsService(userRepo, loginLogRepo)
stats, err := svc.GetDashboardStats(ctx)
if err != nil {
t.Fatalf("GetDashboardStats failed: %v", err)
}
if stats.Users.TotalUsers != 50 {
t.Errorf("期望 Users.TotalUsers=50, 得到 %d", stats.Users.TotalUsers)
}
if stats.Logins.LoginsTodaySuccess != 100 {
t.Errorf("期望 LoginsTodaySuccess=100, 得到 %d", stats.Logins.LoginsTodaySuccess)
}
if stats.Logins.LoginsTodayFailed != 10 {
t.Errorf("期望 LoginsTodayFailed=10, 得到 %d", stats.Logins.LoginsTodayFailed)
}
})
}