Files
user-system/internal/repository/webhook_repository_test.go
long-agent 289aab2930 test: add repository tests to improve coverage from 46.6% to 74%
New test files:
- custom_field_repository_test.go: 10 tests for CustomFieldRepository & UserCustomFieldValueRepository
- login_log_repository_test.go: 3 tests for ListCursor, ListByUserIDCursor, ListAllForExport
- operation_log_repository_test.go: 1 test for ListCursor
- role_repository_test.go: 2 tests for GetAncestorIDs, GetAncestors
- social_account_repository_test.go: 8 CRUD tests
- theme_repository_test.go: 10 tests for ThemeConfigRepository
- user_role_repository_test.go: 1 test for DeleteByUserAndRole

Modified test files:
- device_repository_test.go: Added ListAllCursor tests
- user_repository_test.go: Added AdvancedSearch tests
- webhook_repository_test.go: Added ListByCreatorPaginated test

Updated documentation with new coverage status.
2026-04-11 21:58:28 +08:00

228 lines
6.4 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")
}
}
func TestWebhookRepositoryListByCreatorPaginated(t *testing.T) {
repo := setupWebhookRepository(t)
ctx := context.Background()
// 创建多个webhook
for i := 0; i < 5; i++ {
if err := repo.Create(ctx, newWebhookFixture("wh-creator1-"+string(rune('a'+i)), 1, domain.WebhookStatusActive)); err != nil {
t.Fatalf("Create failed: %v", err)
}
}
// 另一个用户的webhook
if err := repo.Create(ctx, newWebhookFixture("wh-creator2", 2, domain.WebhookStatusActive)); err != nil {
t.Fatalf("Create failed: %v", err)
}
// 测试分页查询创建者1的webhook
webhooks, total, err := repo.ListByCreatorPaginated(ctx, 1, 0, 3)
if err != nil {
t.Fatalf("ListByCreatorPaginated failed: %v", err)
}
if len(webhooks) != 3 {
t.Errorf("len(webhooks) = %d, want 3", len(webhooks))
}
if total != 5 {
t.Errorf("total = %d, want 5", total)
}
// 测试第二页
webhooks2, _, err := repo.ListByCreatorPaginated(ctx, 1, 3, 3)
if err != nil {
t.Fatalf("ListByCreatorPaginated page 2 failed: %v", err)
}
if len(webhooks2) != 2 {
t.Errorf("len(webhooks2) = %d, want 2", len(webhooks2))
}
}