refactor: merge internal/sync into internal/garmin, regroup api files and routes
Garmin auth/sync routes move under /api/garmin/*; sync.Service becomes garmin.Sync with garmin.SyncConfig/ClientConfig; applog becomes internal/log; the test mock moves into the garmin package as MockClient (breaking the test-only import cycle the merge created); stale test URLs and type names updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
114
backend/internal/garmin/mock.go
Normal file
114
backend/internal/garmin/mock.go
Normal file
@@ -0,0 +1,114 @@
|
||||
// MockClient support: a fake Client for tests and frontend/dev
|
||||
// work without a live Garmin account or the wrapper subprocess.
|
||||
package garmin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MockClient is a fake Client returning data supplied by the test/caller.
|
||||
type MockClient struct {
|
||||
AuthResults []AuthResult // consumed in order by Authenticate/CompleteMFA calls
|
||||
Activities []Activity
|
||||
Splits map[int64]ActivitySplits
|
||||
Details map[int64]ActivityDetails
|
||||
Workouts map[int64]Workout
|
||||
// WorkoutErrByID, if set for a given workout ID, makes GetWorkoutByID
|
||||
// return that error for that ID specifically -- independent of the
|
||||
// all-calls-fail Err field below -- so a test can simulate one
|
||||
// activity's workout fetch failing while others in the same batch
|
||||
// succeed.
|
||||
WorkoutErrByID map[int64]error
|
||||
// Delay, if set, is slept (ctx-cancellable) at the start of every
|
||||
// GetActivities call -- lets a test give sync.Service's discovering
|
||||
// phase (backfillCore/incrementalSyncCore) real wall-clock duration, so
|
||||
// a concurrent goroutine can observe Progress() mid-flight instead of
|
||||
// the call returning instantly.
|
||||
Delay time.Duration
|
||||
Err error // if set, every call returns this error
|
||||
authResultCursor int
|
||||
ClosedCalled bool
|
||||
GetActivitiesCalls int
|
||||
AuthenticateCalls int
|
||||
LastEmail string
|
||||
LastPassword string
|
||||
}
|
||||
|
||||
var _ Client = (*MockClient)(nil)
|
||||
|
||||
func (c *MockClient) nextAuthResult() AuthResult {
|
||||
if c.authResultCursor >= len(c.AuthResults) {
|
||||
return AuthResult{Status: AuthSuccess, Message: "Authenticated successfully."}
|
||||
}
|
||||
r := c.AuthResults[c.authResultCursor]
|
||||
c.authResultCursor++
|
||||
return r
|
||||
}
|
||||
|
||||
func (c *MockClient) Authenticate(ctx context.Context) (AuthResult, error) {
|
||||
c.AuthenticateCalls++
|
||||
if c.Err != nil {
|
||||
return AuthResult{}, c.Err
|
||||
}
|
||||
return c.nextAuthResult(), nil
|
||||
}
|
||||
|
||||
func (c *MockClient) CompleteMFA(ctx context.Context, code string) (AuthResult, error) {
|
||||
if c.Err != nil {
|
||||
return AuthResult{}, c.Err
|
||||
}
|
||||
return c.nextAuthResult(), nil
|
||||
}
|
||||
|
||||
func (c *MockClient) GetActivities(ctx context.Context, startDate, endDate string, limit int) ([]Activity, error) {
|
||||
c.GetActivitiesCalls++
|
||||
if c.Delay > 0 {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-time.After(c.Delay):
|
||||
}
|
||||
}
|
||||
if c.Err != nil {
|
||||
return nil, c.Err
|
||||
}
|
||||
if limit > 0 && limit < len(c.Activities) {
|
||||
return c.Activities[:limit], nil
|
||||
}
|
||||
return c.Activities, nil
|
||||
}
|
||||
|
||||
func (c *MockClient) GetActivitySplits(ctx context.Context, activityID int64) (ActivitySplits, error) {
|
||||
if c.Err != nil {
|
||||
return ActivitySplits{}, c.Err
|
||||
}
|
||||
return c.Splits[activityID], nil
|
||||
}
|
||||
|
||||
func (c *MockClient) GetActivityDetails(ctx context.Context, activityID int64) (ActivityDetails, error) {
|
||||
if c.Err != nil {
|
||||
return ActivityDetails{}, c.Err
|
||||
}
|
||||
return c.Details[activityID], nil
|
||||
}
|
||||
|
||||
func (c *MockClient) GetWorkoutByID(ctx context.Context, workoutID int64) (Workout, error) {
|
||||
if c.Err != nil {
|
||||
return Workout{}, c.Err
|
||||
}
|
||||
if err, ok := c.WorkoutErrByID[workoutID]; ok {
|
||||
return Workout{}, err
|
||||
}
|
||||
return c.Workouts[workoutID], nil
|
||||
}
|
||||
|
||||
func (c *MockClient) UpdateCredentials(email, password string) {
|
||||
c.LastEmail = email
|
||||
c.LastPassword = password
|
||||
}
|
||||
|
||||
func (c *MockClient) Close() error {
|
||||
c.ClosedCalled = true
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user