forked from baron/baron-sso
133 lines
3.6 KiB
Go
133 lines
3.6 KiB
Go
package service
|
|
|
|
import (
|
|
"baron-sso-backend/internal/domain"
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type fakeRPUsageOutboxRepo struct {
|
|
created []domain.RPUsageEvent
|
|
ready []domain.RPUsageEvent
|
|
processing []string
|
|
processed []string
|
|
failed []string
|
|
createErr error
|
|
projectErr error
|
|
}
|
|
|
|
func (f *fakeRPUsageOutboxRepo) Create(ctx context.Context, event *domain.RPUsageEvent) error {
|
|
if f.createErr != nil {
|
|
return f.createErr
|
|
}
|
|
f.created = append(f.created, *event)
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeRPUsageOutboxRepo) ListReady(ctx context.Context, limit int) ([]domain.RPUsageEvent, error) {
|
|
return f.ready, nil
|
|
}
|
|
|
|
func (f *fakeRPUsageOutboxRepo) MarkProcessing(ctx context.Context, id string) error {
|
|
f.processing = append(f.processing, id)
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeRPUsageOutboxRepo) MarkProcessed(ctx context.Context, id string) error {
|
|
f.processed = append(f.processed, id)
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeRPUsageOutboxRepo) MarkFailed(ctx context.Context, id string, message string, nextAttemptAt time.Time) error {
|
|
f.failed = append(f.failed, id)
|
|
return nil
|
|
}
|
|
|
|
type fakeRPUsageProjectionRepo struct {
|
|
created []domain.RPUsageEvent
|
|
err error
|
|
}
|
|
|
|
func (f *fakeRPUsageProjectionRepo) CreateRPUsageEvent(ctx context.Context, event domain.RPUsageEvent) error {
|
|
if f.err != nil {
|
|
return f.err
|
|
}
|
|
f.created = append(f.created, event)
|
|
return nil
|
|
}
|
|
|
|
func TestRPUsageEventEmitterRequiresCanonicalFields(t *testing.T) {
|
|
repo := &fakeRPUsageOutboxRepo{}
|
|
emitter := NewRPUsageEventEmitter(repo)
|
|
|
|
err := emitter.EmitRPUsageEvent(context.Background(), domain.RPUsageEvent{
|
|
EventType: domain.RPUsageEventTypeAuthorizationGranted,
|
|
ClientID: "client-app",
|
|
})
|
|
|
|
require.Error(t, err)
|
|
require.Empty(t, repo.created)
|
|
}
|
|
|
|
func TestRPUsageEventEmitterCreatesPendingOutboxEvent(t *testing.T) {
|
|
repo := &fakeRPUsageOutboxRepo{}
|
|
emitter := NewRPUsageEventEmitter(repo)
|
|
|
|
err := emitter.EmitRPUsageEvent(context.Background(), domain.RPUsageEvent{
|
|
EventType: domain.RPUsageEventTypeAuthorizationGranted,
|
|
Subject: "user-123",
|
|
ClientID: "client-app",
|
|
Source: "hydra_consent",
|
|
CorrelationID: "challenge-1",
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, repo.created, 1)
|
|
require.NotEmpty(t, repo.created[0].DedupeKey)
|
|
require.Equal(t, domain.RPUsageEventTypeAuthorizationGranted, repo.created[0].EventType)
|
|
require.Equal(t, "hydra_consent", repo.created[0].Source)
|
|
}
|
|
|
|
func TestRPUsageProjectorWorkerMarksProcessedAfterProjection(t *testing.T) {
|
|
outbox := &fakeRPUsageOutboxRepo{
|
|
ready: []domain.RPUsageEvent{{
|
|
ID: "event-1",
|
|
EventType: domain.RPUsageEventTypeAuthorizationGranted,
|
|
Subject: "user-123",
|
|
ClientID: "client-app",
|
|
}},
|
|
}
|
|
projection := &fakeRPUsageProjectionRepo{}
|
|
worker := NewRPUsageProjectorWorker(outbox, projection)
|
|
|
|
worker.processOnce(context.Background())
|
|
|
|
require.Equal(t, []string{"event-1"}, outbox.processing)
|
|
require.Equal(t, []string{"event-1"}, outbox.processed)
|
|
require.Empty(t, outbox.failed)
|
|
require.Len(t, projection.created, 1)
|
|
}
|
|
|
|
func TestRPUsageProjectorWorkerMarksFailedWhenProjectionFails(t *testing.T) {
|
|
outbox := &fakeRPUsageOutboxRepo{
|
|
ready: []domain.RPUsageEvent{{
|
|
ID: "event-1",
|
|
EventType: domain.RPUsageEventTypeAuthorizationGranted,
|
|
Subject: "user-123",
|
|
ClientID: "client-app",
|
|
}},
|
|
}
|
|
projection := &fakeRPUsageProjectionRepo{err: errors.New("clickhouse unavailable")}
|
|
worker := NewRPUsageProjectorWorker(outbox, projection)
|
|
|
|
worker.processOnce(context.Background())
|
|
|
|
require.Equal(t, []string{"event-1"}, outbox.processing)
|
|
require.Empty(t, outbox.processed)
|
|
require.Equal(t, []string{"event-1"}, outbox.failed)
|
|
}
|