191 lines
5.3 KiB
Go
191 lines
5.3 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/user-management-system/internal/domain"
|
|
)
|
|
|
|
func setupWebhookRepository(t *testing.T) *WebhookRepository {
|
|
t.Helper()
|
|
|
|
db := openTestDB(t)
|
|
if err := db.AutoMigrate(&domain.Webhook{}, &domain.WebhookDelivery{}); err != nil {
|
|
t.Fatalf("migrate webhook tables failed: %v", err)
|
|
}
|
|
|
|
return NewWebhookRepository(db)
|
|
}
|
|
|
|
func newWebhookFixture(name string, createdBy int64, status domain.WebhookStatus) *domain.Webhook {
|
|
return &domain.Webhook{
|
|
Name: name,
|
|
URL: "https://example.com/webhook",
|
|
Secret: "secret-demo",
|
|
Events: `["user.registered"]`,
|
|
Status: status,
|
|
MaxRetries: 3,
|
|
TimeoutSec: 10,
|
|
CreatedBy: createdBy,
|
|
}
|
|
}
|
|
|
|
func TestWebhookRepositoryCreateGetUpdateAndDelete(t *testing.T) {
|
|
repo := setupWebhookRepository(t)
|
|
ctx := context.Background()
|
|
|
|
webhook := newWebhookFixture("alpha", 101, domain.WebhookStatusActive)
|
|
if err := repo.Create(ctx, webhook); err != nil {
|
|
t.Fatalf("Create failed: %v", err)
|
|
}
|
|
if webhook.ID == 0 {
|
|
t.Fatal("expected webhook id to be assigned")
|
|
}
|
|
|
|
loaded, err := repo.GetByID(ctx, webhook.ID)
|
|
if err != nil {
|
|
t.Fatalf("GetByID failed: %v", err)
|
|
}
|
|
if loaded.Name != "alpha" {
|
|
t.Fatalf("expected loaded webhook name alpha, got %q", loaded.Name)
|
|
}
|
|
|
|
if err := repo.Update(ctx, webhook.ID, map[string]interface{}{
|
|
"name": "alpha-updated",
|
|
"status": domain.WebhookStatusInactive,
|
|
}); err != nil {
|
|
t.Fatalf("Update failed: %v", err)
|
|
}
|
|
|
|
updated, err := repo.GetByID(ctx, webhook.ID)
|
|
if err != nil {
|
|
t.Fatalf("GetByID after update failed: %v", err)
|
|
}
|
|
if updated.Name != "alpha-updated" {
|
|
t.Fatalf("expected updated name alpha-updated, got %q", updated.Name)
|
|
}
|
|
if updated.Status != domain.WebhookStatusInactive {
|
|
t.Fatalf("expected updated status inactive, got %d", updated.Status)
|
|
}
|
|
|
|
if err := repo.Delete(ctx, webhook.ID); err != nil {
|
|
t.Fatalf("Delete failed: %v", err)
|
|
}
|
|
|
|
if _, err := repo.GetByID(ctx, webhook.ID); err == nil {
|
|
t.Fatal("expected deleted webhook lookup to fail")
|
|
}
|
|
}
|
|
|
|
func TestWebhookRepositoryListsByCreatorAndActiveStatus(t *testing.T) {
|
|
repo := setupWebhookRepository(t)
|
|
ctx := context.Background()
|
|
|
|
fixtures := []*domain.Webhook{
|
|
newWebhookFixture("creator-1-active", 1, domain.WebhookStatusActive),
|
|
newWebhookFixture("creator-1-inactive", 1, domain.WebhookStatusInactive),
|
|
newWebhookFixture("creator-2-active", 2, domain.WebhookStatusActive),
|
|
}
|
|
|
|
for _, webhook := range fixtures {
|
|
if err := repo.Create(ctx, webhook); err != nil {
|
|
t.Fatalf("Create(%s) failed: %v", webhook.Name, err)
|
|
}
|
|
}
|
|
|
|
creatorOneHooks, err := repo.ListByCreator(ctx, 1)
|
|
if err != nil {
|
|
t.Fatalf("ListByCreator(1) failed: %v", err)
|
|
}
|
|
if len(creatorOneHooks) != 2 {
|
|
t.Fatalf("expected 2 hooks for creator 1, got %d", len(creatorOneHooks))
|
|
}
|
|
|
|
allHooks, err := repo.ListByCreator(ctx, 0)
|
|
if err != nil {
|
|
t.Fatalf("ListByCreator(0) failed: %v", err)
|
|
}
|
|
if len(allHooks) != 3 {
|
|
t.Fatalf("expected 3 hooks when listing all creators, got %d", len(allHooks))
|
|
}
|
|
|
|
activeHooks, err := repo.ListActive(ctx)
|
|
if err != nil {
|
|
t.Fatalf("ListActive failed: %v", err)
|
|
}
|
|
if len(activeHooks) != 2 {
|
|
t.Fatalf("expected 2 active hooks, got %d", len(activeHooks))
|
|
}
|
|
for _, hook := range activeHooks {
|
|
if hook.Status != domain.WebhookStatusActive {
|
|
t.Fatalf("expected active hook status, got %d", hook.Status)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWebhookRepositoryCreateAndListDeliveries(t *testing.T) {
|
|
repo := setupWebhookRepository(t)
|
|
ctx := context.Background()
|
|
|
|
webhook := newWebhookFixture("delivery-hook", 7, domain.WebhookStatusActive)
|
|
if err := repo.Create(ctx, webhook); err != nil {
|
|
t.Fatalf("Create webhook failed: %v", err)
|
|
}
|
|
|
|
olderTime := time.Now().Add(-time.Minute)
|
|
newerTime := time.Now()
|
|
|
|
firstDelivery := &domain.WebhookDelivery{
|
|
WebhookID: webhook.ID,
|
|
EventType: domain.EventUserRegistered,
|
|
Payload: `{"user":"older"}`,
|
|
StatusCode: 200,
|
|
ResponseBody: `{"ok":true}`,
|
|
Attempt: 1,
|
|
Success: true,
|
|
CreatedAt: olderTime,
|
|
}
|
|
secondDelivery := &domain.WebhookDelivery{
|
|
WebhookID: webhook.ID,
|
|
EventType: domain.EventUserLogin,
|
|
Payload: `{"user":"newer"}`,
|
|
StatusCode: 500,
|
|
ResponseBody: `{"ok":false}`,
|
|
Attempt: 2,
|
|
Success: false,
|
|
Error: "delivery failed",
|
|
CreatedAt: newerTime,
|
|
}
|
|
|
|
if err := repo.CreateDelivery(ctx, firstDelivery); err != nil {
|
|
t.Fatalf("CreateDelivery(first) failed: %v", err)
|
|
}
|
|
if err := repo.CreateDelivery(ctx, secondDelivery); err != nil {
|
|
t.Fatalf("CreateDelivery(second) failed: %v", err)
|
|
}
|
|
|
|
latestOnly, err := repo.ListDeliveries(ctx, webhook.ID, 1)
|
|
if err != nil {
|
|
t.Fatalf("ListDeliveries(limit=1) failed: %v", err)
|
|
}
|
|
if len(latestOnly) != 1 {
|
|
t.Fatalf("expected 1 latest delivery, got %d", len(latestOnly))
|
|
}
|
|
if latestOnly[0].ID != secondDelivery.ID {
|
|
t.Fatalf("expected latest delivery id %d, got %d", secondDelivery.ID, latestOnly[0].ID)
|
|
}
|
|
|
|
allDeliveries, err := repo.ListDeliveries(ctx, webhook.ID, 10)
|
|
if err != nil {
|
|
t.Fatalf("ListDeliveries(limit=10) failed: %v", err)
|
|
}
|
|
if len(allDeliveries) != 2 {
|
|
t.Fatalf("expected 2 deliveries, got %d", len(allDeliveries))
|
|
}
|
|
if allDeliveries[0].ID != secondDelivery.ID || allDeliveries[1].ID != firstDelivery.ID {
|
|
t.Fatal("expected deliveries to be returned in reverse created_at order")
|
|
}
|
|
}
|