Files
user-system/internal/service/custom_field_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

497 lines
13 KiB
Go

package service_test
import (
"context"
"testing"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/repository"
"github.com/user-management-system/internal/service"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// =============================================================================
// Custom Field Service Tests
// =============================================================================
func setupCustomFieldTestEnv(t *testing.T) (*service.CustomFieldService, *gorm.DB) {
t.Helper()
db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{
DriverName: "sqlite",
DSN: "file:customfield_test?mode=memory&cache=shared",
}), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
t.Fatalf("failed to connect database: %v", err)
}
if err := db.AutoMigrate(&domain.CustomField{}, &domain.UserCustomFieldValue{}); err != nil {
t.Fatalf("failed to migrate: %v", err)
}
fieldRepo := repository.NewCustomFieldRepository(db)
valueRepo := repository.NewUserCustomFieldValueRepository(db)
svc := service.NewCustomFieldService(fieldRepo, valueRepo)
return svc, db
}
func TestCustomFieldService_CreateField(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
t.Run("Create field success", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "测试字段",
FieldKey: "test_field",
Type: int(domain.CustomFieldTypeString),
Required: false,
}
field, err := svc.CreateField(ctx, req)
if err != nil {
t.Fatalf("CreateField failed: %v", err)
}
if field.FieldKey != "test_field" {
t.Errorf("Expected field key 'test_field', got %s", field.FieldKey)
}
})
t.Run("Create field with duplicate key", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "重复字段",
FieldKey: "test_field", // duplicate
Type: int(domain.CustomFieldTypeString),
}
_, err := svc.CreateField(ctx, req)
if err == nil {
t.Error("Expected error for duplicate field key")
}
})
t.Run("Create number field", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "数字字段",
FieldKey: "number_field",
Type: int(domain.CustomFieldTypeNumber),
MinVal: 0,
MaxVal: 100,
}
field, err := svc.CreateField(ctx, req)
if err != nil {
t.Fatalf("CreateField failed: %v", err)
}
if field.Type != domain.CustomFieldTypeNumber {
t.Errorf("Expected type number, got %d", field.Type)
}
})
t.Run("Create boolean field", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "布尔字段",
FieldKey: "bool_field",
Type: int(domain.CustomFieldTypeBoolean),
}
_, err := svc.CreateField(ctx, req)
if err != nil {
t.Fatalf("CreateField failed: %v", err)
}
})
t.Run("Create date field", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "日期字段",
FieldKey: "date_field",
Type: int(domain.CustomFieldTypeDate),
}
_, err := svc.CreateField(ctx, req)
if err != nil {
t.Fatalf("CreateField failed: %v", err)
}
})
}
func TestCustomFieldService_UpdateField(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
// Create test field
req := &service.CreateFieldRequest{
Name: "更新测试",
FieldKey: "update_field",
Type: int(domain.CustomFieldTypeString),
}
field, _ := svc.CreateField(ctx, req)
t.Run("Update field name", func(t *testing.T) {
updateReq := &service.UpdateFieldRequest{
Name: "更新后名称",
}
updated, err := svc.UpdateField(ctx, field.ID, updateReq)
if err != nil {
t.Fatalf("UpdateField failed: %v", err)
}
if updated.Name != "更新后名称" {
t.Errorf("Expected name '更新后名称', got %s", updated.Name)
}
})
t.Run("Update field required", func(t *testing.T) {
required := true
updateReq := &service.UpdateFieldRequest{
Required: &required,
}
updated, err := svc.UpdateField(ctx, field.ID, updateReq)
if err != nil {
t.Fatalf("UpdateField failed: %v", err)
}
if !updated.Required {
t.Error("Expected required to be true")
}
})
t.Run("Update non-existent field", func(t *testing.T) {
updateReq := &service.UpdateFieldRequest{
Name: "不存在",
}
_, err := svc.UpdateField(ctx, 9999, updateReq)
if err == nil {
t.Error("Expected error for non-existent field")
}
})
}
func TestCustomFieldService_DeleteField(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
t.Run("Delete field success", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "待删除字段",
FieldKey: "delete_field",
Type: int(domain.CustomFieldTypeString),
}
field, _ := svc.CreateField(ctx, req)
err := svc.DeleteField(ctx, field.ID)
if err != nil {
t.Fatalf("DeleteField failed: %v", err)
}
})
t.Run("Delete non-existent field", func(t *testing.T) {
err := svc.DeleteField(ctx, 9999)
if err == nil {
t.Error("Expected error for non-existent field")
}
})
}
func TestCustomFieldService_GetField(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
req := &service.CreateFieldRequest{
Name: "获取测试",
FieldKey: "get_field",
Type: int(domain.CustomFieldTypeString),
}
created, _ := svc.CreateField(ctx, req)
t.Run("Get field success", func(t *testing.T) {
field, err := svc.GetField(ctx, created.ID)
if err != nil {
t.Fatalf("GetField failed: %v", err)
}
if field.FieldKey != "get_field" {
t.Errorf("Expected field key 'get_field', got %s", field.FieldKey)
}
})
}
func TestCustomFieldService_ListFields(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
// Create test fields
for i := 0; i < 3; i++ {
req := &service.CreateFieldRequest{
Name: "列表字段",
FieldKey: string(rune('a' + i)),
Type: int(domain.CustomFieldTypeString),
}
svc.CreateField(ctx, req)
}
t.Run("List fields", func(t *testing.T) {
fields, err := svc.ListFields(ctx)
if err != nil {
t.Fatalf("ListFields failed: %v", err)
}
if len(fields) < 3 {
t.Errorf("Expected at least 3 fields, got %d", len(fields))
}
})
t.Run("List all fields", func(t *testing.T) {
fields, err := svc.ListAllFields(ctx)
if err != nil {
t.Fatalf("ListAllFields failed: %v", err)
}
if len(fields) < 3 {
t.Errorf("Expected at least 3 fields, got %d", len(fields))
}
})
}
func TestCustomFieldService_SetUserFieldValue(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
// Create test field
req := &service.CreateFieldRequest{
Name: "用户字段",
FieldKey: "user_field",
Type: int(domain.CustomFieldTypeString),
}
svc.CreateField(ctx, req)
t.Run("Set user field value success", func(t *testing.T) {
err := svc.SetUserFieldValue(ctx, 1, "user_field", "test value")
if err != nil {
t.Fatalf("SetUserFieldValue failed: %v", err)
}
})
t.Run("Set user field value with non-existent field", func(t *testing.T) {
err := svc.SetUserFieldValue(ctx, 1, "non_existent", "value")
if err == nil {
t.Error("Expected error for non-existent field")
}
})
}
func TestCustomFieldService_GetUserFieldValues(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
// Create test field
req := &service.CreateFieldRequest{
Name: "值字段",
FieldKey: "value_field",
Type: int(domain.CustomFieldTypeString),
}
svc.CreateField(ctx, req)
// Set value
svc.SetUserFieldValue(ctx, 1, "value_field", "test value")
t.Run("Get user field values", func(t *testing.T) {
values, err := svc.GetUserFieldValues(ctx, 1)
if err != nil {
t.Fatalf("GetUserFieldValues failed: %v", err)
}
if len(values) == 0 {
t.Error("Expected at least one field value")
}
})
}
func TestCustomFieldService_ValidateFieldValue(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
t.Run("Validate required field", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "必填字段",
FieldKey: "required_field",
Type: int(domain.CustomFieldTypeString),
Required: true,
}
svc.CreateField(ctx, req)
err := svc.SetUserFieldValue(ctx, 1, "required_field", "")
if err == nil {
t.Error("Expected error for empty required field")
}
})
t.Run("Validate number field", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "数字验证",
FieldKey: "num_validate",
Type: int(domain.CustomFieldTypeNumber),
MinVal: 0,
MaxVal: 100,
}
svc.CreateField(ctx, req)
// Valid number
err := svc.SetUserFieldValue(ctx, 1, "num_validate", "50")
if err != nil {
t.Fatalf("SetUserFieldValue failed: %v", err)
}
// Invalid number
err = svc.SetUserFieldValue(ctx, 1, "num_validate", "not_a_number")
if err == nil {
t.Error("Expected error for invalid number")
}
// Number too large
err = svc.SetUserFieldValue(ctx, 1, "num_validate", "200")
if err == nil {
t.Error("Expected error for number too large")
}
})
t.Run("Validate boolean field", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "布尔验证",
FieldKey: "bool_validate",
Type: int(domain.CustomFieldTypeBoolean),
}
svc.CreateField(ctx, req)
// Valid boolean
err := svc.SetUserFieldValue(ctx, 1, "bool_validate", "true")
if err != nil {
t.Fatalf("SetUserFieldValue failed: %v", err)
}
// Invalid boolean
err = svc.SetUserFieldValue(ctx, 1, "bool_validate", "yes")
if err == nil {
t.Error("Expected error for invalid boolean")
}
})
t.Run("Validate date field", func(t *testing.T) {
req := &service.CreateFieldRequest{
Name: "日期验证",
FieldKey: "date_validate",
Type: int(domain.CustomFieldTypeDate),
}
svc.CreateField(ctx, req)
// Valid date
err := svc.SetUserFieldValue(ctx, 1, "date_validate", "2024-01-15")
if err != nil {
t.Fatalf("SetUserFieldValue failed: %v", err)
}
// Invalid date
err = svc.SetUserFieldValue(ctx, 1, "date_validate", "not_a_date")
if err == nil {
t.Error("Expected error for invalid date")
}
})
}
func TestCustomFieldService_DeleteUserFieldValue(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
// Create test field
req := &service.CreateFieldRequest{
Name: "删除值字段",
FieldKey: "delete_value_field",
Type: int(domain.CustomFieldTypeString),
}
svc.CreateField(ctx, req)
// Set value
svc.SetUserFieldValue(ctx, 1, "delete_value_field", "test")
t.Run("Delete user field value", func(t *testing.T) {
err := svc.DeleteUserFieldValue(ctx, 1, "delete_value_field")
if err != nil {
t.Fatalf("DeleteUserFieldValue failed: %v", err)
}
})
t.Run("Delete non-existent field value", func(t *testing.T) {
err := svc.DeleteUserFieldValue(ctx, 1, "non_existent")
if err == nil {
t.Error("Expected error for non-existent field")
}
})
}
func TestCustomFieldService_BatchSetUserFieldValues(t *testing.T) {
svc, _ := setupCustomFieldTestEnv(t)
ctx := context.Background()
// Create test fields
svc.CreateField(ctx, &service.CreateFieldRequest{
Name: "批量字段1",
FieldKey: "batch_field1",
Type: int(domain.CustomFieldTypeString),
})
svc.CreateField(ctx, &service.CreateFieldRequest{
Name: "批量字段2",
FieldKey: "batch_field2",
Type: int(domain.CustomFieldTypeString),
})
t.Run("Batch set user field values success", func(t *testing.T) {
values := map[string]string{
"batch_field1": "value1",
"batch_field2": "value2",
}
err := svc.BatchSetUserFieldValues(ctx, 1, values)
if err != nil {
t.Fatalf("BatchSetUserFieldValues failed: %v", err)
}
// Verify values were set
userValues, err := svc.GetUserFieldValues(ctx, 1)
if err != nil {
t.Fatalf("GetUserFieldValues failed: %v", err)
}
if len(userValues) < 2 {
t.Errorf("Expected at least 2 field values, got %d", len(userValues))
}
})
t.Run("Batch set with non-existent field", func(t *testing.T) {
values := map[string]string{
"non_existent_field": "value",
}
err := svc.BatchSetUserFieldValues(ctx, 1, values)
if err == nil {
t.Error("Expected error for non-existent field")
}
})
t.Run("Batch set with empty map", func(t *testing.T) {
values := map[string]string{}
err := svc.BatchSetUserFieldValues(ctx, 1, values)
if err != nil {
t.Fatalf("BatchSetUserFieldValues with empty map should succeed: %v", err)
}
})
t.Run("Batch set with invalid value", func(t *testing.T) {
// Create a number field with validation
svc.CreateField(ctx, &service.CreateFieldRequest{
Name: "批量数字字段",
FieldKey: "batch_number",
Type: int(domain.CustomFieldTypeNumber),
MinVal: 0,
MaxVal: 100,
})
values := map[string]string{
"batch_number": "200", // exceeds max
}
err := svc.BatchSetUserFieldValues(ctx, 1, values)
if err == nil {
t.Error("Expected error for invalid value")
}
})
}