339 lines
11 KiB
Plaintext
339 lines
11 KiB
Plaintext
package repository
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
)
|
|
|
|
func TestWebhookSubscriptionRepo_FindByID(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
sub := &model.WebhookSubscription{
|
|
AccountID: 1,
|
|
URL: "https://example.com/hook",
|
|
Events: json.RawMessage(`["conversation_created"]`),
|
|
Secret: "secret123",
|
|
Active: true,
|
|
}
|
|
require.NoError(t, db.Create(sub).Error)
|
|
|
|
found, err := repo.FindByID(context.Background(), sub.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, sub.URL, found.URL)
|
|
assert.Equal(t, sub.AccountID, found.AccountID)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_FindByID_NotFound(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
found, err := repo.FindByID(context.Background(), 9999)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, found)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_GetByID(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
sub := &model.WebhookSubscription{
|
|
AccountID: 1,
|
|
URL: "https://example.com/hook2",
|
|
Events: json.RawMessage(`["message_created"]`),
|
|
Secret: "secret456",
|
|
Active: true,
|
|
}
|
|
require.NoError(t, db.Create(sub).Error)
|
|
|
|
found, err := repo.GetByID(context.Background(), sub.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, sub.ID, found.ID)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_ListByAccount(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
// Create an account to satisfy FK
|
|
acct := &model.Account{Name: "WHListOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
activeSub := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/active",
|
|
Events: json.RawMessage(`["conversation_created"]`),
|
|
Secret: "s1",
|
|
Active: true,
|
|
}
|
|
inactiveSub := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/inactive",
|
|
Events: json.RawMessage(`["message_created"]`),
|
|
Secret: "s2",
|
|
Active: false,
|
|
}
|
|
require.NoError(t, db.Create(activeSub).Error)
|
|
require.NoError(t, db.Create(inactiveSub).Error)
|
|
|
|
// ListByAccount returns only active subscriptions
|
|
subs, err := repo.ListByAccount(context.Background(), acct.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, subs, 1)
|
|
assert.Equal(t, activeSub.ID, subs[0].ID)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_ListActiveByAccount(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
acct := &model.Account{Name: "WHActiveOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
sub1 := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/a1",
|
|
Events: json.RawMessage(`["conversation_created"]`),
|
|
Secret: "s1",
|
|
Active: true,
|
|
}
|
|
sub2 := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/a2",
|
|
Events: json.RawMessage(`["message_updated"]`),
|
|
Secret: "s2",
|
|
Active: true,
|
|
}
|
|
inactive := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/a3",
|
|
Events: json.RawMessage(`["message_created"]`),
|
|
Secret: "s3",
|
|
Active: false,
|
|
}
|
|
require.NoError(t, db.Create(sub1).Error)
|
|
require.NoError(t, db.Create(sub2).Error)
|
|
require.NoError(t, db.Create(inactive).Error)
|
|
|
|
subs, err := repo.ListActiveByAccount(context.Background(), acct.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, subs, 2)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_ListByAccountAndEvent(t *testing.T) {
|
|
skipIfSQLite(t) // uses PG jsonb @> operator
|
|
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
acct := &model.Account{Name: "WHEvOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
subWithEvent := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/ev1",
|
|
Events: json.RawMessage(`["conversation_created","message_created"]`),
|
|
Secret: "s1",
|
|
Active: true,
|
|
}
|
|
subWithoutEvent := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/ev2",
|
|
Events: json.RawMessage(`["message_updated"]`),
|
|
Secret: "s2",
|
|
Active: true,
|
|
}
|
|
require.NoError(t, db.Create(subWithEvent).Error)
|
|
require.NoError(t, db.Create(subWithoutEvent).Error)
|
|
|
|
// Filter by event "conversation_created"
|
|
subs, err := repo.ListByAccountAndEvent(context.Background(), acct.ID, `["conversation_created"]`)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, subs, 1)
|
|
assert.Equal(t, subWithEvent.ID, subs[0].ID)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_Create(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
acct := &model.Account{Name: "WHCreateOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
sub := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/new",
|
|
Events: json.RawMessage(`["conversation_created"]`),
|
|
Secret: "newsecret",
|
|
Active: true,
|
|
}
|
|
err := repo.Create(context.Background(), sub)
|
|
assert.NoError(t, err)
|
|
assert.NotZero(t, sub.ID)
|
|
|
|
// Verify persisted
|
|
found, err := repo.FindByID(context.Background(), sub.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "https://example.com/new", found.URL)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_Update(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
acct := &model.Account{Name: "WHUpdateOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
sub := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/old",
|
|
Events: json.RawMessage(`["conversation_created"]`),
|
|
Secret: "oldsecret",
|
|
Active: true,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), sub))
|
|
|
|
sub.URL = "https://example.com/updated"
|
|
sub.Active = false
|
|
require.NoError(t, repo.Update(context.Background(), sub))
|
|
|
|
found, err := repo.FindByID(context.Background(), sub.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "https://example.com/updated", found.URL)
|
|
assert.False(t, found.Active)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_Delete(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
acct := &model.Account{Name: "WHDeleteOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
sub := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/to-delete",
|
|
Events: json.RawMessage(`["conversation_created"]`),
|
|
Secret: "delsecret",
|
|
Active: true,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), sub))
|
|
|
|
err := repo.Delete(context.Background(), sub.ID)
|
|
assert.NoError(t, err)
|
|
|
|
// Soft-delete: normal query won't find it
|
|
found, err := repo.FindByID(context.Background(), sub.ID)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, found)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_CreateDelivery(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
acct := &model.Account{Name: "WHDelOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
sub := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/del-hook",
|
|
Events: json.RawMessage(`["conversation_created"]`),
|
|
Secret: "delsecret",
|
|
Active: true,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), sub))
|
|
|
|
delivery := &model.WebhookDelivery{
|
|
SubscriptionID: sub.ID,
|
|
EventType: "conversation_created",
|
|
Payload: json.RawMessage(`{"id":1}`),
|
|
Status: model.WebhookDeliveryStatusPending,
|
|
Attempts: 0,
|
|
}
|
|
err := repo.CreateDelivery(context.Background(), delivery)
|
|
assert.NoError(t, err)
|
|
assert.NotZero(t, delivery.ID)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_UpdateDelivery(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
acct := &model.Account{Name: "WHDelUpOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
sub := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/del-up-hook",
|
|
Events: json.RawMessage(`["message_created"]`),
|
|
Secret: "delsecret2",
|
|
Active: true,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), sub))
|
|
|
|
delivery := &model.WebhookDelivery{
|
|
SubscriptionID: sub.ID,
|
|
EventType: "message_created",
|
|
Payload: json.RawMessage(`{"id":2}`),
|
|
Status: model.WebhookDeliveryStatusPending,
|
|
Attempts: 0,
|
|
}
|
|
require.NoError(t, repo.CreateDelivery(context.Background(), delivery))
|
|
|
|
delivery.Status = model.WebhookDeliveryStatusSuccess
|
|
delivery.Attempts = 1
|
|
delivery.ResponseCode = 200
|
|
require.NoError(t, repo.UpdateDelivery(context.Background(), delivery))
|
|
|
|
deliveries, err := repo.ListDeliveriesBySubscription(context.Background(), sub.ID, 10)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, deliveries, 1)
|
|
assert.Equal(t, model.WebhookDeliveryStatusSuccess, deliveries[0].Status)
|
|
assert.Equal(t, 200, deliveries[0].ResponseCode)
|
|
assert.Equal(t, 1, deliveries[0].Attempts)
|
|
}
|
|
|
|
func TestWebhookSubscriptionRepo_ListDeliveriesBySubscription(t *testing.T) {
|
|
db := setupTestDB(t, &model.WebhookSubscription{}, &model.WebhookDelivery{})
|
|
repo := NewWebhookSubscriptionRepo(db)
|
|
|
|
acct := &model.Account{Name: "WHDelListOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(acct).Error)
|
|
|
|
sub := &model.WebhookSubscription{
|
|
AccountID: acct.ID,
|
|
URL: "https://example.com/del-list-hook",
|
|
Events: json.RawMessage(`["conversation_created","message_created"]`),
|
|
Secret: "delsecret3",
|
|
Active: true,
|
|
}
|
|
require.NoError(t, repo.Create(context.Background(), sub))
|
|
|
|
for i := 0; i < 5; i++ {
|
|
delivery := &model.WebhookDelivery{
|
|
SubscriptionID: sub.ID,
|
|
EventType: "conversation_created",
|
|
Payload: json.RawMessage(`{"seq":` + json.Number(string(i+1)) + `}`),
|
|
Status: model.WebhookDeliveryStatusPending,
|
|
Attempts: 0,
|
|
}
|
|
require.NoError(t, repo.CreateDelivery(context.Background(), delivery))
|
|
}
|
|
|
|
// List with limit 3
|
|
deliveries, err := repo.ListDeliveriesBySubscription(context.Background(), sub.ID, 3)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, deliveries, 3)
|
|
|
|
// List with limit 10 (all)
|
|
allDeliveries, err := repo.ListDeliveriesBySubscription(context.Background(), sub.ID, 10)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, allDeliveries, 5)
|
|
} |