template-monorepo/internal/model/notification/usecase/retry_worker_test.go

103 lines
3.5 KiB
Go
Raw Permalink Normal View History

package usecase_test
import (
"context"
"fmt"
"testing"
"gateway/internal/model/notification/config"
domentity "gateway/internal/model/notification/domain/entity"
"gateway/internal/model/notification/domain/enum"
domrepo "gateway/internal/model/notification/domain/repository"
domtpl "gateway/internal/model/notification/domain/template"
domusecase "gateway/internal/model/notification/domain/usecase"
mocknotifrepo "gateway/internal/model/notification/mock/repository"
"gateway/internal/model/notification/provider/email"
"gateway/internal/model/notification/template"
"gateway/internal/model/notification/usecase"
"github.com/stretchr/testify/require"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/mock/gomock"
)
func TestRetryWorker_ProcessJob_Success(t *testing.T) {
ctrl := gomock.NewController(t)
repo := mocknotifrepo.NewMockNotificationRepository(ctrl)
docID := bson.NewObjectID()
doc := &domentity.Notification{
ID: docID,
TenantID: testTenantID,
Status: enum.NotifyStatusPending,
Locale: domtpl.LocaleZhTW,
Attempts: 0,
}
repo.EXPECT().FindByID(gomock.Any(), testTenantID, docID.Hex()).Return(doc, nil)
repo.EXPECT().UpdateDelivery(gomock.Any(), testTenantID, docID.Hex(), gomock.Any()).Return(nil)
worker := usecase.NewRetryWorker(usecase.RetryWorkerParam{
Repo: repo,
Renderer: template.NewRenderer(template.DefaultRegistry(), domtpl.LocaleZhTW),
Email: email.NewChain(email.NewMockSender(
email.WithMockName("mock"),
email.WithMockMessageID("ok"),
)),
Config: config.Config{Email: config.EmailConfig{From: testEmailFrom}},
})
job := &domusecase.RetryJob{
NotificationID: docID.Hex(),
TenantID: testTenantID,
Channel: enum.ChannelEmail,
Kind: enum.NotifyTenantWelcome,
Target: testEmailTarget,
Locale: domtpl.LocaleZhTW,
Data: map[string]any{varTenantName: testTenantName},
}
require.NoError(t, worker.ProcessJob(context.Background(), job))
}
func TestRetryWorker_ProcessJob_DropsToDLQ(t *testing.T) {
ctrl := gomock.NewController(t)
repo := mocknotifrepo.NewMockNotificationRepository(ctrl)
dlq := mocknotifrepo.NewMockNotificationDLQRepository(ctrl)
queue := mocknotifrepo.NewMockRetryQueue(ctrl)
docID := bson.NewObjectID()
doc := &domentity.Notification{
ID: docID,
TenantID: testTenantID,
Status: enum.NotifyStatusRetrying,
Locale: domtpl.LocaleZhTW,
Attempts: 4,
}
repo.EXPECT().FindByID(gomock.Any(), testTenantID, docID.Hex()).Return(doc, nil)
repo.EXPECT().UpdateDelivery(gomock.Any(), testTenantID, docID.Hex(), gomock.Any()).DoAndReturn(
func(_ context.Context, _, _ string, u *domrepo.NotificationDeliveryUpdate) error {
require.Equal(t, enum.NotifyStatusDropped, u.Status)
return nil
},
)
dlq.EXPECT().Insert(gomock.Any(), gomock.Any()).Return(nil)
worker := usecase.NewRetryWorker(usecase.RetryWorkerParam{
Repo: repo,
DLQ: dlq,
Queue: queue,
Renderer: template.NewRenderer(template.DefaultRegistry(), domtpl.LocaleZhTW),
Email: email.NewChain(email.NewMockSender(email.WithMockError(fmt.Errorf("fail")))),
Config: config.Config{Async: config.AsyncConfig{MaxRetry: 5}, Email: config.EmailConfig{From: testEmailFrom}},
})
job := &domusecase.RetryJob{
NotificationID: docID.Hex(),
TenantID: testTenantID,
Channel: enum.ChannelEmail,
Kind: enum.NotifyTenantWelcome,
Target: testEmailTarget,
Data: map[string]any{varTenantName: testTenantName},
}
require.NoError(t, worker.ProcessJob(context.Background(), job))
}