package service import ( "context" "testing" "github.com/gochat/gochat/internal/model" "github.com/gochat/gochat/internal/repository" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/gorm" ) // setupPushSubscriptionService 创建 PushTokenRepo + PushSubscriptionService 测试实例。 func setupPushSubscriptionService(t *testing.T) (*gorm.DB, *repository.PushTokenRepo, *PushSubscriptionService) { t.Helper() db := setupServiceTestDB(t) repo := repository.NewPushTokenRepo(db) svc := NewPushSubscriptionService(repo) return db, repo, svc } // createTestPushToken 在数据库中创建一个测试 PushToken 并返回。 func createTestPushToken(t *testing.T, db *gorm.DB, userID uint, token string, platform string) *model.PushToken { t.Helper() pt := &model.PushToken{ UserID: userID, Token: token, Platform: platform, DeviceID: "test-device-id", } if err := db.Create(pt).Error; err != nil { t.Fatalf("无法创建测试推送令牌: %v", err) } return pt } // ========== ListPushTokens ========== func TestPushSubscriptionService_ListPushTokens_成功(t *testing.T) { db, _, svc := setupPushSubscriptionService(t) account := createTestAccount(t, db) user := createTestUser(t, db, account.ID) // 创建多个推送令牌 createTestPushToken(t, db, user.ID, "token-abc-123", "ios") createTestPushToken(t, db, user.ID, "token-def-456", "android") tokens, err := svc.ListPushTokens(context.Background(), user.ID) require.NoError(t, err) assert.Len(t, tokens, 2) assert.Equal(t, "token-abc-123", tokens[0].Token) assert.Equal(t, "token-def-456", tokens[1].Token) } func TestPushSubscriptionService_ListPushTokens_无令牌(t *testing.T) { db, _, svc := setupPushSubscriptionService(t) account := createTestAccount(t, db) user := createTestUser(t, db, account.ID) tokens, err := svc.ListPushTokens(context.Background(), user.ID) require.NoError(t, err) assert.Len(t, tokens, 0) } // ========== RegisterPushToken ========== func TestPushSubscriptionService_RegisterPushToken_成功(t *testing.T) { db, _, svc := setupPushSubscriptionService(t) account := createTestAccount(t, db) user := createTestUser(t, db, account.ID) pt, err := svc.RegisterPushToken(context.Background(), user.ID, "new-token-xyz", "web", "device-001") require.NoError(t, err) assert.Equal(t, user.ID, pt.UserID) assert.Equal(t, "new-token-xyz", pt.Token) assert.Equal(t, "web", pt.Platform) assert.Equal(t, "device-001", pt.DeviceID) assert.NotZero(t, pt.ID) } // ========== RemovePushToken ========== func TestPushSubscriptionService_RemovePushToken_成功(t *testing.T) { db, _, svc := setupPushSubscriptionService(t) account := createTestAccount(t, db) user := createTestUser(t, db, account.ID) pt := createTestPushToken(t, db, user.ID, "token-to-remove", "ios") err := svc.RemovePushToken(context.Background(), pt.ID) require.NoError(t, err) // 验证令牌已被删除 var count int64 db.Model(&model.PushToken{}).Where("id = ?", pt.ID).Count(&count) assert.Equal(t, int64(0), count) } func TestPushSubscriptionService_RemovePushToken_不存在(t *testing.T) { _, _, svc := setupPushSubscriptionService(t) err := svc.RemovePushToken(context.Background(), 9999) assert.Error(t, err) } // ========== RemovePushTokenByValue ========== func TestPushSubscriptionService_RemovePushTokenByValue_成功(t *testing.T) { db, _, svc := setupPushSubscriptionService(t) account := createTestAccount(t, db) user := createTestUser(t, db, account.ID) pt := createTestPushToken(t, db, user.ID, "token-by-value-remove", "android") err := svc.RemovePushTokenByValue(context.Background(), pt.Token, user.ID) require.NoError(t, err) // 验证令牌已被删除 var count int64 db.Model(&model.PushToken{}).Where("id = ?", pt.ID).Count(&count) assert.Equal(t, int64(0), count) } func TestPushSubscriptionService_RemovePushTokenByValue_不存在(t *testing.T) { _, _, svc := setupPushSubscriptionService(t) err := svc.RemovePushTokenByValue(context.Background(), "nonexistent-token", 9999) // DeleteByTokenAndUser with no matching record should not error (GORM delete 0 rows is not an error) assert.NoError(t, err) }