Files
galaxy-game/mail/internal/adapters/stubprovider/provider_test.go
T
2026-04-17 18:39:16 +02:00

124 lines
3.1 KiB
Go

package stubprovider
import (
"context"
"fmt"
"sync"
"testing"
"galaxy/mail/internal/domain/common"
deliverydomain "galaxy/mail/internal/domain/delivery"
"galaxy/mail/internal/ports"
"github.com/stretchr/testify/require"
)
func TestProviderSendUsesAcceptedDefault(t *testing.T) {
t.Parallel()
provider, err := New()
require.NoError(t, err)
result, err := provider.Send(context.Background(), testMessage(t))
require.NoError(t, err)
require.Equal(t, ports.ClassificationAccepted, result.Classification)
require.Equal(t, "provider=stub result=accepted", result.Summary)
require.Len(t, provider.Inputs(), 1)
}
func TestProviderSendConsumesScriptedOutcomesInOrder(t *testing.T) {
t.Parallel()
provider, err := New(
ScriptedOutcome{
Classification: ports.ClassificationTransientFailure,
Script: "retry_later",
},
ScriptedOutcome{
Classification: ports.ClassificationSuppressed,
Script: "policy_skip",
},
)
require.NoError(t, err)
first, err := provider.Send(context.Background(), testMessage(t))
require.NoError(t, err)
require.Equal(t, ports.ClassificationTransientFailure, first.Classification)
require.Equal(t, "provider=stub result=transient_failure script=retry_later", first.Summary)
second, err := provider.Send(context.Background(), testMessage(t))
require.NoError(t, err)
require.Equal(t, ports.ClassificationSuppressed, second.Classification)
require.Equal(t, "provider=stub result=suppressed script=policy_skip", second.Summary)
third, err := provider.Send(context.Background(), testMessage(t))
require.NoError(t, err)
require.Equal(t, ports.ClassificationAccepted, third.Classification)
}
func TestProviderSendConsumesQueueSafelyAcrossGoroutines(t *testing.T) {
t.Parallel()
const sendCount = 24
initial := make([]ScriptedOutcome, 0, sendCount)
for index := 0; index < sendCount; index++ {
initial = append(initial, ScriptedOutcome{
Classification: ports.ClassificationAccepted,
Script: fmt.Sprintf("case_%02d", index),
})
}
provider, err := New(initial...)
require.NoError(t, err)
message := testMessage(t)
summaries := make(chan string, sendCount)
errs := make(chan error, sendCount)
var waitGroup sync.WaitGroup
for index := 0; index < sendCount; index++ {
waitGroup.Add(1)
go func() {
defer waitGroup.Done()
result, sendErr := provider.Send(context.Background(), message)
if sendErr != nil {
errs <- sendErr
return
}
summaries <- result.Summary
}()
}
waitGroup.Wait()
close(summaries)
close(errs)
for err := range errs {
require.NoError(t, err)
}
seen := make(map[string]struct{}, sendCount)
for summary := range summaries {
seen[summary] = struct{}{}
}
require.Len(t, seen, sendCount)
require.Len(t, provider.Inputs(), sendCount)
}
func testMessage(t *testing.T) ports.Message {
t.Helper()
message := ports.Message{
Envelope: deliverydomain.Envelope{
To: []common.Email{common.Email("pilot@example.com")},
},
Content: deliverydomain.Content{
Subject: "Turn update",
TextBody: "Turn 54 is ready.",
},
}
require.NoError(t, message.Validate())
return message
}