package processor import ( "testing" "time" "github.com/stretchr/testify/assert" "apskel-pos-be/internal/entities" ) func TestValidateResult(t *testing.T) { start := time.Date(2026, 10, 7, 12, 0, 0, 0, time.UTC) after := func(seconds int) time.Time { return start.Add(time.Duration(seconds) * time.Second) } score := func(v int64) *int64 { return &v } outcome := func(v string) *string { return &v } rules := entities.GameResultRules{ MaxScore: score(1000), MinDurationSeconds: score(10), MaxScorePerSecond: ptr(20.0), Outcomes: []string{"WIN", "LOSE"}, } for name, tc := range map[string]struct { rules entities.GameResultRules result SessionResult elapsed int reasons int }{ "no rules accept anything": {entities.GameResultRules{}, SessionResult{Score: score(999999), Outcome: outcome("ANY")}, 0, 0}, "within every rule": {rules, SessionResult{Score: score(1000), Outcome: outcome("WIN")}, 60, 0}, "no score, no outcome": {rules, SessionResult{}, 10, 0}, "too short": {rules, SessionResult{}, 9, 1}, "score above max": {rules, SessionResult{Score: score(1001)}, 600, 1}, "too fast": {rules, SessionResult{Score: score(201)}, 10, 1}, "exactly the per-second cap": {rules, SessionResult{Score: score(200)}, 10, 0}, "negative score": {rules, SessionResult{Score: score(-1)}, 60, 1}, "unknown outcome": {rules, SessionResult{Outcome: outcome("DRAW")}, 60, 1}, "zero time, some score": {entities.GameResultRules{MaxScorePerSecond: ptr(5.0)}, SessionResult{Score: score(1)}, 0, 1}, "zero time, zero score": {entities.GameResultRules{MaxScorePerSecond: ptr(5.0)}, SessionResult{Score: score(0)}, 0, 0}, "every rule broken": {rules, SessionResult{Score: score(5000), Outcome: outcome("DRAW")}, 1, 4}, } { reasons := ValidateResult(tc.rules, tc.result, start, after(tc.elapsed)) assert.Len(t, reasons, tc.reasons, "%s: %v", name, reasons) } }