- Add configuration docs for database and rate limiting - Remove completed tasks from tracking list - Update testing requirements with new test patterns - Enhance web development docs with frontend guidelines - Expand page loading and ban records e2e test coverage
3.5 KiB
Testing Requirements
Coverage Threshold
- Minimum: 80% line coverage for all backend code
- Critical paths (auth, banning, scheduling, API endpoints): 100%
CI Enforcement
.github/workflows/ci.yml runs pytest with --cov-fail-under=80. Build fails if coverage drops below threshold.
Running Tests Locally
cd backend
pytest --cov=app --cov-report=term-missing
Coverage Reports
- Terminal:
--cov-report=term-missing - HTML:
--cov-report=html(output inhtmlcov/)
Coverage Badge
Add to README once CI runs successfully:
[](https://codecov.io/gh/<owner>/BanGUI)
Requires codecov.io integration with repository.
Writing Tests
- Follow pattern:
test_<unit>_<scenario>_<expected> - Mock external dependencies (fail2ban socket, aiohttp calls)
- Test happy path AND error/edge cases
- See
Docs/Backend-Development.md §9for detailed testing guide
E2E Testing
An end-to-end test suite using Robot Framework with the Browser library (Playwright-backed) exercises the full running stack: frontend → backend → fail2ban → database.
Running E2E Tests
make e2e
Requires:
BANGUI_SESSION_SECRETenv var must be set (see Backend-Development.md for setup)- Stack must be startable via
make up(Docker/Podman + compose installed) rfbrowser initis run automatically by thee2etarget (Playwright browsers downloaded on first run; re-run afterrobotframework-browserversion changes)
HTML Report
After a run, open e2e/results/report.html in a browser to view the detailed HTML report with screenshots on failure.
Writing New E2E Tests
Place new .robot files in e2e/tests/. Use e2e/resources/common.resource for shared variables and setup/teardown, and e2e/resources/auth.resource for the Login As Admin keyword.
E2E-3 — Ban Pipeline Timing
Test E2E-3 (e2e/tests/02_ban_records.robot: Simulated Failed Logins Appear As Ban Records) exercises the full ban pipeline:
simulate_failed_logins.sh → fail2ban log scan → ban recorded in fail2ban DB
→ backend polls socket (on-demand, no push) → /api/bans/active
→ history_sync archive (every 300 s) → /api/history
Key timing facts:
- fail2ban (
manual-Jail,backend=polling) re-readsauth.logon its own interval, not event-driven. - maxretry=3 means a ban triggers after the 3rd matching line.
simulate_failed_logins.shwrites 5 lines to ensure the threshold is crossed. - 15 s sleep in the test gives fail2ban time to detect and record the ban before the first assertion. This is a heuristic — the actual polling interval depends on fail2ban's internal cycle.
- history_sync runs every 300 s (
HISTORY_SYNC_INTERVALinbackend/app/tasks/history_sync.py). The History page reads from the archive DB, so it may lag up to 300 s behind real-time. The E2E test usesGET /api/bans/active(direct socket query) for the API assertion to avoid this lag. - Pagination: the History page paginates results. Use
?page_size=500to push the test IP onto the first page, or assert via the API.
If the test fails at Step 2 (no ban detected via API) but check_ban_status.sh shows the IP is banned inside the container, the backend-to-fail2ban socket path is broken. If check_ban_status.sh also shows no ban, the log volume mapping is wrong (fail2ban is not reading the file simulate_failed_logins.sh writes to).