package operation import ( "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func validSuccessEntry() OperationEntry { started := time.Date(2026, 4, 27, 12, 0, 0, 0, time.UTC) finished := started.Add(time.Second) return OperationEntry{ GameID: "game-1", OpKind: OpKindRegisterRuntime, OpSource: OpSourceLobbyInternal, Outcome: OutcomeSuccess, StartedAt: started, FinishedAt: &finished, } } func validFailureEntry() OperationEntry { entry := validSuccessEntry() entry.Outcome = OutcomeFailure entry.ErrorCode = "engine_unreachable" entry.ErrorMessage = "engine returned 502" return entry } func TestOpKindIsKnown(t *testing.T) { for _, kind := range AllOpKinds() { assert.True(t, kind.IsKnown(), "want known: %q", kind) } assert.False(t, OpKind("exotic").IsKnown()) assert.Len(t, AllOpKinds(), 10) } func TestOpSourceIsKnown(t *testing.T) { for _, src := range AllOpSources() { assert.True(t, src.IsKnown(), "want known: %q", src) } assert.False(t, OpSource("exotic").IsKnown()) assert.Len(t, AllOpSources(), 3) } func TestOutcomeIsKnown(t *testing.T) { for _, outcome := range AllOutcomes() { assert.True(t, outcome.IsKnown(), "want known: %q", outcome) } assert.False(t, Outcome("exotic").IsKnown()) assert.Len(t, AllOutcomes(), 2) } func TestOperationEntryValidateHappy(t *testing.T) { require.NoError(t, validSuccessEntry().Validate()) require.NoError(t, validFailureEntry().Validate()) } func TestOperationEntryValidateAcceptsInFlight(t *testing.T) { entry := validSuccessEntry() entry.FinishedAt = nil assert.NoError(t, entry.Validate()) } func TestOperationEntryValidateRejects(t *testing.T) { tests := []struct { name string mutate func(*OperationEntry) }{ {"empty game id", func(e *OperationEntry) { e.GameID = "" }}, {"unknown op kind", func(e *OperationEntry) { e.OpKind = "exotic" }}, {"unknown op source", func(e *OperationEntry) { e.OpSource = "exotic" }}, {"unknown outcome", func(e *OperationEntry) { e.Outcome = "exotic" }}, {"zero started at", func(e *OperationEntry) { e.StartedAt = time.Time{} }}, {"zero finished at when present", func(e *OperationEntry) { zero := time.Time{} e.FinishedAt = &zero }}, {"finished before started", func(e *OperationEntry) { before := e.StartedAt.Add(-time.Second) e.FinishedAt = &before }}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { entry := validSuccessEntry() tt.mutate(&entry) assert.Error(t, entry.Validate()) }) } } func TestOperationEntryValidateRejectsFailureWithoutCode(t *testing.T) { entry := validFailureEntry() entry.ErrorCode = "" assert.Error(t, entry.Validate()) }