from pathlib import Path import pytest from app.garmin.uploader import GarminUploadBlocked, GarminUploader class FakeGarmin: def __init__(self, *args, prompt_mfa=None, import_result=None, login_error=None, import_error=None, **kwargs): self.prompt_mfa = prompt_mfa self.import_result = import_result or {"activityId": 42} self.login_error = login_error self.import_error = import_error self.login_path = None def login(self, tokenstore=None): self.login_path = tokenstore if self.login_error: raise self.login_error def import_activity(self, activity_path: str): if self.import_error: raise self.import_error return self.import_result def test_successful_import_returns_activity_id(tmp_path: Path) -> None: uploader = GarminUploader( email="g@example.com", password="pw", tokenstore=tmp_path / "garmin", client_factory=lambda *a, **kw: FakeGarmin(*a, **kw, import_result={"activityId": 42}), ) result = uploader.import_fit(tmp_path / "ride.fit") assert result.status == "imported" assert result.garmin_activity_id == "42" def test_duplicate_is_terminal_success(tmp_path: Path) -> None: uploader = GarminUploader( email="g@example.com", password="pw", tokenstore=tmp_path / "garmin", client_factory=lambda *a, **kw: FakeGarmin(*a, **kw, import_error=RuntimeError("409 duplicate")), ) result = uploader.import_fit(tmp_path / "ride.fit") assert result.duplicate is True assert result.status == "duplicate" def test_mfa_without_code_is_blocked(tmp_path: Path) -> None: class MfaGarmin(FakeGarmin): def login(self, tokenstore=None): self.prompt_mfa() uploader = GarminUploader( email="g@example.com", password="pw", tokenstore=tmp_path / "garmin", client_factory=MfaGarmin, ) with pytest.raises(GarminUploadBlocked): uploader.import_fit(tmp_path / "ride.fit") def test_mfa_code_is_returned_only_to_prompt(tmp_path: Path) -> None: seen = [] class MfaGarmin(FakeGarmin): def login(self, tokenstore=None): seen.append(self.prompt_mfa()) uploader = GarminUploader( email="g@example.com", password="pw", tokenstore=tmp_path / "garmin", client_factory=MfaGarmin, ) uploader.import_fit(tmp_path / "ride.fit", mfa_code="123456") assert seen == ["123456"]