diff options
Diffstat (limited to 'official_climb/attempt_test.go')
| -rw-r--r-- | official_climb/attempt_test.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/official_climb/attempt_test.go b/official_climb/attempt_test.go new file mode 100644 index 0000000..147c80b --- /dev/null +++ b/official_climb/attempt_test.go @@ -0,0 +1,128 @@ +package official_climb_test + +import ( + "database/sql" + "testing" + "time" + + "github.com/jftuga/geodist" + "github.com/martinlehoux/biking_home/internal/dbtest" + "github.com/martinlehoux/biking_home/official_climb" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func coord(lat, lon float64) geodist.Coord { + return geodist.Coord{Lat: lat, Lon: lon} +} + +func insertRide(t *testing.T, db *sql.DB, opts ...func(*rideInsert)) int64 { + t.Helper() + insert := rideInsert{startDate: "2026-09-01T08:00:00Z"} + for _, opt := range opts { + opt(&insert) + } + result, err := db.Exec(` + INSERT INTO rides (external_id, gpx_path, name, external_sport_type, start_date, distance_m, external_moving_time_s, elapsed_time_s, total_elevation_gain_m, average_speed_mps) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `, "strava:test-ride-"+insert.startDate, "missing.gpx", "Test Ride", "Ride", insert.startDate, 20_000, 0, 0, 0, 0) + require.NoError(t, err) + id, err := result.LastInsertId() + require.NoError(t, err) + return id +} + +type rideInsert struct { + startDate string +} + +func withStartDate(startDate string) func(*rideInsert) { + return func(r *rideInsert) { r.startDate = startDate } +} + +func attemptFixture(rideID, climbID int64, occurrence int) official_climb.Attempt { + return official_climb.Attempt{ + RideID: rideID, + ClimbID: climbID, + Occurrence: occurrence, + DistanceM: 3200, + ElevationGainM: 210, + SlopePercent: 6.5, + Cotacol: 84.2, + CotacolAlgoVersion: "v1", + StartedAt: time.Date(2026, 9, 1, 10, 0, 0, 0, time.UTC), + EndedAt: time.Date(2026, 9, 1, 10, 18, 30, 0, time.UTC), + } +} + +func TestReplaceRideAttemptsRoundTrip(t *testing.T) { + db := dbtest.New(t) + created, err := official_climb.Create(db, official_climb.OfficialClimb{Name: "Col de Test", StartCoord: coord(43.6, 5.4), EndCoord: coord(43.62, 5.42)}) + require.NoError(t, err) + rideID := insertRide(t, db) + + require.NoError(t, official_climb.ReplaceRideAttempts(db, rideID, []official_climb.Attempt{ + attemptFixture(rideID, created.ID, 0), + attemptFixture(rideID, created.ID, 1), + })) + + attempts, err := official_climb.AttemptsForClimb(db, created.ID) + require.NoError(t, err) + require.Len(t, attempts, 2) + assert.Equal(t, 0, attempts[0].Occurrence) + assert.Equal(t, 1, attempts[1].Occurrence) + assert.Equal(t, 3200.0, attempts[0].DistanceM) + assert.Equal(t, "v1", attempts[0].CotacolAlgoVersion) + assert.Equal(t, time.Date(2026, 9, 1, 10, 18, 30, 0, time.UTC), attempts[0].EndedAt) + + rideAttempts, err := official_climb.AttemptsForRide(db, rideID) + require.NoError(t, err) + require.Len(t, rideAttempts, 2) +} + +func TestReplaceRideAttemptsDropsStaleRows(t *testing.T) { + db := dbtest.New(t) + first, err := official_climb.Create(db, official_climb.OfficialClimb{Name: "Col A", StartCoord: coord(43.6, 5.4), EndCoord: coord(43.62, 5.42)}) + require.NoError(t, err) + second, err := official_climb.Create(db, official_climb.OfficialClimb{Name: "Col B", StartCoord: coord(43.7, 5.5), EndCoord: coord(43.72, 5.52)}) + require.NoError(t, err) + rideID := insertRide(t, db) + + require.NoError(t, official_climb.ReplaceRideAttempts(db, rideID, []official_climb.Attempt{attemptFixture(rideID, first.ID, 0)})) + require.NoError(t, official_climb.ReplaceRideAttempts(db, rideID, []official_climb.Attempt{attemptFixture(rideID, second.ID, 0)})) + + attempts, err := official_climb.AttemptsForClimb(db, first.ID) + require.NoError(t, err) + assert.Empty(t, attempts) + attempts, err = official_climb.AttemptsForClimb(db, second.ID) + require.NoError(t, err) + require.Len(t, attempts, 1) +} + +func TestReplaceRideAttemptsRejectsForeignRide(t *testing.T) { + db := dbtest.New(t) + created, err := official_climb.Create(db, official_climb.OfficialClimb{Name: "Col de Test", StartCoord: coord(43.6, 5.4), EndCoord: coord(43.62, 5.42)}) + require.NoError(t, err) + rideID := insertRide(t, db) + + attempt := attemptFixture(rideID+1, created.ID, 0) + err = official_climb.ReplaceRideAttempts(db, rideID, []official_climb.Attempt{attempt}) + assert.Error(t, err) +} + +func TestAttemptsForClimbOrdersByRideDate(t *testing.T) { + db := dbtest.New(t) + created, err := official_climb.Create(db, official_climb.OfficialClimb{Name: "Col de Test", StartCoord: coord(43.6, 5.4), EndCoord: coord(43.62, 5.42)}) + require.NoError(t, err) + newer := insertRide(t, db, withStartDate("2026-09-10T08:00:00Z")) + older := insertRide(t, db, withStartDate("2026-09-02T08:00:00Z")) + + require.NoError(t, official_climb.ReplaceRideAttempts(db, newer, []official_climb.Attempt{attemptFixture(newer, created.ID, 0)})) + require.NoError(t, official_climb.ReplaceRideAttempts(db, older, []official_climb.Attempt{attemptFixture(older, created.ID, 0)})) + + attempts, err := official_climb.AttemptsForClimb(db, created.ID) + require.NoError(t, err) + require.Len(t, attempts, 2) + assert.Equal(t, older, attempts[0].RideID) + assert.Equal(t, newer, attempts[1].RideID) +} |
