Files
CosmicClash/server/store/initial_connect_sql_test.go
T

61 lines
2.4 KiB
Go

package store
import (
"database/sql"
"testing"
"time"
"github.com/cosmic-clash/cosmic-clash/server/domain"
)
func TestInitialConnectSQLPreservesAtomicNoShowReconciliation(t *testing.T) {
if !contains(initialConnectCandidatesSQL, "ASSIGNMENT_READY") || !contains(initialConnectCandidatesSQL, "LIMIT $1") {
t.Fatal("initial-connect sweep is not bounded to pre-live matches")
}
for query, fragments := range map[string][]string{
initialConnectIdempotencyInsertSQL: {"ON CONFLICT", "payload_digest"},
initialConnectMatchLockSQL: {"FOR UPDATE", "match_id = $1"},
initialConnectParticipantsSQL: {"participation_active", "FOR UPDATE"},
initialConnectDeactivateSQL: {"abandoned_at", "participation_active = FALSE"},
initialConnectReleaseAllSQL: {"match_id = $1", "participation_active = FALSE"},
initialConnectPenaltySQL: {"INITIAL_CONNECT_NO_SHOW", "ON CONFLICT"},
initialConnectOutboxSQL: {"state_changed", "revision", "ON CONFLICT"},
} {
for _, fragment := range fragments {
if !contains(query, fragment) {
t.Fatalf("query %q missing %q", query, fragment)
}
}
}
}
func TestInitialConnectPlanValidationRejectsIncompleteOrForgedPlans(t *testing.T) {
participants := []initialConnectParticipant{
{PlayerID: "p0", TicketID: "t0", Team: 0, ConnectedAt: validTime(100), Active: true},
{PlayerID: "p1", TicketID: "t1", Team: 1, Active: true},
}
plan := domain.InitialConnectPlan{
Action: domain.InitialConnectStartWithBot, MatchState: domain.Live,
Connected: []string{"p0"},
NoShows: []domain.Abandonment{{PlayerID: "p1", Cooldown: time.Minute, AbandonedAt: time.Unix(100, 0)}},
CasualLineup: []domain.CasualSlot{
{Slot: 0, Team: 0, PlayerID: "p0"}, {Slot: 1, Team: 1, PlayerID: "bot-1", IsBot: true},
{Slot: 2, Team: 0, PlayerID: "bot-2", IsBot: true}, {Slot: 3, Team: 1, PlayerID: "bot-3", IsBot: true},
{Slot: 4, Team: 0, PlayerID: "bot-4", IsBot: true}, {Slot: 5, Team: 1, PlayerID: "bot-5", IsBot: true},
},
}
if err := validateInitialConnectPlan(plan, participants, domain.Casual); err != nil {
t.Fatalf("valid plan rejected: %v", err)
}
plan.CasualLineup[1].Team = 0
if err := validateInitialConnectPlan(plan, participants, domain.Casual); err == nil {
t.Fatal("team-swapped lineup accepted")
}
}
func validTime(unix int64) (result sql.NullTime) {
result.Time = time.Unix(unix, 0)
result.Valid = true
return result
}