package services import ( "fmt" "os" "strings" "testing" "time" "github.com/stretchr/testify/assert" "golang.org/x/crypto/bcrypt" "git.beifan.cn/trace-system/backend-go/config" "git.beifan.cn/trace-system/backend-go/database" "git.beifan.cn/trace-system/backend-go/logger" "git.beifan.cn/trace-system/backend-go/models" ) func TestMain(m *testing.M) { config.LoadConfig() if err := logger.InitializeLogger("test"); err != nil { fmt.Printf("日志系统初始化失败: %v\n", err) os.Exit(1) } defer logger.Sync() database.InitDB() database.AutoMigrate() database.DB.Unscoped().Where("1 = 1").Delete(&models.User{}) database.DB.Unscoped().Where("1 = 1").Delete(&models.Company{}) database.DB.Unscoped().Where("1 = 1").Delete(&models.Serial{}) exitCode := m.Run() database.DB.Unscoped().Where("1 = 1").Delete(&models.User{}) database.DB.Unscoped().Where("1 = 1").Delete(&models.Company{}) database.DB.Unscoped().Where("1 = 1").Delete(&models.Serial{}) os.Exit(exitCode) } func TestAuthService_ValidateUser_Success(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "testuser", Password: string(password), Name: "测试用户", Email: "test@example.com", Role: "user", } database.DB.Create(&user) authService := AuthService{} result, err := authService.ValidateUser("testuser", "password123") assert.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, "testuser", result.Username) database.DB.Unscoped().Delete(&user) } func TestAuthService_ValidateUser_WrongPassword(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "testuser2", Password: string(password), Name: "测试用户2", Email: "test2@example.com", Role: "user", } database.DB.Create(&user) authService := AuthService{} _, err := authService.ValidateUser("testuser2", "wrongpassword") assert.Error(t, err) database.DB.Unscoped().Delete(&user) } func TestAuthService_ValidateUser_UserNotFound(t *testing.T) { authService := AuthService{} _, err := authService.ValidateUser("nonexistent", "password") assert.Error(t, err) } func TestAuthService_GenerateToken_Success(t *testing.T) { user := &models.User{ ID: 1, Username: "testuser", Role: "user", } authService := AuthService{} token, err := authService.GenerateToken(user) assert.NoError(t, err) assert.NotEmpty(t, token) assert.NotEmpty(t, "Bearer "+token) } func TestAuthService_GetProfile_Success(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "testuser3", Password: string(password), Name: "测试用户3", Email: "test3@example.com", Role: "user", } database.DB.Create(&user) authService := AuthService{} profile, err := authService.GetProfile(user.ID) assert.NoError(t, err) assert.NotNil(t, profile) assert.Equal(t, "testuser3", profile.Username) assert.Equal(t, "测试用户3", profile.Name) database.DB.Unscoped().Delete(&user) } func TestAuthService_ChangePassword_Success(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("oldpassword"), bcrypt.DefaultCost) user = models.User{ Username: "testuser4", Password: string(password), Name: "测试用户4", Email: "test4@example.com", Role: "user", } database.DB.Create(&user) authService := AuthService{} err := authService.ChangePassword(user.ID, "oldpassword", "newpassword") assert.NoError(t, err) var updatedUser models.User database.DB.First(&updatedUser, user.ID) err = bcrypt.CompareHashAndPassword([]byte(updatedUser.Password), []byte("newpassword")) assert.NoError(t, err) database.DB.Unscoped().Delete(&user) } func TestAuthService_ChangePassword_WrongCurrentPassword(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("oldpassword"), bcrypt.DefaultCost) user = models.User{ Username: "testuser5", Password: string(password), Name: "测试用户5", Email: "test5@example.com", Role: "user", } database.DB.Create(&user) authService := AuthService{} err := authService.ChangePassword(user.ID, "wrongpassword", "newpassword") assert.Error(t, err) database.DB.Unscoped().Delete(&user) } func TestAuthService_UpdateProfile_Success(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "testuser6", Password: string(password), Name: "测试用户6", Email: "test6@example.com", Role: "user", } database.DB.Create(&user) authService := AuthService{} profile, err := authService.UpdateProfile(user.ID, "新名称", "newemail@example.com") assert.NoError(t, err) assert.NotNil(t, profile) assert.Equal(t, "新名称", profile.Name) assert.Equal(t, "newemail@example.com", profile.Email) database.DB.Unscoped().Delete(&user) } func TestSerialsService_Generate_Success(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "adminuser", Password: string(password), Name: "管理员", Email: "admin@example.com", Role: "admin", } database.DB.Create(&user) serialService := SerialsService{} serials, err := serialService.Generate("TestCompany", 5, 30, user.ID) assert.NoError(t, err) assert.Len(t, serials, 5) assert.Equal(t, "TestCompany", serials[0].CompanyName) assert.True(t, serials[0].IsActive) for _, serial := range serials { database.DB.Unscoped().Delete(&serial) } database.DB.Unscoped().Where("company_name = ?", "TestCompany").Delete(&models.Company{}) database.DB.Unscoped().Delete(&user) } func TestSerialsService_Generate_WithPrefix(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "adminuser2", Password: string(password), Name: "管理员2", Email: "admin2@example.com", Role: "admin", } database.DB.Create(&user) serialService := SerialsService{} serials, err := serialService.Generate("TestCompany2", 3, 30, user.ID, "TEST") assert.NoError(t, err) assert.Len(t, serials, 3) assert.True(t, len(serials[0].SerialNumber) > 0) assert.Contains(t, serials[0].SerialNumber, "TEST") for _, serial := range serials { database.DB.Unscoped().Delete(&serial) } database.DB.Unscoped().Where("company_name = ?", "TestCompany2").Delete(&models.Company{}) database.DB.Unscoped().Delete(&user) } func TestSerialsService_Query_QuerySuccess(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "adminuser3", Password: string(password), Name: "管理员3", Email: "admin3@example.com", Role: "admin", } database.DB.Create(&user) serialService := SerialsService{} serials, _ := serialService.Generate("TestCompany3", 1, 30, user.ID, "QR") serialNumber := strings.ToUpper(serials[0].SerialNumber) result, err := serialService.Query(serialNumber) assert.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, serialNumber, strings.ToUpper(result.SerialNumber)) assert.True(t, result.IsActive) for _, serial := range serials { database.DB.Unscoped().Delete(&serial) } database.DB.Unscoped().Where("company_name = ?", "TestCompany3").Delete(&models.Company{}) database.DB.Unscoped().Delete(&user) } func TestSerialsService_Query_SerialNotFound(t *testing.T) { serialService := SerialsService{} _, err := serialService.Query("NONEXISTENT") assert.Error(t, err) } func TestSerialsService_FindAll_Success(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "adminuser4", Password: string(password), Name: "管理员4", Email: "admin4@example.com", Role: "admin", } database.DB.Create(&user) serialService := SerialsService{} serials, _ := serialService.Generate("TestCompany4", 10, 30, user.ID, "LIST") result, total, totalPages, err := serialService.FindAll(1, 5, "") assert.NoError(t, err) assert.Len(t, result, 5) assert.GreaterOrEqual(t, total, 10) assert.Greater(t, totalPages, 0) for _, serial := range serials { database.DB.Unscoped().Delete(&serial) } database.DB.Unscoped().Where("company_name = ?", "TestCompany4").Delete(&models.Company{}) database.DB.Unscoped().Delete(&user) } func TestSerialsService_FindAll_WithSearch(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "adminuser5", Password: string(password), Name: "管理员5", Email: "admin5@example.com", Role: "admin", } database.DB.Create(&user) serialService := SerialsService{} serials, _ := serialService.Generate("SearchCompany", 5, 30, user.ID, "SEARCH") result, _, _, err := serialService.FindAll(1, 10, "SearchCompany") assert.NoError(t, err) assert.Greater(t, len(result), 0) assert.Equal(t, "SearchCompany", result[0].CompanyName) for _, serial := range serials { database.DB.Unscoped().Delete(&serial) } database.DB.Unscoped().Where("company_name = ?", "SearchCompany").Delete(&models.Company{}) database.DB.Unscoped().Delete(&user) } func TestSerialsService_Revoke_Success(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "adminuser6", Password: string(password), Name: "管理员6", Email: "admin6@example.com", Role: "admin", } database.DB.Create(&user) serialService := SerialsService{} serials, _ := serialService.Generate("RevokeCompany", 1, 30, user.ID, "REVOKE") serialNumber := serials[0].SerialNumber err := serialService.Revoke(serialNumber) assert.NoError(t, err) var revokedSerial models.Serial database.DB.Where("serial_number = ?", serialNumber).First(&revokedSerial) assert.False(t, revokedSerial.IsActive) for _, serial := range serials { database.DB.Unscoped().Delete(&serial) } database.DB.Unscoped().Where("company_name = ?", "RevokeCompany").Delete(&models.Company{}) database.DB.Unscoped().Delete(&user) } func TestSerialsService_Update_Success(t *testing.T) { var user models.User password, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) user = models.User{ Username: "adminuser7", Password: string(password), Name: "管理员7", Email: "admin7@example.com", Role: "admin", } database.DB.Create(&user) serialService := SerialsService{} serials, _ := serialService.Generate("UpdateCompany", 1, 30, user.ID, "UPDATE") serialNumber := serials[0].SerialNumber newValidUntil := time.Now().AddDate(0, 0, 60) isActive := false updateData := models.UpdateSerialDTO{ ValidUntil: &newValidUntil, IsActive: &isActive, } result, err := serialService.Update(serialNumber, updateData) assert.NoError(t, err) assert.NotNil(t, result) assert.False(t, result.IsActive) for _, serial := range serials { database.DB.Unscoped().Delete(&serial) } database.DB.Unscoped().Where("company_name = ?", "UpdateCompany").Delete(&models.Company{}) database.DB.Unscoped().Delete(&user) }