76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
import json
|
|
import os
|
|
from datetime import date
|
|
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_get_last_sync_date(mock_client, temp_storage):
|
|
os.makedirs(temp_storage, exist_ok=True)
|
|
sync = GarminSync(mock_client, storage_dir=temp_storage)
|
|
|
|
# 1. No files
|
|
assert sync.get_last_sync_date() is None
|
|
|
|
# 2. Add files
|
|
today = date(2025, 12, 12)
|
|
with open(os.path.join(temp_storage, "activity_1.json"), "w") as f:
|
|
json.dump({"activityId": 1, "startTimeLocal": "2025-12-10 10:00:00"}, f)
|
|
|
|
with open(os.path.join(temp_storage, "activity_2.json"), "w") as f:
|
|
json.dump({"activityId": 2, "startTimeLocal": "2025-12-12 10:00:00"}, f)
|
|
|
|
# 3. Invalid Date
|
|
with open(os.path.join(temp_storage, "activity_bad.json"), "w") as f:
|
|
json.dump({"activityId": 3, "startTimeLocal": "invalid-date"}, f)
|
|
|
|
assert sync.get_last_sync_date() == today
|
|
|
|
def test_sync_smart_no_local(mock_client, temp_storage):
|
|
os.makedirs(temp_storage, exist_ok=True)
|
|
sync = GarminSync(mock_client, storage_dir=temp_storage)
|
|
|
|
with patch.object(sync, 'sync_activities', return_value=10) as mock_sync_act:
|
|
count = sync.sync_smart()
|
|
assert count == 10
|
|
mock_sync_act.assert_called_with(days=365)
|
|
|
|
def test_sync_smart_incremental(mock_client, temp_storage):
|
|
os.makedirs(temp_storage, exist_ok=True)
|
|
sync = GarminSync(mock_client, storage_dir=temp_storage)
|
|
|
|
# Latest is 2 days ago
|
|
mock_today = date(2025, 1, 5)
|
|
last_sync = date(2025, 1, 3)
|
|
|
|
with open(os.path.join(temp_storage, "activity_1.json"), "w") as f:
|
|
json.dump({"activityId": 1, "startTimeLocal": f"{last_sync} 10:00:00"}, f)
|
|
|
|
with patch("garmin.sync.date") as mock_date_cls:
|
|
mock_date_cls.today.return_value = mock_today
|
|
# Need to allow date constructor usage inside sync.py if used
|
|
# But Sync.py imports date, datetime separately.
|
|
|
|
# When we patch 'garmin.sync.date', we replace the class 'date' imported in that module
|
|
# So date.today() is mocked.
|
|
# But side effect: date(2025,1,5) might fail if we mocked the constructor?
|
|
# Usually today is a classmethod.
|
|
|
|
# Simpler: sync_smart calculates days = (today - latest_date).days
|
|
# If today=5th, latest=3rd. diff = 2.
|
|
|
|
with patch.object(sync, 'sync_activities', return_value=5) as mock_sync_act:
|
|
sync.sync_smart()
|
|
mock_sync_act.assert_called_with(days=2)
|