feat: add operational sync controls

This commit is contained in:
Bastian Wagner
2026-08-15 16:24:11 +02:00
parent fd50bbbab7
commit c2f13611b9
9 changed files with 305 additions and 11 deletions

View File

@@ -45,7 +45,7 @@ def sync_run_repository(db_session: Session) -> SyncRunRepository:
@pytest.fixture
def client(tmp_path: Path) -> TestClient:
def app(tmp_path: Path):
settings = Settings(
ADMIN_PASSWORD="admin-secret",
SECRET_KEY="0123456789abcdef0123456789abcdef",
@@ -54,11 +54,63 @@ def client(tmp_path: Path) -> TestClient:
DATABASE_URL=f"sqlite:///{tmp_path / 'app.db'}",
SYNC_INTERVAL_MINUTES=5,
)
app = create_app(settings)
application = create_app(settings)
try:
yield TestClient(app)
yield application
finally:
app.state.db_engine.dispose()
application.state.db_engine.dispose()
@pytest.fixture
def client(app) -> TestClient:
return TestClient(app)
def _extract_csrf(html: str) -> str:
marker = 'name="csrf_token" value="'
start = html.index(marker) + len(marker)
end = html.index('"', start)
return html[start:end]
class FakeSyncManager:
def __init__(self) -> None:
self.user_calls: list[int] = []
self.all_calls = 0
self.raise_already_running = False
self.mfa_calls: list[tuple[int, str]] = []
async def sync_user(self, user_id: int, mfa_code: str | None = None):
if self.raise_already_running:
from app.sync.manager import SyncAlreadyRunning
raise SyncAlreadyRunning(f"sync already running for user {user_id}")
self.user_calls.append(user_id)
if mfa_code is not None:
self.mfa_calls.append((user_id, mfa_code))
from app.sync.states import SyncOutcome
return SyncOutcome(user_id=user_id, status="success", discovered=0, imported=0, skipped=0, failed=0)
async def sync_all_enabled(self):
self.all_calls += 1
return []
@pytest.fixture
def fake_sync_manager() -> FakeSyncManager:
return FakeSyncManager()
@pytest.fixture
def authenticated_client(app, client: TestClient, fake_sync_manager: FakeSyncManager) -> TestClient:
page = client.get("/login")
csrf = _extract_csrf(page.text)
response = client.post("/login", data={"password": "admin-secret", "csrf_token": csrf}, follow_redirects=False)
assert response.status_code == 303
app.state.sync_manager = fake_sync_manager
client.csrf_token = csrf
return client
@pytest.fixture