Files
galaxy-game/mail/internal/domain/attempt/model_test.go
T
2026-04-17 18:39:16 +02:00

169 lines
4.2 KiB
Go

package attempt
import (
"testing"
"time"
"galaxy/mail/internal/domain/common"
"github.com/stretchr/testify/require"
)
func TestStatusCanTransitionTo(t *testing.T) {
t.Parallel()
tests := []struct {
name string
from Status
to Status
want bool
}{
{name: "scheduled to in progress", from: StatusScheduled, to: StatusInProgress, want: true},
{name: "scheduled to render failed", from: StatusScheduled, to: StatusRenderFailed, want: true},
{name: "scheduled to accepted", from: StatusScheduled, to: StatusProviderAccepted, want: false},
{name: "in progress to accepted", from: StatusInProgress, to: StatusProviderAccepted, want: true},
{name: "in progress to rejected", from: StatusInProgress, to: StatusProviderRejected, want: true},
{name: "in progress to transport failed", from: StatusInProgress, to: StatusTransportFailed, want: true},
{name: "in progress to timed out", from: StatusInProgress, to: StatusTimedOut, want: true},
{name: "accepted terminal", from: StatusProviderAccepted, to: StatusTimedOut, want: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
require.Equal(t, tt.want, tt.from.CanTransitionTo(tt.to))
})
}
}
func TestStatusIsTerminal(t *testing.T) {
t.Parallel()
require.False(t, StatusScheduled.IsTerminal())
require.False(t, StatusInProgress.IsTerminal())
require.True(t, StatusProviderAccepted.IsTerminal())
require.True(t, StatusProviderRejected.IsTerminal())
require.True(t, StatusTransportFailed.IsTerminal())
require.True(t, StatusTimedOut.IsTerminal())
require.True(t, StatusRenderFailed.IsTerminal())
}
func TestAttemptValidate(t *testing.T) {
t.Parallel()
scheduledFor := time.Unix(1_775_121_700, 0).UTC()
startedAt := scheduledFor.Add(time.Minute)
finishedAt := startedAt.Add(2 * time.Second)
tests := []struct {
name string
record Attempt
wantErr bool
}{
{
name: "valid scheduled",
record: Attempt{
DeliveryID: common.DeliveryID("delivery-123"),
AttemptNo: 1,
ScheduledFor: scheduledFor,
Status: StatusScheduled,
},
},
{
name: "valid in progress",
record: Attempt{
DeliveryID: common.DeliveryID("delivery-123"),
AttemptNo: 2,
ScheduledFor: scheduledFor,
StartedAt: &startedAt,
Status: StatusInProgress,
},
},
{
name: "valid terminal",
record: Attempt{
DeliveryID: common.DeliveryID("delivery-123"),
AttemptNo: 3,
ScheduledFor: scheduledFor,
StartedAt: &startedAt,
FinishedAt: &finishedAt,
Status: StatusProviderAccepted,
},
},
{
name: "valid render failed",
record: Attempt{
DeliveryID: common.DeliveryID("delivery-123"),
AttemptNo: 4,
ScheduledFor: scheduledFor,
StartedAt: &startedAt,
FinishedAt: &finishedAt,
Status: StatusRenderFailed,
ProviderClassification: "missing_required_variable",
ProviderSummary: "missing required variables: player.name",
},
},
{
name: "attempt number must be positive",
record: Attempt{
DeliveryID: common.DeliveryID("delivery-123"),
ScheduledFor: scheduledFor,
Status: StatusScheduled,
},
wantErr: true,
},
{
name: "in progress missing started at",
record: Attempt{
DeliveryID: common.DeliveryID("delivery-123"),
AttemptNo: 1,
ScheduledFor: scheduledFor,
Status: StatusInProgress,
},
wantErr: true,
},
{
name: "terminal missing finished at",
record: Attempt{
DeliveryID: common.DeliveryID("delivery-123"),
AttemptNo: 1,
ScheduledFor: scheduledFor,
StartedAt: &startedAt,
Status: StatusProviderRejected,
},
wantErr: true,
},
{
name: "finished before started",
record: Attempt{
DeliveryID: common.DeliveryID("delivery-123"),
AttemptNo: 1,
ScheduledFor: scheduledFor,
StartedAt: &startedAt,
FinishedAt: &scheduledFor,
Status: StatusTimedOut,
},
wantErr: true,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := tt.record.Validate()
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
})
}
}