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") } }) }