101 lines
2.7 KiB
Go
101 lines
2.7 KiB
Go
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())
|
|
}
|