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" ) // ============================================================================= // Export Service Tests // ============================================================================= func setupExportTestEnv(t *testing.T) (*service.ExportService, *gorm.DB) { t.Helper() db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{ DriverName: "sqlite", DSN: "file:export_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.User{}); err != nil { t.Fatalf("failed to migrate: %v", err) } userRepo := repository.NewUserRepository(db) svc := service.NewExportService(userRepo, nil) return svc, db } func TestExportService_ExportUsers(t *testing.T) { svc, db := setupExportTestEnv(t) ctx := context.Background() // Create test users for i := 0; i < 3; i++ { user := &domain.User{ Username: "export_user_" + string(rune('a'+i)), Password: "$2a$10$hash", Status: domain.UserStatusActive, } db.Create(user) } t.Run("Export users as CSV", func(t *testing.T) { req := &service.ExportUsersRequest{ Format: "csv", } data, filename, contentType, err := svc.ExportUsers(ctx, req) if err != nil { t.Fatalf("ExportUsers failed: %v", err) } if len(data) == 0 { t.Error("Expected export data") } if filename == "" { t.Error("Expected filename") } if contentType == "" { t.Error("Expected content type") } }) t.Run("Export users as XLSX", func(t *testing.T) { req := &service.ExportUsersRequest{ Format: "xlsx", } data, _, _, err := svc.ExportUsers(ctx, req) if err != nil { t.Fatalf("ExportUsers failed: %v", err) } if len(data) == 0 { t.Error("Expected export data") } }) t.Run("Export users with invalid format", func(t *testing.T) { req := &service.ExportUsersRequest{ Format: "invalid", } _, _, _, err := svc.ExportUsers(ctx, req) if err == nil { t.Error("Expected error for invalid format") } }) t.Run("Export users with nil request", func(t *testing.T) { data, _, _, err := svc.ExportUsers(ctx, nil) if err != nil { t.Fatalf("ExportUsers with nil request failed: %v", err) } if len(data) == 0 { t.Error("Expected export data") } }) } func TestExportService_ExportUsersCSV(t *testing.T) { svc, db := setupExportTestEnv(t) ctx := context.Background() // Create test user user := &domain.User{ Username: "csv_user", Password: "$2a$10$hash", Status: domain.UserStatusActive, } db.Create(user) t.Run("Export users CSV", func(t *testing.T) { data, filename, err := svc.ExportUsersCSV(ctx) if err != nil { t.Fatalf("ExportUsersCSV failed: %v", err) } if len(data) == 0 { t.Error("Expected CSV data") } if filename == "" { t.Error("Expected filename") } }) } func TestExportService_ExportUsersXLSX(t *testing.T) { svc, db := setupExportTestEnv(t) ctx := context.Background() // Create test user user := &domain.User{ Username: "xlsx_user", Password: "$2a$10$hash", Status: domain.UserStatusActive, } db.Create(user) t.Run("Export users XLSX", func(t *testing.T) { data, filename, err := svc.ExportUsersXLSX(ctx) if err != nil { t.Fatalf("ExportUsersXLSX failed: %v", err) } if len(data) == 0 { t.Error("Expected XLSX data") } if filename == "" { t.Error("Expected filename") } }) } func TestExportService_GetImportTemplate(t *testing.T) { svc, _ := setupExportTestEnv(t) t.Run("Get import template default", func(t *testing.T) { data, filename := svc.GetImportTemplate() if len(data) == 0 { t.Error("Expected template data") } if filename == "" { t.Error("Expected filename") } }) t.Run("Get import template CSV", func(t *testing.T) { data, filename, contentType, err := svc.GetImportTemplateByFormat("csv") if err != nil { t.Fatalf("GetImportTemplateByFormat failed: %v", err) } if len(data) == 0 { t.Error("Expected template data") } if filename == "" { t.Error("Expected filename") } if contentType == "" { t.Error("Expected content type") } }) t.Run("Get import template XLSX", func(t *testing.T) { data, _, _, err := svc.GetImportTemplateByFormat("xlsx") if err != nil { t.Fatalf("GetImportTemplateByFormat failed: %v", err) } if len(data) == 0 { t.Error("Expected template data") } }) t.Run("Get import template invalid format", func(t *testing.T) { _, _, _, err := svc.GetImportTemplateByFormat("invalid") if err == nil { t.Error("Expected error for invalid format") } }) } // ============================================================================= // Export Users CSV Extended Tests // ============================================================================= func TestExportService_ExportUsersCSV_Extended(t *testing.T) { svc, db := setupExportTestEnv(t) ctx := context.Background() // Create multiple test users with various fields email := "export@test.com" phone := "13800138000" users := []*domain.User{ {Username: "csv_user1", Password: "$2a$10$hash", Status: domain.UserStatusActive, Email: &email, Phone: &phone, Nickname: "User One"}, {Username: "csv_user2", Password: "$2a$10$hash", Status: domain.UserStatusInactive}, {Username: "csv_user3", Password: "$2a$10$hash", Status: domain.UserStatusLocked}, } for _, u := range users { db.Create(u) } t.Run("Export users CSV with data", func(t *testing.T) { data, filename, err := svc.ExportUsersCSV(ctx) if err != nil { t.Fatalf("ExportUsersCSV failed: %v", err) } if len(data) == 0 { t.Error("Expected CSV data") } if filename == "" { t.Error("Expected filename") } }) } // ============================================================================= // Import Users Tests // ============================================================================= func TestExportService_ImportUsersCSV(t *testing.T) { svc, _ := setupExportTestEnv(t) ctx := context.Background() t.Run("Import CSV with empty data", func(t *testing.T) { successCount, failCount, errs := svc.ImportUsersCSV(ctx, []byte("")) _ = failCount _ = errs // Empty data should result in 0 successful imports if successCount != 0 { t.Errorf("Expected 0 success, got %d", successCount) } }) } // ============================================================================= // Import Users Extended Tests // ============================================================================= func TestExportService_ImportUsers(t *testing.T) { svc, db := setupExportTestEnv(t) ctx := context.Background() t.Run("Import users with invalid format", func(t *testing.T) { successCount, _, _ := svc.ImportUsers(ctx, []byte("test"), "invalid_format") if successCount != 0 { t.Errorf("Expected 0 success for invalid format, got %d", successCount) } }) t.Run("Import valid CSV data", func(t *testing.T) { csvData := "用户名,密码,邮箱,手机号,昵称\nnewuser1,Password123!,new1@test.com,13800138001,User One\nnewuser2,Password123!,new2@test.com,13800138002,User Two" successCount, failCount, errs := svc.ImportUsersCSV(ctx, []byte(csvData)) if successCount != 2 { t.Errorf("Expected 2 successful imports, got %d, errors: %v", successCount, errs) } _ = failCount }) t.Run("Import CSV with missing username", func(t *testing.T) { csvData := "用户名,密码\n,Password123!" successCount, failCount, errs := svc.ImportUsersCSV(ctx, []byte(csvData)) if successCount != 0 { t.Errorf("Expected 0 success, got %d", successCount) } if failCount == 0 { t.Error("Expected at least one failure") } if len(errs) == 0 { t.Error("Expected error message") } }) t.Run("Import CSV with missing password", func(t *testing.T) { csvData := "用户名,密码\nnopwduser," successCount, failCount, errs := svc.ImportUsersCSV(ctx, []byte(csvData)) if successCount != 0 { t.Errorf("Expected 0 success, got %d", successCount) } if failCount == 0 { t.Error("Expected at least one failure") } _ = errs }) t.Run("Import CSV with duplicate username", func(t *testing.T) { // Create existing user db.Create(&domain.User{Username: "duplicateuser", Password: "$2a$10$hash", Status: domain.UserStatusActive}) csvData := "用户名,密码\nduplicateuser,Password123!" successCount, failCount, _ := svc.ImportUsersCSV(ctx, []byte(csvData)) if successCount != 0 { t.Errorf("Expected 0 success for duplicate, got %d", successCount) } if failCount == 0 { t.Error("Expected failure for duplicate username") } }) t.Run("Import CSV with only headers", func(t *testing.T) { csvData := "用户名,密码,邮箱" successCount, _, _ := svc.ImportUsersCSV(ctx, []byte(csvData)) if successCount != 0 { t.Errorf("Expected 0 success for header-only CSV, got %d", successCount) } }) } func TestExportService_ImportUsersXLSX(t *testing.T) { svc, _ := setupExportTestEnv(t) ctx := context.Background() t.Run("Import XLSX with invalid data", func(t *testing.T) { successCount, _, _ := svc.ImportUsersXLSX(ctx, []byte("not a valid xlsx")) if successCount != 0 { t.Errorf("Expected 0 success for invalid XLSX, got %d", successCount) } }) }