Files
go-garminconnect/internal/api/mock_server_test.go
2025-08-28 09:58:24 -07:00

197 lines
4.9 KiB
Go

package api
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"sync"
)
// MockServer simulates the Garmin Connect API
type MockServer struct {
server *httptest.Server
mu sync.Mutex
// Endpoint handlers
activitiesHandler http.HandlerFunc
activityDetailsHandler http.HandlerFunc
uploadHandler http.HandlerFunc
userHandler http.HandlerFunc
healthHandler http.HandlerFunc
authHandler http.HandlerFunc
}
// NewMockServer creates a new mock Garmin Connect server
func NewMockServer() *MockServer {
m := &MockServer{}
m.server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
m.mu.Lock()
defer m.mu.Unlock()
switch {
case strings.HasPrefix(r.URL.Path, "/activity-service/activities"):
m.handleActivities(w, r)
case strings.HasPrefix(r.URL.Path, "/activity-service/activity/"):
m.handleActivityDetails(w, r)
case strings.HasPrefix(r.URL.Path, "/upload-service/upload"):
m.handleUpload(w, r)
case strings.HasPrefix(r.URL.Path, "/user-service/user"):
m.handleUserData(w, r)
case strings.HasPrefix(r.URL.Path, "/health-service"):
m.handleHealthData(w, r)
case strings.HasPrefix(r.URL.Path, "/auth"):
m.handleAuth(w, r)
default:
http.Error(w, "Not found", http.StatusNotFound)
}
}))
return m
}
// URL returns the base URL of the mock server
func (m *MockServer) URL() string {
return m.server.URL
}
// Close shuts down the mock server
func (m *MockServer) Close() {
m.server.Close()
}
// SetActivitiesHandler sets a custom handler for activities endpoint
func (m *MockServer) SetActivitiesHandler(handler http.HandlerFunc) {
m.mu.Lock()
defer m.mu.Unlock()
m.activitiesHandler = handler
}
// SetUploadHandler sets a custom handler for upload endpoint
func (m *MockServer) SetUploadHandler(handler http.HandlerFunc) {
m.mu.Lock()
defer m.mu.Unlock()
m.uploadHandler = handler
}
// Default handler implementations would follow for each endpoint
// ...
// handleActivities is the default activities endpoint handler
func (m *MockServer) handleActivities(w http.ResponseWriter, r *http.Request) {
if m.activitiesHandler != nil {
m.activitiesHandler(w, r)
return
}
// Default implementation
activities := []ActivityResponse{
{
ActivityID: 1,
Name: "Morning Run",
StartTime: garminTime{time.Now().Add(-24 * time.Hour)},
Duration: 3600,
Distance: 10.0,
},
}
json.NewEncoder(w).Encode(ActivitiesResponse{
Activities: activities,
Pagination: Pagination{
Page: 1,
PageSize: 10,
TotalCount: 1,
},
})
}
// handleActivityDetails is the default activity details endpoint handler
func (m *MockServer) handleActivityDetails(w http.ResponseWriter, r *http.Request) {
if m.activityDetailsHandler != nil {
m.activityDetailsHandler(w, r)
return
}
// Extract activity ID from path
pathParts := strings.Split(r.URL.Path, "/")
activityID, err := strconv.ParseInt(pathParts[len(pathParts)-1], 10, 64)
if err != nil {
http.Error(w, "Invalid activity ID", http.StatusBadRequest)
return
}
activity := ActivityDetailResponse{
ActivityResponse: ActivityResponse{
ActivityID: activityID,
Name: "Mock Activity",
Type: "RUNNING",
StartTime: garminTime{time.Now().Add(-24 * time.Hour)},
Duration: 3600,
Distance: 10.0,
},
Calories: 500,
AverageHR: 150,
MaxHR: 170,
ElevationGain: 100,
}
json.NewEncoder(w).Encode(activity)
}
// handleUpload is the default activity upload handler
func (m *MockServer) handleUpload(w http.ResponseWriter, r *http.Request) {
if m.uploadHandler != nil {
m.uploadHandler(w, r)
return
}
// Simulate successful upload
response := map[string]interface{}{
"activityId": 12345,
}
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(response)
}
// handleUserData is the default user data handler
func (m *MockServer) handleUserData(w http.ResponseWriter, r *http.Request) {
if m.userHandler != nil {
m.userHandler(w, r)
return
}
// Return mock user data
user := map[string]interface{}{
"displayName": "Mock User",
"email": "mock@example.com",
}
json.NewEncoder(w).Encode(user)
}
// handleHealthData is the default health data handler
func (m *MockServer) handleHealthData(w http.ResponseWriter, r *http.Request) {
if m.healthHandler != nil {
m.healthHandler(w, r)
return
}
// Return mock health data
data := map[string]interface{}{
"bodyBattery": 90,
"stress": 35,
"sleep": map[string]interface{}{
"duration": 480,
"quality": 85,
},
}
json.NewEncoder(w).Encode(data)
}
// handleAuth is the default authentication handler
func (m *MockServer) handleAuth(w http.ResponseWriter, r *http.Request) {
if m.authHandler != nil {
m.authHandler(w, r)
return
}
// Simulate successful authentication
response := map[string]interface{}{
"token": "mock-token-123",
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}