127 lines
4.6 KiB
Python
127 lines
4.6 KiB
Python
import json
|
|
import os
|
|
from datetime import date, timedelta
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from garmin.sync import GarminSync
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_client():
|
|
return MagicMock()
|
|
|
|
@pytest.fixture
|
|
def temp_storage(tmp_path):
|
|
return str(tmp_path / "data")
|
|
|
|
def test_dashboard_stats_vo2max_fallback(mock_client, temp_storage):
|
|
# Coverage for sync.py VO2Max logic
|
|
fixed_today = date(2026, 1, 1)
|
|
os.makedirs(temp_storage, exist_ok=True)
|
|
|
|
# 1. Running with VO2Max (Should be preferred)
|
|
with open(os.path.join(temp_storage, "activity_run.json"), "w") as f:
|
|
json.dump({
|
|
"activityId": 1,
|
|
"startTimeLocal": fixed_today.strftime("%Y-%m-%d %H:%M:%S"),
|
|
"activityType": {"typeKey": "running"},
|
|
"vo2MaxValue": 55
|
|
}, f)
|
|
|
|
with patch("garmin.sync.date") as mock_date:
|
|
mock_date.today.return_value = fixed_today
|
|
sync = GarminSync(mock_client, storage_dir=temp_storage)
|
|
stats = sync.get_dashboard_stats()
|
|
assert stats["vo2_max"] == 55
|
|
|
|
# 2. Cycling Only (Should pick cycling)
|
|
# Remove run
|
|
os.remove(os.path.join(temp_storage, "activity_run.json"))
|
|
with open(os.path.join(temp_storage, "activity_cycle.json"), "w") as f:
|
|
json.dump({
|
|
"activityId": 2,
|
|
"startTimeLocal": fixed_today.strftime("%Y-%m-%d %H:%M:%S"),
|
|
"activityType": {"typeKey": "cycling"},
|
|
"vo2MaxCyclingValue": 45
|
|
}, f)
|
|
|
|
with patch("garmin.sync.date") as mock_date:
|
|
mock_date.today.return_value = fixed_today
|
|
sync = GarminSync(mock_client, storage_dir=temp_storage)
|
|
stats = sync.get_dashboard_stats()
|
|
assert stats["vo2_max"] == 45
|
|
|
|
# 3. Mixed (Running has no VO2, Cycling does -> Should fallback to Cycling)
|
|
with open(os.path.join(temp_storage, "activity_run_no_vo2.json"), "w") as f:
|
|
json.dump({
|
|
"activityId": 3,
|
|
"startTimeLocal": (fixed_today + timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S"), # Newer
|
|
"activityType": {"typeKey": "running"}
|
|
# No vo2MaxValue
|
|
}, f)
|
|
|
|
with patch("garmin.sync.date") as mock_date:
|
|
mock_date.today.return_value = fixed_today
|
|
sync = GarminSync(mock_client, storage_dir=temp_storage)
|
|
stats = sync.get_dashboard_stats()
|
|
assert stats["vo2_max"] == 45 # From cycling
|
|
|
|
def test_dashboard_stats_vo2max_deep_scan(mock_client, temp_storage):
|
|
# Coverage for sync.py: VO2Max found outside top 5 (deep scan)
|
|
fixed_today = date(2026, 1, 1)
|
|
os.makedirs(temp_storage, exist_ok=True)
|
|
|
|
# Create 6 activities. Top 5 have no VO2. 6th has it.
|
|
for i in range(6):
|
|
with open(os.path.join(temp_storage, f"activity_{i}.json"), "w") as f:
|
|
# i=0 is newest. i=5 is oldest.
|
|
# We want headers to be sorted by date desc.
|
|
# So activity_0 is today. activity_5 is today-5.
|
|
act_date = fixed_today - timedelta(days=i)
|
|
|
|
data = {
|
|
"activityId": i,
|
|
"startTimeLocal": act_date.strftime("%Y-%m-%d %H:%M:%S"),
|
|
"activityType": {"typeKey": "running"},
|
|
"duration": 1800
|
|
}
|
|
|
|
if i == 5:
|
|
# The 6th activity (oldest in this set) has the VO2
|
|
data["vo2MaxValue"] = 52
|
|
|
|
json.dump(data, f)
|
|
|
|
with patch("garmin.sync.date") as mock_date:
|
|
mock_date.today.return_value = fixed_today
|
|
sync = GarminSync(mock_client, storage_dir=temp_storage)
|
|
stats = sync.get_dashboard_stats()
|
|
assert stats["vo2_max"] == 52
|
|
|
|
def test_dashboard_stats_vo2max_cycling_deep_scan(mock_client, temp_storage):
|
|
# Coverage for sync.py: Cycling VO2Max found outside top 5
|
|
fixed_today = date(2026, 1, 1)
|
|
os.makedirs(temp_storage, exist_ok=True)
|
|
|
|
for i in range(6):
|
|
with open(os.path.join(temp_storage, f"activity_{i}.json"), "w") as f:
|
|
act_date = fixed_today - timedelta(days=i)
|
|
data = {
|
|
"activityId": i,
|
|
"startTimeLocal": act_date.strftime("%Y-%m-%d %H:%M:%S"),
|
|
"activityType": {"typeKey": "cycling"},
|
|
"duration": 1800
|
|
}
|
|
if i == 5:
|
|
# The 6th activity
|
|
data["vo2MaxCyclingValue"] = 48
|
|
json.dump(data, f)
|
|
|
|
with patch("garmin.sync.date") as mock_date:
|
|
mock_date.today.return_value = fixed_today
|
|
sync = GarminSync(mock_client, storage_dir=temp_storage)
|
|
stats = sync.get_dashboard_stats()
|
|
assert stats["vo2_max"] == 48
|