Files
gochat/internal/service/webhook_subscription_service_test.go_BAK
T
2026-06-04 15:44:48 +08:00

223 lines
7.7 KiB
Plaintext

package service
import (
"context"
"encoding/json"
"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"
)
// setupWebhookSubscriptionService 创建 WebhookSubscriptionRepo + WebhookSubscriptionService 测试实例。
func setupWebhookSubscriptionService(t *testing.T) (*gorm.DB, *repository.WebhookSubscriptionRepo, *WebhookSubscriptionService) {
t.Helper()
db := setupServiceTestDB(t)
repo := repository.NewWebhookSubscriptionRepo(db)
svc := NewWebhookSubscriptionService(repo)
return db, repo, svc
}
// createTestWebhookSubscription 在数据库中创建一个测试 WebhookSubscription 并返回。
func createTestWebhookSubscription(t *testing.T, db *gorm.DB, accountID uint, url string, events []string) *model.WebhookSubscription {
t.Helper()
eventsJSON, err := json.Marshal(events)
if err != nil {
t.Fatalf("无法序列化事件列表: %v", err)
}
sub := &model.WebhookSubscription{
AccountID: accountID,
URL: url,
Events: eventsJSON,
Secret: "test-secret-key",
Active: true,
}
if err := db.Create(sub).Error; err != nil {
t.Fatalf("无法创建测试 Webhook 订阅: %v", err)
}
return sub
}
// ========== ListSubscriptions ==========
func TestWebhookSubscriptionService_ListSubscriptions_成功(t *testing.T) {
db, _, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
// 创建多个订阅
createTestWebhookSubscription(t, db, account.ID, "https://example.com/hook1", []string{"message_created"})
createTestWebhookSubscription(t, db, account.ID, "https://example.com/hook2", []string{"conversation_created"})
subs, err := svc.ListSubscriptions(context.Background(), account.ID)
require.NoError(t, err)
assert.Len(t, subs, 2)
}
func TestWebhookSubscriptionService_ListSubscriptions_无订阅(t *testing.T) {
db, _, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
subs, err := svc.ListSubscriptions(context.Background(), account.ID)
require.NoError(t, err)
assert.Len(t, subs, 0)
}
// ========== CreateSubscription ==========
func TestWebhookSubscriptionService_CreateSubscription_成功(t *testing.T) {
db, _, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
events := []string{"message_created", "conversation_created"}
sub, err := svc.CreateSubscription(context.Background(), account.ID, "https://example.com/webhook", events)
require.NoError(t, err)
assert.Equal(t, account.ID, sub.AccountID)
assert.Equal(t, "https://example.com/webhook", sub.URL)
assert.True(t, sub.Active)
assert.NotZero(t, sub.ID)
// 验证 secret 已自动生成
assert.NotEmpty(t, sub.Secret)
assert.Len(t, sub.Secret, 64) // 32 bytes hex-encoded = 64 chars
// 验证 Events 是有效的 JSON
var parsedEvents []string
err = json.Unmarshal(sub.Events, &parsedEvents)
require.NoError(t, err)
assert.Equal(t, events, parsedEvents)
}
// ========== UpdateSubscription ==========
func TestWebhookSubscriptionService_UpdateSubscription_成功(t *testing.T) {
db, _, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
sub := createTestWebhookSubscription(t, db, account.ID, "https://old.example.com/hook", []string{"message_created"})
newURL := "https://new.example.com/hook"
newEvents := []string{"conversation_created", "message_updated"}
updated, err := svc.UpdateSubscription(context.Background(), sub.ID, newURL, newEvents, true)
require.NoError(t, err)
assert.Equal(t, newURL, updated.URL)
// 验证 Events 已更新
var parsedEvents []string
err = json.Unmarshal(updated.Events, &parsedEvents)
require.NoError(t, err)
assert.Equal(t, newEvents, parsedEvents)
assert.True(t, updated.Active)
}
func TestWebhookSubscriptionService_UpdateSubscription_仅URL(t *testing.T) {
db, _, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
sub := createTestWebhookSubscription(t, db, account.ID, "https://old.example.com/hook", []string{"message_created"})
updated, err := svc.UpdateSubscription(context.Background(), sub.ID, "https://updated.example.com/hook", nil, true)
require.NoError(t, err)
assert.Equal(t, "https://updated.example.com/hook", updated.URL)
// Events 应保持不变
var parsedEvents []string
err = json.Unmarshal(updated.Events, &parsedEvents)
require.NoError(t, err)
assert.Equal(t, []string{"message_created"}, parsedEvents)
}
func TestWebhookSubscriptionService_UpdateSubscription_不存在(t *testing.T) {
_, _, svc := setupWebhookSubscriptionService(t)
updated, err := svc.UpdateSubscription(context.Background(), 9999, "https://example.com/hook", []string{"event"}, true)
assert.Error(t, err)
assert.Nil(t, updated)
}
// ========== DeleteSubscription ==========
func TestWebhookSubscriptionService_DeleteSubscription_成功(t *testing.T) {
db, _, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
sub := createTestWebhookSubscription(t, db, account.ID, "https://example.com/hook", []string{"message_created"})
err := svc.DeleteSubscription(context.Background(), sub.ID)
require.NoError(t, err)
// 验证订阅已被删除
var count int64
db.Model(&model.WebhookSubscription{}).Where("id = ?", sub.ID).Count(&count)
assert.Equal(t, int64(0), count)
}
func TestWebhookSubscriptionService_DeleteSubscription_不存在(t *testing.T) {
_, _, svc := setupWebhookSubscriptionService(t)
err := svc.DeleteSubscription(context.Background(), 9999)
assert.Error(t, err)
}
// ========== GetSubscription ==========
func TestWebhookSubscriptionService_GetSubscription_成功(t *testing.T) {
db, _, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
sub := createTestWebhookSubscription(t, db, account.ID, "https://example.com/hook", []string{"message_created"})
result, err := svc.GetSubscription(context.Background(), sub.ID)
require.NoError(t, err)
assert.Equal(t, sub.ID, result.ID)
assert.Equal(t, sub.URL, result.URL)
assert.Equal(t, account.ID, result.AccountID)
}
func TestWebhookSubscriptionService_GetSubscription_不存在(t *testing.T) {
_, _, svc := setupWebhookSubscriptionService(t)
result, err := svc.GetSubscription(context.Background(), 9999)
assert.Error(t, err)
assert.Nil(t, result)
}
// ========== ListDeliveries ==========
func TestWebhookSubscriptionService_ListDeliveries_成功(t *testing.T) {
db, repo, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
sub := createTestWebhookSubscription(t, db, account.ID, "https://example.com/hook", []string{"message_created"})
// 直接通过 repo 创建投递记录
ctx := context.Background()
delivery1 := &model.WebhookDelivery{
SubscriptionID: sub.ID,
EventType: "message_created",
Payload: json.RawMessage(`{"id":1}`),
Status: "success",
Attempts: 1,
}
require.NoError(t, repo.CreateDelivery(ctx, delivery1))
delivery2 := &model.WebhookDelivery{
SubscriptionID: sub.ID,
EventType: "conversation_created",
Payload: json.RawMessage(`{"id":2}`),
Status: "pending",
Attempts: 0,
}
require.NoError(t, repo.CreateDelivery(ctx, delivery2))
deliveries, err := svc.ListDeliveries(context.Background(), sub.ID, 10)
require.NoError(t, err)
assert.Len(t, deliveries, 2)
}
func TestWebhookSubscriptionService_ListDeliveries_无投递记录(t *testing.T) {
db, _, svc := setupWebhookSubscriptionService(t)
account := createTestAccount(t, db)
sub := createTestWebhookSubscription(t, db, account.ID, "https://example.com/hook", []string{"message_created"})
deliveries, err := svc.ListDeliveries(context.Background(), sub.ID, 10)
require.NoError(t, err)
assert.Len(t, deliveries, 0)
}