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:
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 分钟,与默认值一致)
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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筛选
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 测试网关路由相关的数据库查询
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -4,7 +4,6 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
@@ -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",
|
||||
})
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// repo_robustness_test.go — repository 层鲁棒性测试
|
||||
// 覆盖:重复主键、唯一索引冲突、大量数据分页正确性、
|
||||
// SQL 注入防护(参数化查询验证)、软删除后查询、
|
||||
// 空字符串/极值/特殊字符输入、上下文取消
|
||||
//
|
||||
// SQL 注入防护(参数化查询验证)、软删除后查询、
|
||||
// 空字符串/极值/特殊字符输入、上下文取消
|
||||
package repository
|
||||
|
||||
import (
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user