errors
This commit is contained in:
@@ -6,10 +6,11 @@ from sqlalchemy import select
|
||||
from app.db.models import ActivityStatus, HealthState, SyncRun, SyncRunStatus, SyncUser
|
||||
from app.db.repositories import UserRepository
|
||||
from app.garmin.uploader import UploadResult
|
||||
from app.mywhoosh.client import MyWhooshDeviceConflictError
|
||||
from app.mywhoosh.models import MyWhooshActivity
|
||||
from app.sync.manager import SyncManager
|
||||
from tests.sync.conftest import FakeFitConverter, _create_user
|
||||
from tests.sync.fakes import FakeMyWhooshClient
|
||||
from tests.sync.fakes import FakeGarminUploader, FakeMyWhooshClient
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -188,6 +189,46 @@ async def test_garmin_action_required_cleared_after_successful_import(
|
||||
assert reloaded.health_state == HealthState.HEALTHY
|
||||
|
||||
|
||||
class DeviceConflictMyWhooshClient:
|
||||
"""Fake MyWhoosh client that always raises MyWhooshDeviceConflictError
|
||||
from list_activities, simulating MyWhoosh's "already logged in from
|
||||
another device" response."""
|
||||
|
||||
async def list_activities(self, email: str, password: str):
|
||||
raise MyWhooshDeviceConflictError("You are already logged in from another device.")
|
||||
|
||||
async def download_fit(self, activity_file_id: str, email: str, password: str) -> bytes:
|
||||
raise AssertionError("download_fit should not be reached in this test")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_device_conflict_sets_distinct_action_reason(seeded_user: SyncUser, session_factory, cipher, settings) -> None:
|
||||
"""A MyWhoosh device-conflict response must be distinguishable in the UI
|
||||
from a generic auth failure, so users get an actionable hint instead of
|
||||
being told to re-check their password."""
|
||||
mywhoosh = DeviceConflictMyWhooshClient()
|
||||
converter = FakeFitConverter()
|
||||
garmin = FakeGarminUploader()
|
||||
manager = SyncManager(
|
||||
session_factory=session_factory,
|
||||
credential_cipher=cipher,
|
||||
settings=settings,
|
||||
mywhoosh_factory=lambda token_store: mywhoosh,
|
||||
garmin_factory=lambda email, password, tokenstore: garmin,
|
||||
fit_converter=converter,
|
||||
)
|
||||
|
||||
outcome = await manager.sync_user(seeded_user.id)
|
||||
assert outcome.status == "failed"
|
||||
assert "another device" in outcome.message
|
||||
|
||||
with session_factory() as session:
|
||||
reloaded = UserRepository(session).get(seeded_user.id)
|
||||
assert reloaded.action_reason == "mywhoosh_device_conflict"
|
||||
assert reloaded.mywhoosh_state == "device_conflict"
|
||||
assert reloaded.health_state == HealthState.ACTION_REQUIRED
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mfa_code_reaches_real_garmin_uploader_via_sync_manager(
|
||||
session_factory, cipher, settings, seeded_user: SyncUser
|
||||
|
||||
Reference in New Issue
Block a user