from datetime import date from unittest.mock import AsyncMock, patch import pytest from backend.src.main import app from backend.src.schemas import User from fastapi import HTTPException from httpx import AsyncClient @pytest.fixture def mock_garmin_activity_service(): with patch('backend.src.api.garmin_sync.GarminActivityService') as MockGarminActivityService: service_instance = MockGarminActivityService.return_value yield service_instance @pytest.fixture def mock_get_current_user(): with patch('backend.src.api.garmin_sync.get_current_user') as mock_current_user: mock_current_user.return_value = User(id=1, name="Test User", email="test@example.com") yield mock_current_user @pytest.mark.asyncio async def test_trigger_garmin_activity_sync_success(mock_garmin_activity_service, mock_get_current_user): mock_garmin_activity_service.sync_activities_in_background = AsyncMock() mock_garmin_activity_service.sync_activities_in_background.return_value = None async with AsyncClient(app=app, base_url="http://test") as client: response = await client.post( "/api/sync/garmin/activities", json={ "force_resync": False, "start_date": "2023-01-01", "end_date": "2023-01-31" } ) assert response.status_code == 202 response_json = response.json() assert "job_id" in response_json assert "status" in response_json assert response_json["status"] == "pending" mock_garmin_activity_service.sync_activities_in_background.assert_called_once() args, kwargs = mock_garmin_activity_service.sync_activities_in_background.call_args assert not args[1] # force_resync assert args[2] == date(2023, 1, 1) # start_date assert args[3] == date(2023, 1, 31) # end_date @pytest.mark.asyncio async def test_trigger_garmin_activity_sync_no_dates(mock_garmin_activity_service, mock_get_current_user): mock_garmin_activity_service.sync_activities_in_background = AsyncMock() mock_garmin_activity_service.sync_activities_in_background.return_value = None async with AsyncClient(app=app, base_url="http://test") as client: response = await client.post( "/api/sync/garmin/activities", json={} ) assert response.status_code == 202 response_json = response.json() assert "job_id" in response_json assert "status" in response_json assert response_json["status"] == "pending" mock_garmin_activity_service.sync_activities_in_background.assert_called_once() args, kwargs = mock_garmin_activity_service.sync_activities_in_background.call_args assert not args[1] # force_resync assert args[2] is None # start_date assert args[3] is None # end_date @pytest.mark.asyncio async def test_trigger_garmin_activity_sync_unauthorized(): with patch('backend.src.api.garmin_sync.get_current_user', side_effect=HTTPException(status_code=401)): async with AsyncClient(app=app, base_url="http://test") as client: response = await client.post( "/api/sync/garmin/activities", json={} ) assert response.status_code == 401 assert response.json() == {"detail": "Not Authenticated"} # Default FastAPI 401 detail