Add tests for background tasks and fail2ban client utility

- tests/test_tasks/test_blocklist_import.py: 14 tests, 96% coverage
- tests/test_tasks/test_health_check.py: 12 tests, 100% coverage
- tests/test_tasks/test_geo_cache_flush.py: 8 tests, 100% coverage
- tests/test_services/test_fail2ban_client.py: 24 new tests, 96% coverage

Total: 50 new tests (628 → 678 passing). Overall coverage 85% → 87%.
ruff, mypy --strict, tsc, and eslint all clean.
This commit is contained in:
2026-03-13 10:29:22 +01:00
parent d0b8b78d12
commit d6da81131f
5 changed files with 1010 additions and 0 deletions

View File

@@ -260,3 +260,65 @@ Reference config directory: `/home/lukas/Volume/repo/BanGUI/Docker/fail2ban-dev-
- Backend: add router integration tests for the new update fields.
- Frontend: update `ConfigPageLogPath.test.tsx` mock `JailConfig` to include `use_dns` and `prefregex`.
---
## Task 8 — Improve Test Coverage for Background Tasks and Utilities ✅ DONE
**Goal:** Raise test coverage for the background-task modules and the fail2ban client utility to ≥ 80 %, closing the critical-path gap flagged in the Step 6.2 review.
**Coverage before this task (from last full run):**
| Module | Before |
|---|---|
| `app/tasks/blocklist_import.py` | 23 % |
| `app/tasks/health_check.py` | 43 % |
| `app/tasks/geo_cache_flush.py` | 60 % |
| `app/utils/fail2ban_client.py` | 58 % |
### 8a — Tests for `blocklist_import`
Create `tests/test_tasks/test_blocklist_import.py`:
- `_run_import` happy path: mock `blocklist_service.import_all`, verify structured log emitted.
- `_run_import` exception path: simulate unexpected exception, verify `log.exception` called.
- `_apply_schedule` hourly: mock scheduler, verify `add_job` called with `"interval"` trigger and correct `hours`.
- `_apply_schedule` daily: verify `"cron"` trigger with `hour` and `minute`.
- `_apply_schedule` weekly: verify `"cron"` trigger with `day_of_week`, `hour`, `minute`.
- `_apply_schedule` replaces an existing job: confirm `remove_job` called first when job already exists.
### 8b — Tests for `health_check`
Create `tests/test_tasks/test_health_check.py`:
- `_run_probe` online status: verify `app.state.server_status` is updated correctly.
- `_run_probe` offline→online transition: verify `"fail2ban_came_online"` log event.
- `_run_probe` online→offline transition: verify `"fail2ban_went_offline"` log event.
- `_run_probe` stable online (no transition): verify no transition log events.
- `register`: verify `add_job` is called with `"interval"` trigger and initial offline status set.
### 8c — Tests for `geo_cache_flush`
Create `tests/test_tasks/test_geo_cache_flush.py`:
- `_run_flush` with dirty IPs: verify `geo_service.flush_dirty` is called and debug log emitted when count > 0.
- `_run_flush` with nothing: verify `flush_dirty` called but no debug log.
- `register`: verify `add_job` called with correct interval and stable job ID.
### 8d — Extended tests for `fail2ban_client`
Extend `tests/test_services/test_fail2ban_client.py`:
- `send()` success path: mock `run_in_executor`, verify response is returned and debug log emitted.
- `send()` `Fail2BanConnectionError`: verify exception is re-raised and warning log emitted.
- `send()` `Fail2BanProtocolError`: verify exception is re-raised and error log emitted.
- `_send_command_sync` connection closed mid-stream (empty chunk): verify `Fail2BanConnectionError`.
- `_send_command_sync` pickle parse error (bad bytes in response): verify `Fail2BanProtocolError`.
- `_coerce_command_token` for `str`, `bool`, `int`, `float`, `list`, `dict`, `set`, and a custom object (stringified).
**Result:** 50 new tests added (678 total). Coverage after:
| Module | Before | After |
|---|---|---|
| `app/tasks/blocklist_import.py` | 23 % | 96 % |
| `app/tasks/health_check.py` | 43 % | 100 % |
| `app/tasks/geo_cache_flush.py` | 60 % | 100 % |
| `app/utils/fail2ban_client.py` | 58 % | 96 % |
Overall backend coverage: 85 % → 87 %. ruff, mypy --strict, tsc, and eslint all clean.