sync: scope Service to one user per instance
NewService now takes a userID, baked into the instance rather than passed per-call -- matches internal/api's one-Service-per-logged-in-user model (Task 13), so ClassifyActivity/Backfill/etc. keep their existing call signatures unchanged everywhere they're already used.
This commit is contained in:
@@ -28,17 +28,26 @@ func fixedNow(t time.Time) func() time.Time {
|
||||
return func() time.Time { return t }
|
||||
}
|
||||
|
||||
func provisionTestUser(t *testing.T, db *store.DB) int64 {
|
||||
t.Helper()
|
||||
userID, err := db.ProvisionUser(context.Background(), "test-sub", "Test")
|
||||
if err != nil {
|
||||
t.Fatalf("ProvisionUser: %v", err)
|
||||
}
|
||||
return userID
|
||||
}
|
||||
|
||||
// setBackfillHorizon sets Profile.BackfillHorizonDays, which Backfill reads
|
||||
// fresh on every call (it's no longer part of Config).
|
||||
func setBackfillHorizon(t *testing.T, db *store.DB, days int) {
|
||||
func setBackfillHorizon(t *testing.T, db *store.DB, userID int64, days int) {
|
||||
t.Helper()
|
||||
ctx := context.Background()
|
||||
profile, err := db.GetProfile(ctx)
|
||||
profile, err := db.GetProfile(ctx, userID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetProfile: %v", err)
|
||||
}
|
||||
profile.BackfillHorizonDays = days
|
||||
if err := db.UpdateProfile(ctx, profile); err != nil {
|
||||
if err := db.UpdateProfile(ctx, userID, profile); err != nil {
|
||||
t.Fatalf("UpdateProfile: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -46,18 +55,19 @@ func setBackfillHorizon(t *testing.T, db *store.DB, days int) {
|
||||
func TestBackfill_StoresActivitiesAndRecordsSyncRun(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
m := &mock.Client{Activities: []garmin.Activity{
|
||||
{ActivityID: 1, ActivityName: "Morning Run", ActivityType: garmin.ActivityType{TypeKey: "running"},
|
||||
StartTimeGMT: "2026-07-01 06:00:00", Distance: 5000, Duration: 1500, AverageSpeed: 3.33, AverageHR: 145},
|
||||
}}
|
||||
svc := NewService(m, db, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
svc := NewService(m, db, userID, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("Backfill: %v", err)
|
||||
}
|
||||
|
||||
activities, err := db.ListActivities(ctx, store.ActivityFilter{})
|
||||
activities, err := db.ListActivities(ctx, userID, store.ActivityFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("ListActivities: %v", err)
|
||||
}
|
||||
@@ -68,7 +78,7 @@ func TestBackfill_StoresActivitiesAndRecordsSyncRun(t *testing.T) {
|
||||
t.Errorf("GarminActivityID = %d, want 1", activities[0].GarminActivityID)
|
||||
}
|
||||
|
||||
runs, err := db.ListSyncRuns(ctx, 10)
|
||||
runs, err := db.ListSyncRuns(ctx, userID, 10)
|
||||
if err != nil {
|
||||
t.Fatalf("ListSyncRuns: %v", err)
|
||||
}
|
||||
@@ -188,6 +198,7 @@ func TestTargetHRRange_CustomRangeAndZoneNumberViaKarvonen(t *testing.T) {
|
||||
func TestBackfill_SkipsNonRunningActivities(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
m := &mock.Client{Activities: []garmin.Activity{
|
||||
{ActivityID: 1, ActivityType: garmin.ActivityType{TypeKey: "running"},
|
||||
@@ -199,13 +210,13 @@ func TestBackfill_SkipsNonRunningActivities(t *testing.T) {
|
||||
{ActivityID: 4, ActivityType: garmin.ActivityType{TypeKey: "indoor_cycling"},
|
||||
StartTimeGMT: "2026-07-04 06:00:00", Distance: 0, Duration: 1800},
|
||||
}}
|
||||
svc := NewService(m, db, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
svc := NewService(m, db, userID, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("Backfill: %v", err)
|
||||
}
|
||||
|
||||
activities, err := db.ListActivities(ctx, store.ActivityFilter{})
|
||||
activities, err := db.ListActivities(ctx, userID, store.ActivityFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("ListActivities: %v", err)
|
||||
}
|
||||
@@ -222,6 +233,7 @@ func TestBackfill_SkipsNonRunningActivities(t *testing.T) {
|
||||
func TestFillPendingDetailsAndClassify_EndToEnd(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
const garminActivityID = 42
|
||||
m := &mock.Client{
|
||||
@@ -244,7 +256,7 @@ func TestFillPendingDetailsAndClassify_EndToEnd(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
svc := NewService(m, db, Config{MinConfidence: 0.5}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
svc := NewService(m, db, userID, Config{MinConfidence: 0.5}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("Backfill: %v", err)
|
||||
@@ -252,7 +264,7 @@ func TestFillPendingDetailsAndClassify_EndToEnd(t *testing.T) {
|
||||
|
||||
// A workout kind that should cleanly match the seeded activity's pace.
|
||||
ruleJSON := `{"match":"all","conditions":[{"metric":"avg_pace_sec_per_km","op":"between","value":[280,320]}]}`
|
||||
if _, err := db.CreateWorkoutKind(ctx, store.WorkoutKind{Name: "Test Classification Tempo", RuleJSON: ruleJSON, IsActive: true}); err != nil {
|
||||
if _, err := db.CreateWorkoutKind(ctx, userID, store.WorkoutKind{Name: "Test Classification Tempo", RuleJSON: ruleJSON, IsActive: true}); err != nil {
|
||||
t.Fatalf("CreateWorkoutKind: %v", err)
|
||||
}
|
||||
|
||||
@@ -260,7 +272,7 @@ func TestFillPendingDetailsAndClassify_EndToEnd(t *testing.T) {
|
||||
t.Fatalf("FillPendingDetails: %v", err)
|
||||
}
|
||||
|
||||
activities, err := db.ListActivities(ctx, store.ActivityFilter{})
|
||||
activities, err := db.ListActivities(ctx, userID, store.ActivityFilter{})
|
||||
if err != nil || len(activities) != 1 {
|
||||
t.Fatalf("ListActivities: %v, %+v", err, activities)
|
||||
}
|
||||
@@ -273,12 +285,12 @@ func TestFillPendingDetailsAndClassify_EndToEnd(t *testing.T) {
|
||||
t.Error("expected SplitsFetchedAt to be set after FillPendingDetails")
|
||||
}
|
||||
|
||||
laps, err := db.LapsForActivity(ctx, activityID)
|
||||
laps, err := db.LapsForActivity(ctx, userID, activityID)
|
||||
if err != nil || len(laps) != 1 {
|
||||
t.Fatalf("LapsForActivity: %v, %+v", err, laps)
|
||||
}
|
||||
|
||||
assignment, ok, err := db.CurrentAssignment(ctx, activityID)
|
||||
assignment, ok, err := db.CurrentAssignment(ctx, userID, activityID)
|
||||
if err != nil || !ok {
|
||||
t.Fatalf("CurrentAssignment: ok=%v err=%v", ok, err)
|
||||
}
|
||||
@@ -290,6 +302,7 @@ func TestFillPendingDetailsAndClassify_EndToEnd(t *testing.T) {
|
||||
func TestFillPendingDetails_ResolvesWorkoutTargetsOntoLaps(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
const garminActivityID = 55
|
||||
const workoutID = 999
|
||||
@@ -313,7 +326,7 @@ func TestFillPendingDetails_ResolvesWorkoutTargetsOntoLaps(t *testing.T) {
|
||||
}},
|
||||
},
|
||||
}
|
||||
svc := NewService(m, db, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
svc := NewService(m, db, userID, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("Backfill: %v", err)
|
||||
@@ -322,11 +335,11 @@ func TestFillPendingDetails_ResolvesWorkoutTargetsOntoLaps(t *testing.T) {
|
||||
t.Fatalf("FillPendingDetails: %v", err)
|
||||
}
|
||||
|
||||
activities, err := db.ListActivities(ctx, store.ActivityFilter{})
|
||||
activities, err := db.ListActivities(ctx, userID, store.ActivityFilter{})
|
||||
if err != nil || len(activities) != 1 {
|
||||
t.Fatalf("ListActivities: %v, %+v", err, activities)
|
||||
}
|
||||
laps, err := db.LapsForActivity(ctx, activities[0].ID)
|
||||
laps, err := db.LapsForActivity(ctx, userID, activities[0].ID)
|
||||
if err != nil || len(laps) != 1 {
|
||||
t.Fatalf("LapsForActivity: %v, %+v", err, laps)
|
||||
}
|
||||
@@ -341,6 +354,7 @@ func TestFillPendingDetails_ResolvesWorkoutTargetsOntoLaps(t *testing.T) {
|
||||
func TestFillPendingDetails_OneExtraTrailingLapKeepsOtherLapsTargets(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
const garminActivityID = 56
|
||||
const workoutID = 1000
|
||||
@@ -369,7 +383,7 @@ func TestFillPendingDetails_OneExtraTrailingLapKeepsOtherLapsTargets(t *testing.
|
||||
}},
|
||||
},
|
||||
}
|
||||
svc := NewService(m, db, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
svc := NewService(m, db, userID, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("Backfill: %v", err)
|
||||
@@ -378,8 +392,8 @@ func TestFillPendingDetails_OneExtraTrailingLapKeepsOtherLapsTargets(t *testing.
|
||||
t.Fatalf("FillPendingDetails: %v", err)
|
||||
}
|
||||
|
||||
activities, _ := db.ListActivities(ctx, store.ActivityFilter{})
|
||||
laps, err := db.LapsForActivity(ctx, activities[0].ID)
|
||||
activities, _ := db.ListActivities(ctx, userID, store.ActivityFilter{})
|
||||
laps, err := db.LapsForActivity(ctx, userID, activities[0].ID)
|
||||
if err != nil || len(laps) != 2 {
|
||||
t.Fatalf("LapsForActivity: %v, %+v", err, laps)
|
||||
}
|
||||
@@ -443,13 +457,14 @@ func TestBuildMetricContext_DerivesIsRace(t *testing.T) {
|
||||
func TestBackfill_SecondRunIsANoOpOnceHorizonFullyCovered(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
m := &mock.Client{Activities: []garmin.Activity{
|
||||
{ActivityID: 1, ActivityType: garmin.ActivityType{TypeKey: "running"}, StartTimeGMT: "2026-07-05 06:00:00", Distance: 5000, Duration: 1500},
|
||||
}}
|
||||
svc := NewService(m, db, Config{BackfillWindowDays: 10},
|
||||
svc := NewService(m, db, userID, Config{BackfillWindowDays: 10},
|
||||
fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
setBackfillHorizon(t, db, 10)
|
||||
setBackfillHorizon(t, db, userID, 10)
|
||||
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("first Backfill: %v", err)
|
||||
@@ -459,7 +474,7 @@ func TestBackfill_SecondRunIsANoOpOnceHorizonFullyCovered(t *testing.T) {
|
||||
t.Fatal("expected first backfill to call GetActivities at least once")
|
||||
}
|
||||
|
||||
state, err := db.GetSyncState(ctx)
|
||||
state, err := db.GetSyncState(ctx, userID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetSyncState: %v", err)
|
||||
}
|
||||
@@ -479,13 +494,14 @@ func TestBackfill_SecondRunIsANoOpOnceHorizonFullyCovered(t *testing.T) {
|
||||
func TestResetAll_AllowsFreshBackfillAfterwards(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
m := &mock.Client{Activities: []garmin.Activity{
|
||||
{ActivityID: 1, ActivityType: garmin.ActivityType{TypeKey: "running"}, StartTimeGMT: "2026-07-05 06:00:00", Distance: 5000, Duration: 1500},
|
||||
}}
|
||||
svc := NewService(m, db, Config{BackfillWindowDays: 10},
|
||||
svc := NewService(m, db, userID, Config{BackfillWindowDays: 10},
|
||||
fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
setBackfillHorizon(t, db, 10)
|
||||
setBackfillHorizon(t, db, userID, 10)
|
||||
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("first Backfill: %v", err)
|
||||
@@ -495,7 +511,7 @@ func TestResetAll_AllowsFreshBackfillAfterwards(t *testing.T) {
|
||||
if err := svc.ResetAll(ctx); err != nil {
|
||||
t.Fatalf("ResetAll: %v", err)
|
||||
}
|
||||
activities, err := db.ListActivities(ctx, store.ActivityFilter{})
|
||||
activities, err := db.ListActivities(ctx, userID, store.ActivityFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("ListActivities: %v", err)
|
||||
}
|
||||
@@ -509,7 +525,7 @@ func TestResetAll_AllowsFreshBackfillAfterwards(t *testing.T) {
|
||||
if m.GetActivitiesCalls <= firstCallCount {
|
||||
t.Errorf("expected Backfill after ResetAll to call GetActivities again (fresh pull), call count stayed at %d", m.GetActivitiesCalls)
|
||||
}
|
||||
activities, err = db.ListActivities(ctx, store.ActivityFilter{})
|
||||
activities, err = db.ListActivities(ctx, userID, store.ActivityFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("ListActivities after re-backfill: %v", err)
|
||||
}
|
||||
@@ -521,14 +537,15 @@ func TestResetAll_AllowsFreshBackfillAfterwards(t *testing.T) {
|
||||
func TestBackfill_ResumesFromWatermarkWhenHorizonGrows(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
m := &mock.Client{Activities: []garmin.Activity{
|
||||
{ActivityID: 1, ActivityType: garmin.ActivityType{TypeKey: "running"}, StartTimeGMT: "2026-07-05 06:00:00", Distance: 5000, Duration: 1500},
|
||||
}}
|
||||
now := fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC))
|
||||
|
||||
svc := NewService(m, db, Config{BackfillWindowDays: 10}, now)
|
||||
setBackfillHorizon(t, db, 10)
|
||||
svc := NewService(m, db, userID, Config{BackfillWindowDays: 10}, now)
|
||||
setBackfillHorizon(t, db, userID, 10)
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("first Backfill: %v", err)
|
||||
}
|
||||
@@ -537,8 +554,8 @@ func TestBackfill_ResumesFromWatermarkWhenHorizonGrows(t *testing.T) {
|
||||
// Simulate the user widening the horizon later -- should resume from the
|
||||
// watermark (not re-fetch the already-covered recent window) but still
|
||||
// make progress toward the new, deeper horizon.
|
||||
setBackfillHorizon(t, db, 30)
|
||||
svc2 := NewService(m, db, Config{BackfillWindowDays: 10}, now)
|
||||
setBackfillHorizon(t, db, userID, 30)
|
||||
svc2 := NewService(m, db, userID, Config{BackfillWindowDays: 10}, now)
|
||||
if err := svc2.Backfill(ctx); err != nil {
|
||||
t.Fatalf("second Backfill: %v", err)
|
||||
}
|
||||
@@ -546,7 +563,7 @@ func TestBackfill_ResumesFromWatermarkWhenHorizonGrows(t *testing.T) {
|
||||
t.Errorf("expected additional GetActivities calls when horizon grows, got %d total (was %d)", m.GetActivitiesCalls, firstCallCount)
|
||||
}
|
||||
|
||||
state, err := db.GetSyncState(ctx)
|
||||
state, err := db.GetSyncState(ctx, userID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetSyncState: %v", err)
|
||||
}
|
||||
@@ -558,6 +575,7 @@ func TestBackfill_ResumesFromWatermarkWhenHorizonGrows(t *testing.T) {
|
||||
func TestFullSync_RecordsOneCombinedSyncRun(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
m := &mock.Client{
|
||||
Activities: []garmin.Activity{
|
||||
@@ -571,15 +589,15 @@ func TestFullSync_RecordsOneCombinedSyncRun(t *testing.T) {
|
||||
1: {ActivityID: 1}, 2: {ActivityID: 2},
|
||||
},
|
||||
}
|
||||
svc := NewService(m, db, Config{BackfillWindowDays: 10},
|
||||
svc := NewService(m, db, userID, Config{BackfillWindowDays: 10},
|
||||
fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
setBackfillHorizon(t, db, 10)
|
||||
setBackfillHorizon(t, db, userID, 10)
|
||||
|
||||
if err := svc.FullSync(ctx, 10); err != nil {
|
||||
t.Fatalf("FullSync: %v", err)
|
||||
}
|
||||
|
||||
runs, err := db.ListSyncRuns(ctx, 10)
|
||||
runs, err := db.ListSyncRuns(ctx, userID, 10)
|
||||
if err != nil {
|
||||
t.Fatalf("ListSyncRuns: %v", err)
|
||||
}
|
||||
@@ -606,7 +624,7 @@ func TestFullSync_RecordsOneCombinedSyncRun(t *testing.T) {
|
||||
t.Errorf("ActivitiesFetched = %d, want 2 (genuinely new activities, deduped across stages)", run.ActivitiesFetched)
|
||||
}
|
||||
|
||||
activities, err := db.ListActivities(ctx, store.ActivityFilter{})
|
||||
activities, err := db.ListActivities(ctx, userID, store.ActivityFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("ListActivities: %v", err)
|
||||
}
|
||||
@@ -618,6 +636,7 @@ func TestFullSync_RecordsOneCombinedSyncRun(t *testing.T) {
|
||||
func TestFillPendingDetails_ReportsLiveProgress(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userID := provisionTestUser(t, db)
|
||||
|
||||
m := &mock.Client{
|
||||
Activities: []garmin.Activity{},
|
||||
@@ -634,7 +653,7 @@ func TestFillPendingDetails_ReportsLiveProgress(t *testing.T) {
|
||||
m.Details[i] = garmin.ActivityDetails{ActivityID: i}
|
||||
}
|
||||
|
||||
svc := NewService(m, db, Config{InterCallDelay: 150 * time.Millisecond},
|
||||
svc := NewService(m, db, userID, Config{InterCallDelay: 150 * time.Millisecond},
|
||||
fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
if err := svc.Backfill(ctx); err != nil {
|
||||
t.Fatalf("Backfill: %v", err)
|
||||
@@ -663,3 +682,47 @@ func TestFillPendingDetails_ReportsLiveProgress(t *testing.T) {
|
||||
t.Errorf("Progress after completion = %+v, want zero value (idle)", final)
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_TwoUsersSyncIndependently(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
userA, err := db.ProvisionUser(ctx, "sub-a", "A")
|
||||
if err != nil {
|
||||
t.Fatalf("ProvisionUser(a): %v", err)
|
||||
}
|
||||
userB, err := db.ProvisionUser(ctx, "sub-b", "B")
|
||||
if err != nil {
|
||||
t.Fatalf("ProvisionUser(b): %v", err)
|
||||
}
|
||||
|
||||
mA := &mock.Client{Activities: []garmin.Activity{
|
||||
{ActivityID: 1, ActivityType: garmin.ActivityType{TypeKey: "running"}, StartTimeGMT: "2026-07-01 06:00:00", Distance: 5000, Duration: 1500},
|
||||
}}
|
||||
mB := &mock.Client{Activities: []garmin.Activity{
|
||||
{ActivityID: 2, ActivityType: garmin.ActivityType{TypeKey: "running"}, StartTimeGMT: "2026-07-01 06:00:00", Distance: 8000, Duration: 2400},
|
||||
}}
|
||||
svcA := NewService(mA, db, userA, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
svcB := NewService(mB, db, userB, Config{}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC)))
|
||||
|
||||
if err := svcA.Backfill(ctx); err != nil {
|
||||
t.Fatalf("Backfill(a): %v", err)
|
||||
}
|
||||
if err := svcB.Backfill(ctx); err != nil {
|
||||
t.Fatalf("Backfill(b): %v", err)
|
||||
}
|
||||
|
||||
activitiesA, err := db.ListActivities(ctx, userA, store.ActivityFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("ListActivities(a): %v", err)
|
||||
}
|
||||
activitiesB, err := db.ListActivities(ctx, userB, store.ActivityFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("ListActivities(b): %v", err)
|
||||
}
|
||||
if len(activitiesA) != 1 || activitiesA[0].GarminActivityID != 1 {
|
||||
t.Fatalf("userA's activities = %+v, want exactly garmin id 1", activitiesA)
|
||||
}
|
||||
if len(activitiesB) != 1 || activitiesB[0].GarminActivityID != 2 {
|
||||
t.Fatalf("userB's activities = %+v, want exactly garmin id 2", activitiesB)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user