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)
This commit is contained in:
2026-04-17 20:43:50 +08:00
parent 0d66aa0423
commit 582ad7a069
136 changed files with 19010 additions and 8544 deletions

View File

@@ -8,8 +8,8 @@ import (
"strings"
"testing"
"github.com/user-management-system/internal/service"
"github.com/stretchr/testify/require"
"github.com/user-management-system/internal/service"
)
func uniqueTestValue(t *testing.T, prefix string) string {

View File

@@ -8,10 +8,10 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/user-management-system/internal/service"
)
type BillingCacheSuite struct {

View File

@@ -8,10 +8,10 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/user-management-system/internal/service"
)
// 测试用 TTL 配置15 分钟,与默认值一致)

View File

@@ -6,10 +6,10 @@ import (
"sync/atomic"
"testing"
_ "modernc.org/sqlite"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite"
"github.com/user-management-system/internal/domain"
)

View File

@@ -5,8 +5,8 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/config"
"github.com/stretchr/testify/require"
"github.com/user-management-system/internal/config"
_ "github.com/lib/pq"
)

View File

@@ -7,10 +7,10 @@ import (
"testing"
"time"
_ "modernc.org/sqlite"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/pagination"
@@ -496,11 +496,11 @@ func TestDeviceRepository_ListAllCursor(t *testing.T) {
now := time.Now()
for i := 0; i < 5; i++ {
repo.Create(ctx, &domain.Device{
UserID: int64(i + 1),
DeviceID: "cursor-device-" + string(rune('a'+i)),
DeviceName: "设备" + string(rune('0'+i)),
Status: domain.DeviceStatusActive,
LastActiveTime: now.Add(-time.Duration(i) * time.Minute),
UserID: int64(i + 1),
DeviceID: "cursor-device-" + string(rune('a'+i)),
DeviceName: "设备" + string(rune('0'+i)),
Status: domain.DeviceStatusActive,
LastActiveTime: now.Add(-time.Duration(i) * time.Minute),
})
}
@@ -542,25 +542,25 @@ func TestDeviceRepository_ListAllCursor_WithFilters(t *testing.T) {
now := time.Now()
repo.Create(ctx, &domain.Device{
UserID: 1,
DeviceID: "filter-dev1",
DeviceName: "用户1设备",
Status: domain.DeviceStatusActive,
LastActiveTime: now,
UserID: 1,
DeviceID: "filter-dev1",
DeviceName: "用户1设备",
Status: domain.DeviceStatusActive,
LastActiveTime: now,
})
repo.Create(ctx, &domain.Device{
UserID: 2,
DeviceID: "filter-dev2",
DeviceName: "用户2设备",
Status: domain.DeviceStatusActive,
LastActiveTime: now,
UserID: 2,
DeviceID: "filter-dev2",
DeviceName: "用户2设备",
Status: domain.DeviceStatusActive,
LastActiveTime: now,
})
repo.Create(ctx, &domain.Device{
UserID: 1,
DeviceID: "filter-dev3",
DeviceName: "用户1禁用设备",
Status: domain.DeviceStatusInactive,
LastActiveTime: now,
UserID: 1,
DeviceID: "filter-dev3",
DeviceName: "用户1禁用设备",
Status: domain.DeviceStatusInactive,
LastActiveTime: now,
})
// 按用户ID筛选

View File

@@ -7,10 +7,10 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/user-management-system/internal/service"
)
type EmailCacheSuite struct {

View File

@@ -7,10 +7,10 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/user-management-system/internal/service"
)
type GatewayCacheSuite struct {

View File

@@ -6,9 +6,9 @@ import (
"context"
"testing"
"github.com/stretchr/testify/suite"
dbent "github.com/user-management-system/ent"
"github.com/user-management-system/internal/service"
"github.com/stretchr/testify/suite"
)
// GatewayRoutingSuite 测试网关路由相关的数据库查询

View File

@@ -7,10 +7,10 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/user-management-system/internal/service"
)
type GeminiTokenCacheSuite struct {

View File

@@ -8,10 +8,10 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/user-management-system/internal/service"
)
type IdentityCacheSuite struct {

View File

@@ -4,7 +4,6 @@ package repository
import (
"context"
"testing"
"time"
"github.com/redis/go-redis/v9"

View File

@@ -7,10 +7,10 @@ import (
"testing"
"time"
_ "modernc.org/sqlite"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/pagination"
@@ -139,10 +139,10 @@ func TestLoginLogRepository_ListAllForExport(t *testing.T) {
Status: 1,
})
repo.Create(ctx, &domain.LoginLog{
UserID: int64Ptr(2),
LoginType: 2,
IP: "192.168.1.2",
Status: 0,
UserID: int64Ptr(2),
LoginType: 2,
IP: "192.168.1.2",
Status: 0,
FailReason: "invalid password",
})

View File

@@ -7,10 +7,10 @@ import (
"testing"
"time"
_ "modernc.org/sqlite"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/pagination"
@@ -53,7 +53,7 @@ func TestOperationLogRepository_ListCursor(t *testing.T) {
for i := 0; i < 5; i++ {
repo.Create(ctx, &domain.OperationLog{
UserID: nil,
OperationType: "test",
OperationType: "test",
OperationName: "测试操作" + string(rune('0'+i)),
RequestMethod: "GET",
RequestPath: "/api/test",

View File

@@ -7,8 +7,8 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/service"
"github.com/stretchr/testify/require"
"github.com/user-management-system/internal/service"
)
func TestOpsRepositoryBatchInsertErrorLogs(t *testing.T) {

View File

@@ -4,8 +4,8 @@ import (
"testing"
"time"
"github.com/user-management-system/internal/config"
"github.com/stretchr/testify/require"
"github.com/user-management-system/internal/config"
)
func TestBuildRedisOptions(t *testing.T) {

View File

@@ -9,10 +9,10 @@ import (
"sync/atomic"
"testing"
_ "modernc.org/sqlite"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite"
"github.com/user-management-system/internal/domain"
)

View File

@@ -1,7 +1,8 @@
// repo_robustness_test.go — repository 层鲁棒性测试
// 覆盖:重复主键、唯一索引冲突、大量数据分页正确性、
// SQL 注入防护(参数化查询验证)、软删除后查询、
// 空字符串/极值/特殊字符输入、上下文取消
//
// SQL 注入防护(参数化查询验证)、软删除后查询、
// 空字符串/极值/特殊字符输入、上下文取消
package repository
import (

View File

@@ -7,9 +7,9 @@ import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/user-management-system/internal/config"
"github.com/user-management-system/internal/service"
"github.com/stretchr/testify/require"
)
func TestSchedulerSnapshotOutboxReplay(t *testing.T) {

View File

@@ -6,10 +6,10 @@ import (
"sync/atomic"
"testing"
_ "modernc.org/sqlite"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite"
"github.com/user-management-system/internal/domain"
)

View File

@@ -5,10 +5,10 @@ import (
"sync/atomic"
"testing"
_ "modernc.org/sqlite" // 纯 Go SQLite注册 "sqlite" 驱动
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite" // 纯 Go SQLite注册 "sqlite" 驱动
"github.com/user-management-system/internal/domain"
)

View File

@@ -6,10 +6,10 @@ import (
"sync/atomic"
"testing"
_ "modernc.org/sqlite"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite"
"github.com/user-management-system/internal/domain"
)
@@ -72,9 +72,9 @@ func TestThemeConfigRepository_GetByID(t *testing.T) {
ctx := context.Background()
theme := &domain.ThemeConfig{
Name: "getbyid-theme",
Name: "getbyid-theme",
PrimaryColor: "#0000ff",
Enabled: true,
Enabled: true,
}
repo.Create(ctx, theme)
@@ -94,9 +94,9 @@ func TestThemeConfigRepository_GetByName(t *testing.T) {
ctx := context.Background()
theme := &domain.ThemeConfig{
Name: "unique-theme-name",
Name: "unique-theme-name",
PrimaryColor: "#ffff00",
Enabled: true,
Enabled: true,
}
repo.Create(ctx, theme)

View File

@@ -7,10 +7,10 @@ import (
"testing"
"time"
"github.com/stretchr/testify/suite"
dbent "github.com/user-management-system/ent"
"github.com/user-management-system/internal/pkg/pagination"
"github.com/user-management-system/internal/service"
"github.com/stretchr/testify/suite"
)
type UserRepoSuite struct {

View File

@@ -355,14 +355,14 @@ func TestUserRepository_Search(t *testing.T) {
ctx := context.Background()
repo.Create(ctx, &domain.User{
Username: "searchuser1",
Username: "searchuser1",
Nickname: "张三",
Email: domain.StrPtr("zhangsan@example.com"),
Password: "hash",
Status: domain.UserStatusActive,
})
repo.Create(ctx, &domain.User{
Username: "searchuser2",
Username: "searchuser2",
Nickname: "李四",
Email: domain.StrPtr("lisi@example.com"),
Password: "hash",
@@ -388,7 +388,7 @@ func TestUserRepository_Search_LikePattern(t *testing.T) {
ctx := context.Background()
repo.Create(ctx, &domain.User{
Username: "user%with%percent",
Username: "user%with%percent",
Nickname: "测试用户",
Email: domain.StrPtr("percent@example.com"),
Password: "hash",
@@ -642,8 +642,8 @@ func TestUserRepository_AdvancedSearch_LikeSpecialChars(t *testing.T) {
ctx := context.Background()
repo.Create(ctx, &domain.User{
Username: "user%with%percent",
Nickname: "测试用户",
Username: "user%with%percent",
Nickname: "测试用户",
Password: "hash",
Status: domain.UserStatusActive,
})
@@ -806,4 +806,3 @@ func TestUserRepository_ListCursor_WithRoleIDs(t *testing.T) {
t.Errorf("users[0].Username = %s, want roleuser1", users[0].Username)
}
}

View File

@@ -8,10 +8,10 @@ import (
"testing"
"time"
"github.com/stretchr/testify/suite"
dbent "github.com/user-management-system/ent"
"github.com/user-management-system/internal/pkg/pagination"
"github.com/user-management-system/internal/service"
"github.com/stretchr/testify/suite"
)
type UserSubscriptionRepoSuite struct {