mirror of
https://github.com/IS1DI/x0gp.git
synced 2026-07-19 05:47:02 +00:00
Add driver profile stats API, nickname update editing, and security checks
This commit is contained in:
@@ -393,3 +393,127 @@ func TestGetRaceAndLastFinished(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDriverProfileStats(t *testing.T) {
|
||||
dsn := os.Getenv("DATABASE_URL")
|
||||
if dsn == "" {
|
||||
t.Skip("DATABASE_URL is empty; skipping integration test")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
pool, err := pgxpool.New(ctx, dsn)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open pool: %v", err)
|
||||
}
|
||||
defer pool.Close()
|
||||
|
||||
store := NewPgStore(pool)
|
||||
|
||||
// Clean up any test records
|
||||
_, _ = store.Exec(ctx, `DELETE FROM race_queue WHERE driver_id = 'test-stats-drv'`)
|
||||
_, _ = store.Exec(ctx, `DELETE FROM race_drivers WHERE driver_id = 'test-stats-drv'`)
|
||||
_, _ = store.Exec(ctx, `DELETE FROM races WHERE id LIKE 'test-stats-race-%'`)
|
||||
_, _ = store.Exec(ctx, `DELETE FROM drivers WHERE id = 'test-stats-drv'`)
|
||||
|
||||
// 1. Create a driver
|
||||
_, _ = store.Exec(ctx, `
|
||||
INSERT INTO drivers (id, nickname, name, avatar_url, created_ms, updated_ms)
|
||||
VALUES ('test-stats-drv', 'TSD', 'Test Stats Driver', '', 1700000000, 1700000000)`)
|
||||
|
||||
// 2. Insert races and race results
|
||||
// Race 1: finished, TSD took 2nd position, best lap 15000, total time 50000
|
||||
race1 := FinishedRace{
|
||||
ID: "test-stats-race-1",
|
||||
Name: "Race 1",
|
||||
TrackID: "monaco",
|
||||
MaxCars: 4,
|
||||
Laps: 5,
|
||||
TimeLimitS: 300,
|
||||
DriverIDs: []string{"test-stats-drv"},
|
||||
Status: "finished",
|
||||
CreatedMs: 1700000000,
|
||||
StartedMs: 1700000500,
|
||||
FinishedMs: 1700060000,
|
||||
DurationMs: 59500,
|
||||
TotalLaps: 5,
|
||||
TotalDrivers: 2,
|
||||
Results: []DriverResult{
|
||||
{
|
||||
DriverID: "test-stats-drv",
|
||||
TotalTimeMs: 50000,
|
||||
BestLapMs: 15000,
|
||||
Position: ptrInt(2),
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := store.InsertFinished(ctx, race1); err != nil {
|
||||
t.Fatalf("InsertFinished 1 failed: %v", err)
|
||||
}
|
||||
|
||||
// Race 2: finished, TSD took 1st position (Win), best lap 14000 (Best Lap), total time 45000
|
||||
race2 := FinishedRace{
|
||||
ID: "test-stats-race-2",
|
||||
Name: "Race 2",
|
||||
TrackID: "monaco",
|
||||
MaxCars: 4,
|
||||
Laps: 5,
|
||||
TimeLimitS: 300,
|
||||
DriverIDs: []string{"test-stats-drv"},
|
||||
Status: "finished",
|
||||
CreatedMs: 1700100000,
|
||||
StartedMs: 1700100500,
|
||||
FinishedMs: 1700160000,
|
||||
DurationMs: 59500,
|
||||
TotalLaps: 5,
|
||||
TotalDrivers: 2,
|
||||
Results: []DriverResult{
|
||||
{
|
||||
DriverID: "test-stats-drv",
|
||||
TotalTimeMs: 45000,
|
||||
BestLapMs: 14000,
|
||||
Position: ptrInt(1),
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := store.InsertFinished(ctx, race2); err != nil {
|
||||
t.Fatalf("InsertFinished 2 failed: %v", err)
|
||||
}
|
||||
|
||||
// 3. Query stats
|
||||
stats, err := store.GetDriverStats(ctx, "test-stats-drv")
|
||||
if err != nil {
|
||||
t.Fatalf("GetDriverStats failed: %v", err)
|
||||
}
|
||||
if stats.TotalRacesStarted != 2 || stats.TotalRacesFinished != 2 {
|
||||
t.Errorf("expected 2 races started/finished, got: %+v", stats)
|
||||
}
|
||||
if stats.Wins != 1 || stats.Podiums != 2 {
|
||||
t.Errorf("expected 1 win, 2 podiums, got: %+v", stats)
|
||||
}
|
||||
if stats.BestLapMs != 14000 {
|
||||
t.Errorf("expected best lap 14000, got %d", stats.BestLapMs)
|
||||
}
|
||||
if stats.TotalPlaytimeMs != 95000 {
|
||||
t.Errorf("expected total playtime 95000, got %d", stats.TotalPlaytimeMs)
|
||||
}
|
||||
|
||||
// 4. Query last race (should be Race 2, finished at 1700160000)
|
||||
last, err := store.GetDriverLastRace(ctx, "test-stats-drv")
|
||||
if err != nil {
|
||||
t.Fatalf("GetDriverLastRace failed: %v", err)
|
||||
}
|
||||
if last == nil || last.RaceID != "test-stats-race-2" {
|
||||
t.Errorf("expected last race test-stats-race-2, got: %+v", last)
|
||||
}
|
||||
|
||||
// 5. Query best race (should be Race 2, because position 1 is better than 2)
|
||||
best, err := store.GetDriverBestRace(ctx, "test-stats-drv")
|
||||
if err != nil {
|
||||
t.Fatalf("GetDriverBestRace failed: %v", err)
|
||||
}
|
||||
if best == nil || best.RaceID != "test-stats-race-2" {
|
||||
t.Errorf("expected best race test-stats-race-2, got: %+v", best)
|
||||
}
|
||||
}
|
||||
|
||||
func ptrInt(v int) *int { return &v }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user