aboutsummaryrefslogtreecommitdiff
path: root/official_climb/attempt_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'official_climb/attempt_test.go')
-rw-r--r--official_climb/attempt_test.go128
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)
+}