feat: Implement Garmin sync, login improvements, and utility scripts

This commit is contained in:
2025-10-11 11:56:25 -07:00
parent 56a93cd8df
commit 3819e4f5e2
921 changed files with 2058 additions and 371 deletions

View File

@@ -0,0 +1,116 @@
from unittest.mock import AsyncMock, patch
import pytest
from backend.src.schemas import GarminCredentials
from backend.src.services.garmin_activity_service import GarminActivityService
from backend.src.services.garmin_health_service import GarminHealthService
@pytest.fixture
def mock_garmin_auth_service_instance():
with patch(
'backend.src.services.garmin_activity_service.GarminAuthService'
) as MockGarminAuthService:
instance = MockGarminAuthService.return_value
yield instance
@pytest.fixture
def mock_central_db_service_instance():
with patch(
'backend.src.services.garmin_activity_service.CentralDBService'
) as MockCentralDBService:
service_instance = MockCentralDBService.return_value
yield service_instance
@pytest.fixture
def mock_garmin_client_service_instance():
with patch(
'backend.src.services.garmin_activity_service.GarminClientService'
) as MockGarminClientService:
instance = MockGarminClientService.return_value
yield instance
@pytest.mark.asyncio
async def test_garmin_activity_sync_authentication_flow(
mock_garmin_auth_service_instance,
mock_central_db_service_instance,
mock_garmin_client_service_instance
):
user_id = 1
username = "test@example.com"
password = "password123"
# Mock GarminCredentials from CentralDB
mock_credentials = GarminCredentials(
garmin_username=username,
garmin_password_plaintext=password
)
mock_central_db_service_instance.get_garmin_credentials.return_value = mock_credentials
# Mock GarminClientService authentication
mock_garmin_client_service_instance.is_authenticated.return_value = False
mock_garmin_client_service_instance.authenticate.return_value = True
# Mock GarminClientService.get_client().get_activities
mock_garmin_client_instance = AsyncMock()
mock_garmin_client_service_instance.get_client.return_value = mock_garmin_client_instance
mock_garmin_client_instance.get_activities.return_value = [] # Simulate no activities
activity_service = GarminActivityService(
garmin_client_service=mock_garmin_client_service_instance,
activity_download_service=AsyncMock(), # Mock this dependency
garmin_auth_service=mock_garmin_auth_service_instance, # Still needed for init, but methods not called
central_db_service=mock_central_db_service_instance
)
# Call sync_activities_in_background, which will trigger authentication
await activity_service.sync_activities_in_background(job_id="test_job")
# Assertions
mock_central_db_service_instance.get_garmin_credentials.assert_called_once_with(user_id)
mock_garmin_client_service_instance.update_credentials.assert_called_once_with(username, password)
mock_garmin_client_service_instance.is_authenticated.assert_called_once()
mock_garmin_client_service_instance.authenticate.assert_called_once()
mock_garmin_client_instance.get_activities.assert_called_once()
@pytest.mark.asyncio
async def test_garmin_health_sync_authentication_flow(
mock_garmin_auth_service_instance,
mock_central_db_service_instance,
mock_garmin_client_service_instance
):
user_id = 1
username = "test@example.com"
password = "password123"
# Mock GarminCredentials from CentralDB
mock_credentials = GarminCredentials(
garmin_username=username,
garmin_password_plaintext=password
)
mock_central_db_service_instance.get_garmin_credentials.return_value = mock_credentials
# Mock GarminClientService authentication
mock_garmin_client_service_instance.is_authenticated.return_value = False
mock_garmin_client_service_instance.authenticate.return_value = True
# Mock GarminClientService.get_client().get_daily_summary
mock_garmin_client_instance = AsyncMock()
mock_garmin_client_service_instance.get_client.return_value = mock_garmin_client_instance
mock_garmin_client_instance.get_daily_summary.return_value = [] # Simulate no summaries
health_service = GarminHealthService(
garmin_client_service=mock_garmin_client_service_instance,
central_db_service=mock_central_db_service_instance,
garmin_auth_service=mock_garmin_auth_service_instance # Still needed for init, but methods not called
)
# Call sync_health_metrics_in_background, which will trigger authentication
await health_service.sync_health_metrics_in_background(job_id="test_job")
# Assertions
mock_central_db_service_instance.get_garmin_credentials.assert_called_once_with(user_id)
mock_garmin_client_service_instance.update_credentials.assert_called_once_with(username, password)
mock_garmin_client_service_instance.is_authenticated.assert_called_once()
mock_garmin_client_service_instance.authenticate.assert_called_once()
mock_garmin_client_instance.get_daily_summary.assert_called_once()