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

345 lines
9.3 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"
)
// =============================================================================
// 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)
}
})
}