import pytest from unittest.mock import MagicMock, patch from src.services.garmin.client import GarminClient from garth.exc import GarthException from sqlalchemy.orm import Session def test_login_mfa_flow_crash(): # Mock DB session mock_db = MagicMock(spec=Session) mock_db.query.return_value.filter_by.return_value.first.return_value = None # Mock garth with patch('src.services.garmin.auth.garth') as mock_garth: # 1. Setup mock to raise "needs-mfa" exception mock_garth.login.side_effect = GarthException("Error: needs-mfa") # 2. Setup mock client state that might be missing attributes # This simulates a potential state where mfa_state is malformed or client is missing mock_garth.client = MagicMock() # Case A: mfa_state is None mock_garth.client.mfa_state = None client = GarminClient("testuser", "testpass") # Expectation: calling login should NOT raise an unhandled exception # It should catch GarthException and try to handle MFA. # If it crashes here, we found the bug. try: status = client.login(mock_db) print(f"Login status: {status}") except Exception as e: pytest.fail(f"Login raised unhandled exception: {e}") def test_login_mfa_flow_success_structure(): # Test with CORRECT structure to verify what it expects mock_db = MagicMock(spec=Session) with patch('src.services.garmin.auth.garth') as mock_garth: # Setup expected structure mock_client_instance = MagicMock() mock_client_instance._session.cookies.get_dict.return_value = {"cookie": "yum"} # Link sess property to _session to match garth.Client behavior or ensure attribute exists mock_client_instance.sess = mock_client_instance._session mock_client_instance.domain = "garmin.com" mock_client_instance.last_resp.text = "success" mock_client_instance.last_resp.url = "http://garmin.com" # Mock tuple return for success flow mock_garth.login.return_value = ("needs_mfa", { "signin_params": {"csrf": "token"}, "mfa": "state", "client": mock_client_instance }) mock_garth.login.side_effect = None mock_garth.client.mfa_state = { "signin_params": {"csrf": "token"}, "client": mock_client_instance } client = GarminClient("testuser", "testpass") status = client.login(mock_db) assert status == "mfa_required"