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:
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user