223 lines
7.7 KiB
Plaintext
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)
|
|
} |