aboutsummaryrefslogtreecommitdiff
path: root/web/server_test.go
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2026-08-27 13:37:26 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2026-08-27 13:37:26 +0200
commitabbbf17bcfe6dfa663b7019c4892db09e27b3808 (patch)
tree483968e14d6e853aeb909724e7d60998f3d2a4b2 /web/server_test.go
parent6ec883a7fd40a14f2882076bd1a377bbbd0438ad (diff)
Resync Strava title from list payload via Save
Context / Problem: Strava titles can be corrected after import. The sync path only handled new rides; existing rides were marked skipped without checking the cheap list metadata, so corrections like ride #789 stayed stale. What: In syncRides reuse the existing Save write path for rare title resyncs (pay GPX parse cost) when existing.Name != list.Name; track progress.Updated and surface it in SSE/TS UI; add tests for resync without stream fetch. Remove the now-obsolete TODO. QA: go test/ vet, tsc, biome/stylelint pass.
Diffstat (limited to 'web/server_test.go')
-rw-r--r--web/server_test.go78
1 files changed, 76 insertions, 2 deletions
diff --git a/web/server_test.go b/web/server_test.go
index a60d742..7137031 100644
--- a/web/server_test.go
+++ b/web/server_test.go
@@ -615,6 +615,80 @@ func TestSyncRidesSavesActivityWithoutRoute(t *testing.T) {
assert.True(t, found)
}
+func TestSyncRidesResyncsTitleFromList(t *testing.T) {
+ server, db := newWebTestServer(t)
+ startDate := time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC)
+ gpxPath := testGPXPath(t, "existing.gpx")
+ require.NoError(t, ride.Save(db, ride.StoredRide{
+ ExternalID: "strava:789",
+ GPXPath: gpxPath,
+ Name: "Old Title",
+ Type: "Ride",
+ StartDate: startDate,
+ DistanceM: 20_000,
+ }))
+ // Verify the title was corrected on Strava (ride #789).
+ client := fakeSyncClient{
+ activities: []strava.Activity{
+ {ID: 789, Name: "Corrected Title", Type: "Ride", StartDate: startDate},
+ },
+ results: map[int64]fakeSyncResult{},
+ }
+ gpxDir := t.TempDir()
+ var getCalled bool
+ wrapped := countingSyncClient{inner: client, getCalled: &getCalled}
+ progress, err := server.syncRides(wrapped, gpxDir, startDate, startDate.AddDate(0, 0, 1), nil)
+ require.NoError(t, err)
+ assert.Equal(t, SyncProgress{Total: 1, Completed: 1, Imported: 0, Skipped: 0, Updated: 1}, progress)
+ assert.False(t, getCalled, "sync should not fetch streams for metadata resync")
+ updated, found, err := ride.GetByExternalID(db, "strava:789")
+ require.NoError(t, err)
+ require.True(t, found)
+ assert.Equal(t, "Corrected Title", updated.Name)
+ assert.Equal(t, gpxPath, updated.GPXPath, "GPX path should be preserved on metadata resync")
+}
+
+func TestSyncRidesSkipsWhenTitleUnchanged(t *testing.T) {
+ server, db := newWebTestServer(t)
+ startDate := time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC)
+ require.NoError(t, ride.Save(db, ride.StoredRide{
+ ExternalID: "strava:789",
+ GPXPath: testGPXPath(t, "existing2.gpx"),
+ Name: "Same Title",
+ Type: "Ride",
+ StartDate: startDate,
+ DistanceM: 20_000,
+ }))
+ client := fakeSyncClient{
+ activities: []strava.Activity{
+ {ID: 789, Name: "Same Title", Type: "Ride", StartDate: startDate},
+ },
+ results: map[int64]fakeSyncResult{},
+ }
+ gpxDir := t.TempDir()
+ progress, err := server.syncRides(client, gpxDir, startDate, startDate.AddDate(0, 0, 1), nil)
+ require.NoError(t, err)
+ assert.Equal(t, SyncProgress{Total: 1, Completed: 1, Imported: 0, Skipped: 1, Updated: 0}, progress)
+ stored, found, err := ride.GetByExternalID(db, "strava:789")
+ require.NoError(t, err)
+ require.True(t, found)
+ assert.Equal(t, "Same Title", stored.Name)
+}
+
+type countingSyncClient struct {
+ inner fakeSyncClient
+ getCalled *bool
+}
+
+func (c countingSyncClient) List(from, to time.Time) ([]strava.Activity, error) {
+ return c.inner.List(from, to)
+}
+
+func (c countingSyncClient) Get(id int64) (strava.Activity, []byte, error) {
+ *c.getCalled = true
+ return c.inner.Get(id)
+}
+
func TestSyncRejectsConcurrentImport(t *testing.T) {
server, _ := newWebTestServer(t)
appConfig, err := config.Load(server.configPath)
@@ -645,8 +719,8 @@ func TestWriteSyncEvent(t *testing.T) {
require.NoError(t, writeSyncEvent(response, response, "complete", progress))
body := response.Body.String()
- assert.Contains(t, body, "event: progress\ndata: {\"total\":2,\"completed\":1,\"imported\":1,\"skipped\":0}\n\n")
- assert.Contains(t, body, "event: complete\ndata: {\"total\":2,\"completed\":1,\"imported\":1,\"skipped\":0}\n\n")
+ assert.Contains(t, body, "event: progress\ndata: {\"total\":2,\"completed\":1,\"imported\":1,\"skipped\":0,\"updated\":0}\n\n")
+ assert.Contains(t, body, "event: complete\ndata: {\"total\":2,\"completed\":1,\"imported\":1,\"skipped\":0,\"updated\":0}\n\n")
assert.Less(t, strings.Index(body, "event: progress"), strings.Index(body, "event: complete"))
}