"""Tests for history_sync task registration.""" from __future__ import annotations from unittest.mock import AsyncMock, MagicMock, patch from app.tasks import history_sync class TestHistorySyncTask: async def test_register_schedules_job(self) -> None: fake_scheduler = MagicMock() class FakeState: pass class FakeSettings: fail2ban_socket = "/tmp/fake.sock" app = type("FakeApp", (), {})() app.state = FakeState() app.state.scheduler = fake_scheduler app.state.settings = FakeSettings() history_sync.register(app) fake_scheduler.add_job.assert_called_once() called_args, called_kwargs = fake_scheduler.add_job.call_args assert called_kwargs["id"] == history_sync.JOB_ID assert called_kwargs["kwargs"]["settings"] is app.state.settings async def test_backfill_window_is_7_5_days(self) -> None: assert history_sync.BACKFILL_WINDOW == 648000 async def test_sync_uses_strict_since_after_restart(self) -> None: fake_app = type("FakeApp", (), {})() fake_app.state = type("FakeState", (), {})() fake_app.state.settings = type("FakeSettings", (), {})() fake_app.state.settings.fail2ban_socket = "/tmp/fake.sock" fake_app.state.settings.database_path = "/tmp/fake.db" fake_app.state.db = MagicMock() fake_app.state.db.close = AsyncMock() async def fake_get_history_page(*, db_path: str, since: int, page: int, page_size: int, **kwargs): assert since == 1001 return [], 0 async def fake_get_fail2ban_db_path(socket_path: str) -> str: return "/tmp/fake.sqlite3" with patch( "app.tasks.history_sync.open_db", new_callable=AsyncMock, return_value=fake_app.state.db, ), patch( "app.tasks.history_sync._get_last_archive_ts", new=AsyncMock(return_value=1000), ), patch( "app.tasks.history_sync.get_fail2ban_db_path", new=fake_get_fail2ban_db_path, ), patch( "app.tasks.history_sync.fail2ban_db_repo.get_history_page", new=fake_get_history_page, ): await history_sync._run_sync(fake_app)