- Docs/Tasks.md: document 122 E2E test failures (fail2ban missing) - e2e/proxy_server.py: add HTTP proxy for frontend dev server - e2e/resources/common.resource: update test resource
2283 lines
69 KiB
Markdown
2283 lines
69 KiB
Markdown
# E2E Test Failure Tasks
|
|
|
|
> Generated from Robot Framework test run on 2026-06-21.
|
|
> **Overall Result:** 123 tests, 0 passed, 122 failed, 1 skipped.
|
|
> **Root Cause:** Backend health check returns HTTP 503 because fail2ban is not installed/running (`ModuleNotFoundError: No module named 'fail2ban'`). All suites fail at `Suite Setup` → `Wait For Backend Health`.
|
|
|
|
---
|
|
|
|
## Task: Fix E2E Suite Setup — Backend Health Check
|
|
|
|
**Problem:** Every test suite fails during `Suite Setup` because `Wait For Backend Health` in `e2e/resources/common.resource` polls `GET /api/v1/health` and expects HTTP 200. The backend returns HTTP 503 with body `{"status":"unavailable","fail2ban":"offline","database":"ok","scheduler":"running","cache":"initialised"}`.
|
|
|
|
**Step That Fails:** `Suite Setup` → `Wait For Backend Health` keyword (line 24 in `common.resource`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/resources/common.resource` — `Wait For Backend Health` keyword
|
|
- `backend/app/routers/health.py` — health endpoint logic
|
|
- `backend/app/utils/fail2ban_client.py` — fail2ban module import
|
|
- `Docker/compose.debug.yml` — how fail2ban is wired in the Docker stack
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Requires: stack up (make up)"
|
|
- `Docs/Deployment.md` — fail2ban dependency setup
|
|
- `Makefile` — `make e2e` target
|
|
|
|
**Expected Behavior:** Either:
|
|
1. The health check accepts 503 as "backend is up but degraded" and proceeds with tests, OR
|
|
2. fail2ban is installed and running so health returns 200.
|
|
|
|
---
|
|
|
|
## Task: 01 Setup And Auth — Setup Page Renders All Form Fields
|
|
|
|
**Test:** `Setup Page Renders All Form Fields`
|
|
**Suite:** `01_setup_and_auth.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`) — backend never becomes healthy within 120s timeout.
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/01_setup_and_auth.robot`
|
|
- `e2e/resources/common.resource`
|
|
- `frontend/src/pages/SetupPage.tsx` (or equivalent setup page component)
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — Setup wizard feature coverage
|
|
- `Docs/Features.md` — Setup wizard form fields, password strength, validation
|
|
|
|
**Expected Behavior:** Setup page loads with all required form fields visible (Master Password, Confirm Password, Database Path, fail2ban Socket Path, Timezone, Session Duration, Submit button).
|
|
|
|
---
|
|
|
|
## Task: 01 Setup And Auth — Password Strength Indicator Updates On Input
|
|
|
|
**Test:** `Password Strength Indicator Updates On Input`
|
|
**Suite:** `01_setup_and_auth.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/01_setup_and_auth.robot`
|
|
- `frontend/src/components/PasswordStrengthIndicator.tsx` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Password strength indicator behavior
|
|
|
|
**Expected Behavior:** Four-segment strength bar updates dynamically as user types password. Weak password shows 1 segment, strong password shows 4 segments.
|
|
|
|
---
|
|
|
|
## Task: 01 Setup And Auth — Password Mismatch Shows Validation Error
|
|
|
|
**Test:** `Password Mismatch Shows Validation Error`
|
|
**Suite:** `01_setup_and_auth.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/01_setup_and_auth.robot`
|
|
- `frontend/src/pages/SetupPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Setup form validation
|
|
|
|
**Expected Behavior:** Submitting with non-matching passwords surfaces an error on the Confirm Password field.
|
|
|
|
---
|
|
|
|
## Task: 01 Setup And Auth — Empty Required Fields Show Validation Errors
|
|
|
|
**Test:** `Empty Required Fields Show Validation Errors`
|
|
**Suite:** `01_setup_and_auth.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/01_setup_and_auth.robot`
|
|
- `frontend/src/pages/SetupPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Required field validation
|
|
|
|
**Expected Behavior:** Submitting with blank required fields shows field-level error messages for each empty required input.
|
|
|
|
---
|
|
|
|
## Task: 01 Setup And Auth — Invalid Session Duration Shows Validation Error
|
|
|
|
**Test:** `Invalid Session Duration Shows Validation Error`
|
|
**Suite:** `01_setup_and_auth.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/01_setup_and_auth.robot`
|
|
- `frontend/src/pages/SetupPage.tsx`
|
|
- `backend/app/models/request.py` — session duration validation
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Session duration validation rules
|
|
|
|
**Expected Behavior:** Submitting with an invalid session duration (e.g., negative, zero, or non-numeric) shows a validation error.
|
|
|
|
---
|
|
|
|
## Task: 01 Setup And Auth — Incomplete Password Shows Complexity Error
|
|
|
|
**Test:** `Incomplete Password Shows Complexity Error`
|
|
**Suite:** `01_setup_and_auth.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/01_setup_and_auth.robot`
|
|
- `frontend/src/pages/SetupPage.tsx`
|
|
- `frontend/src/utils/passwordValidation.ts` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Password complexity requirements
|
|
|
|
**Expected Behavior:** Submitting a password that does not meet complexity rules (length, special chars, etc.) shows a complexity error message.
|
|
|
|
---
|
|
|
|
## Task: 01 Setup And Auth — Setup Completes Successfully And Redirects To Login
|
|
|
|
**Test:** `Setup Completes Successfully And Redirects To Login`
|
|
**Suite:** `01_setup_and_auth.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/01_setup_and_auth.robot`
|
|
- `frontend/src/pages/SetupPage.tsx`
|
|
- `backend/app/routers/setup.py` — setup completion endpoint
|
|
- `backend/app/services/setup_service.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Setup completion flow
|
|
- `e2e/Instructions.md` — Setup wizard full submit
|
|
|
|
**Expected Behavior:** Filling all required fields with valid data and submitting completes setup, creates the admin user, initializes the database, and redirects to `/login`.
|
|
|
|
---
|
|
|
|
## Task: 02 Ban Records — Simulated Failed Logins Appear As Ban Records
|
|
|
|
**Test:** `Simulated Failed Logins Appear As Ban Records`
|
|
**Suite:** `02_ban_records.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
**Specific Error:** `'' does not contain '192.168.100.99'` (from earlier partial run before backend was fully down).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_ban_records.robot`
|
|
- `backend/app/routers/bans.py` — ban records endpoint
|
|
- `backend/app/services/ban_service.py`
|
|
- `Docker/simulate_failed_logins.sh` — simulation script
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "end-to-end ban pipeline: fail2ban log → history"
|
|
- `Docs/Features.md` — Ban pipeline flow
|
|
|
|
**Expected Behavior:** Simulating failed SSH logins triggers fail2ban to ban the IP, and the banned IP appears in the dashboard/history within a reasonable time.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Login Page Renders Password Input
|
|
|
|
**Test:** `Login Page Renders Password Input`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `frontend/src/pages/LoginPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — Login page feature coverage
|
|
- `Docs/Features.md` — Login page UI
|
|
|
|
**Expected Behavior:** Login page shows a single password input field (no username field) and a submit button.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Login Page Has No Username Field
|
|
|
|
**Test:** `Login Page Has No Username Field`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `frontend/src/pages/LoginPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Login page must NOT ask for a username"
|
|
|
|
**Expected Behavior:** The login page does NOT contain a username/email input field. Only password is required.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Login With Wrong Password Shows Error
|
|
|
|
**Test:** `Login With Wrong Password Shows Error`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `frontend/src/pages/LoginPage.tsx`
|
|
- `backend/app/routers/auth.py` — login endpoint
|
|
- `backend/app/services/auth_service.py`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "wrong password" test case
|
|
|
|
**Expected Behavior:** Submitting an incorrect password displays an error message (e.g., "Invalid credentials") without revealing whether the user exists.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Login Rate Limits After Multiple Failures
|
|
|
|
**Test:** `Login Rate Limits After Multiple Failures`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `backend/app/routers/auth.py` — rate limiting
|
|
- `backend/app/middleware/rate_limit.py` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Per-IP rate limit trial"
|
|
- `Docs/Security.md` — Rate limiting rules
|
|
|
|
**Expected Behavior:** After 5 failed login attempts from the same IP within 60 seconds, subsequent attempts receive HTTP 429 Too Many Requests.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Session Endpoint Returns 401 Without Cookie
|
|
|
|
**Test:** `Session Endpoint Returns 401 Without Cookie`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `backend/app/routers/auth.py` — session validation endpoint
|
|
- `backend/app/middleware/session.py` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "session validation 401"
|
|
|
|
**Expected Behavior:** Calling `GET /api/v1/auth/session` without a valid session cookie returns HTTP 401 Unauthorized.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Direct Access To Protected Route Redirects To Login
|
|
|
|
**Test:** `Direct Access To Protected Route Redirects To Login`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `frontend/src/App.tsx` — route guards
|
|
- `frontend/src/components/ProtectedRoute.tsx` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Route protection
|
|
|
|
**Expected Behavior:** Navigating directly to a protected route (e.g., `/dashboard`) without being logged in redirects to `/login`.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Session Validation 401 On Mount Redirects To Login
|
|
|
|
**Test:** `Session Validation 401 On Mount Redirects To Login`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `frontend/src/hooks/useSession.ts` (or equivalent)
|
|
- `frontend/src/components/ProtectedRoute.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "When the backend session check returns 401, the UI redirects"
|
|
|
|
**Expected Behavior:** When the frontend mounts and the session validation API returns 401, the user is redirected to the login page.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Logout Clears Session
|
|
|
|
**Test:** `Logout Clears Session`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `frontend/src/components/Sidebar.tsx` — logout button
|
|
- `backend/app/routers/auth.py` — logout endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Clicking the Sign Out button clears the session"
|
|
|
|
**Expected Behavior:** Clicking "Sign Out" clears the session cookie and invalidates the session on the backend.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — After Logout Protected Pages Redirect To Login
|
|
|
|
**Test:** `After Logout Protected Pages Redirect To Login`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `frontend/src/App.tsx` — route guards
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — Post-logout behavior
|
|
|
|
**Expected Behavior:** After logging out, attempting to navigate to any protected page redirects to `/login`.
|
|
|
|
---
|
|
|
|
## Task: 02 Login — Login Preserves Originally Requested Page Via Next Parameter
|
|
|
|
**Test:** `Login Preserves Originally Requested Page Via Next Parameter`
|
|
**Suite:** `02_login.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/02_login.robot`
|
|
- `frontend/src/pages/LoginPage.tsx` — `next` query param handling
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "After successful login, user is redirected to the originally requested page"
|
|
|
|
**Expected Behavior:** If an unauthenticated user tries to access `/jails`, they are redirected to `/login?next=/jails`. After successful login, they are redirected to `/jails`.
|
|
|
|
---
|
|
|
|
## Task: 03 Blocklist Import — Manual Blocklist Import Completes Without Error
|
|
|
|
**Test:** `Manual Blocklist Import Completes Without Error`
|
|
**Suite:** `03_blocklist_import.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
**Specific Error:** `Url: http://localhost:8000/api/v1/blocklists Expected status: 401 != 200`
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_blocklist_import.robot`
|
|
- `backend/app/routers/blocklists.py` — blocklist import endpoint
|
|
- `backend/app/services/blocklist_service.py`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "blocklist manual import via UI"
|
|
- `Docs/Features.md` — Blocklist importer
|
|
|
|
**Expected Behavior:** A logged-in admin can trigger a manual blocklist import via the UI/API, and it completes without errors. The endpoint should return 200 (not 401, which implies auth/session issue).
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Page Renders Status Bar
|
|
|
|
**Test:** `Dashboard Page Renders Status Bar`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `frontend/src/pages/DashboardPage.tsx`
|
|
- `backend/app/routers/dashboard.py` — status endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "status bar, time-range presets, data-source badges"
|
|
- `Docs/Features.md` — Dashboard overview
|
|
|
|
**Expected Behavior:** The dashboard page renders a status bar showing fail2ban server status (online/offline), version, and other key metrics.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Ban List Renders Columns
|
|
|
|
**Test:** `Dashboard Ban List Renders Columns`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `frontend/src/components/BanList.tsx` (or equivalent)
|
|
- `backend/app/routers/dashboard.py` — bans endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Dashboard ban list table
|
|
|
|
**Expected Behavior:** The ban list table contains expected columns: IP Address, Country, Banned At, Expires At, Jail, Actions.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Time Range 24h Shows Live Source
|
|
|
|
**Test:** `Dashboard Time Range 24h Shows Live Source`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `frontend/src/pages/DashboardPage.tsx` — time range selector
|
|
- `backend/app/routers/dashboard.py` — bans endpoint with range filter
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Selecting Last 24 hours shows Live source badge"
|
|
|
|
**Expected Behavior:** Selecting "Last 24 hours" from the time range dropdown shows a "Live" data source badge, indicating data comes directly from fail2ban.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Time Range 7d Shows Archive Source
|
|
|
|
**Test:** `Dashboard Time Range 7d Shows Archive Source`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `frontend/src/pages/DashboardPage.tsx`
|
|
- `backend/app/routers/dashboard.py`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Selecting Last 7 days shows Archive source badge"
|
|
|
|
**Expected Behavior:** Selecting "Last 7 days" shows an "Archive" data source badge, indicating data comes from the SQLite archive.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Time Range 30d Shows Archive Source
|
|
|
|
**Test:** `Dashboard Time Range 30d Shows Archive Source`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `frontend/src/pages/DashboardPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Selecting Last 30 days shows Archive source badge"
|
|
|
|
**Expected Behavior:** Selecting "Last 30 days" shows an "Archive" data source badge.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Time Range 365d Shows Archive Source
|
|
|
|
**Test:** `Dashboard Time Range 365d Shows Archive Source`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `frontend/src/pages/DashboardPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Selecting Last 365 days shows Archive source badge"
|
|
|
|
**Expected Behavior:** Selecting "Last 365 days" shows an "Archive" data source badge.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Bans Endpoint Returns Expected Shape
|
|
|
|
**Test:** `Dashboard Bans Endpoint Returns Expected Shape`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `backend/app/routers/dashboard.py` — `GET /api/v1/dashboard/bans`
|
|
- `backend/app/models/response.py` — ban response schema
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Dashboard bans endpoint contract
|
|
|
|
**Expected Behavior:** `GET /api/v1/dashboard/bans?range=24h&page=1&page_size=100` returns a paginated response with `items`, `total`, `page`, `page_size` fields, and each item has `ip`, `country`, `banned_at`, `expires_at`, `jail`.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Status Endpoint Returns Version
|
|
|
|
**Test:** `Dashboard Status Endpoint Returns Version`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `backend/app/routers/dashboard.py` — `GET /api/v1/dashboard/status`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Dashboard status endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/dashboard/status` returns JSON containing `version`, `online`, `jails_count`, and other status fields.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Bans By Country Endpoint
|
|
|
|
**Test:** `Dashboard Bans By Country Endpoint`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `backend/app/routers/dashboard.py` — `GET /api/v1/dashboard/bans/by-country`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Geo aggregation endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/dashboard/bans/by-country?range=24h` returns a list of `{country_code, country_name, count}` objects.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Bans Trend Endpoint
|
|
|
|
**Test:** `Dashboard Bans Trend Endpoint`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `backend/app/routers/dashboard.py` — `GET /api/v1/dashboard/bans/trend`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Trend endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/dashboard/bans/trend?range=24h` returns time-series data for chart rendering.
|
|
|
|
---
|
|
|
|
## Task: 03 Dashboard — Dashboard Bans By Jail Endpoint
|
|
|
|
**Test:** `Dashboard Bans By Jail Endpoint`
|
|
**Suite:** `03_dashboard.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/03_dashboard.robot`
|
|
- `backend/app/routers/dashboard.py` — jail aggregation endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jail aggregation endpoint
|
|
|
|
**Expected Behavior:** Returns bans grouped by jail name with counts.
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Page Renders World Map And Companion Table
|
|
|
|
**Test:** `Map Page Renders World Map And Companion Table`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `frontend/src/pages/MapPage.tsx`
|
|
- `frontend/src/components/WorldMap.tsx` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "World Map View — country fills, click-to-filter"
|
|
- `Docs/Features.md` — Map view
|
|
|
|
**Expected Behavior:** The map page renders an interactive world map and a companion data table below it.
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Page Renders Time Range Selector
|
|
|
|
**Test:** `Map Page Renders Time Range Selector`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `frontend/src/pages/MapPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — Map time range presets
|
|
|
|
**Expected Behavior:** The map page includes a time range selector (24h, 7d, 30d, 365d).
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Page 24h Preset Shows Live Source Badge
|
|
|
|
**Test:** `Map Page 24h Preset Shows Live Source Badge`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `frontend/src/pages/MapPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Selecting Last 24 hours shows Live source badge"
|
|
|
|
**Expected Behavior:** Selecting 24h on the map page shows a "Live" data source badge.
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Page 7d Preset Shows Archive Source Badge
|
|
|
|
**Test:** `Map Page 7d Preset Shows Archive Source Badge`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `frontend/src/pages/MapPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Selecting Last 7 days shows Archive source badge"
|
|
|
|
**Expected Behavior:** Selecting 7d on the map page shows an "Archive" data source badge.
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Companion Table Is Sticky Header
|
|
|
|
**Test:** `Map Companion Table Is Sticky Header`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `frontend/src/components/MapCompanionTable.tsx` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "sticky table header/footer"
|
|
|
|
**Expected Behavior:** The companion table below the map has a sticky header that remains visible while scrolling.
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Page Has Zoom Controls
|
|
|
|
**Test:** `Map Page Has Zoom Controls`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `frontend/src/components/WorldMap.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "zoom controls"
|
|
|
|
**Expected Behavior:** The map includes zoom in/out controls (buttons or mouse wheel support).
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Bans By Country API Endpoint
|
|
|
|
**Test:** `Map Bans By Country API Endpoint`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `backend/app/routers/dashboard.py` — geo endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Geo/country endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/dashboard/bans/by-country` returns country-level ban counts for map coloring.
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Threshold Config Endpoint Exists
|
|
|
|
**Test:** `Map Threshold Config Endpoint Exists`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `backend/app/routers/config_misc.py` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Map threshold configuration
|
|
|
|
**Expected Behavior:** A configuration endpoint exists for setting map color thresholds (e.g., low/medium/high ban count ranges).
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Threshold Config Returns Thresholds
|
|
|
|
**Test:** `Map Threshold Config Returns Thresholds`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `backend/app/routers/config_misc.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Map threshold configuration
|
|
|
|
**Expected Behavior:** The threshold config endpoint returns the currently configured threshold values.
|
|
|
|
---
|
|
|
|
## Task: 04 Map — Map Filter Clears And Resets Companion Table
|
|
|
|
**Test:** `Map Filter Clears And Resets Companion Table`
|
|
**Suite:** `04_map.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/04_map.robot`
|
|
- `frontend/src/pages/MapPage.tsx`
|
|
- `frontend/src/components/MapCompanionTable.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "click-to-filter, Clear filter"
|
|
|
|
**Expected Behavior:** Clicking a country on the map filters the companion table to that country. Clicking "Clear filter" resets the table to show all countries.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Jails Page Lists Active Jails
|
|
|
|
**Test:** `Jails Page Lists Active Jails`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `frontend/src/pages/JailsPage.tsx`
|
|
- `backend/app/routers/jails.py` — jails list endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Jail Management — list"
|
|
- `Docs/Features.md` — Jail management
|
|
|
|
**Expected Behavior:** The jails page displays a table of all active jails with status, backend, banned count, failed count, find time, ban time, and max retry.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Jails API Returns Active Jails
|
|
|
|
**Test:** `Jails API Returns Active Jails`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — `GET /api/v1/jails`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jails endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/jails` returns a list of active jail configurations and their current status.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Jail Detail Page Loads For First Active Jail
|
|
|
|
**Test:** `Jail Detail Page Loads For First Active Jail`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `frontend/src/pages/JailDetailPage.tsx`
|
|
- `backend/app/routers/jails.py` — jail detail endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Jail Management — list, ban/unban API, IP lookup"
|
|
|
|
**Expected Behavior:** Navigating to `/jails/{jail-name}` loads the detail page for that jail, showing banned IPs, ignore list, and jail controls.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Ban An IP Via API
|
|
|
|
**Test:** `Ban An IP Via API`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — `POST /api/v1/bans`
|
|
- `backend/app/services/ban_service.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Ban endpoint
|
|
- `e2e/Instructions.md` — "Ban / Unban IP"
|
|
|
|
**Expected Behavior:** `POST /api/v1/bans` with `{ip, jail}` bans the specified IP in the specified jail.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Unban The IP We Just Banned
|
|
|
|
**Test:** `Unban The IP We Just Banned`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — `DELETE /api/v1/bans/{ip}`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Unban endpoint
|
|
|
|
**Expected Behavior:** `DELETE /api/v1/bans/{ip}` (or equivalent unban endpoint) removes the ban for the specified IP.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Unban All Endpoint Accepts Request
|
|
|
|
**Test:** `Unban All Endpoint Accepts Request`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — bulk unban endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Bulk unban endpoint
|
|
|
|
**Expected Behavior:** An endpoint exists to unban all IPs (either globally or per-jail) and returns success.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Active Bans Endpoint Returns List
|
|
|
|
**Test:** `Active Bans Endpoint Returns List`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — active bans endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Active bans endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/jails/{name}/bans` returns a paginated list of currently banned IPs for the specified jail.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — IP Lookup Endpoint Returns Geo
|
|
|
|
**Test:** `IP Lookup Endpoint Returns Geo`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/geo.py` — geo lookup endpoint
|
|
- `backend/app/services/geo_service.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Geo lookup endpoint
|
|
- `Docs/Features.md` — IP geolocation
|
|
|
|
**Expected Behavior:** `GET /api/v1/geo/{ip}` returns geolocation data (country, city, ASN, org) for the given IP.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Ignore List Add And Remove Via API
|
|
|
|
**Test:** `Ignore List Add And Remove Via API`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — ignore list endpoints
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Ignore list endpoints
|
|
|
|
**Expected Behavior:** `POST /api/v1/jails/{name}/ignore` adds an IP to the ignore list. `DELETE /api/v1/jails/{name}/ignore/{ip}` removes it.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Ignore Self Toggle Via API
|
|
|
|
**Test:** `Ignore Self Toggle Via API`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — ignore self toggle
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Ignore self toggle
|
|
|
|
**Expected Behavior:** An endpoint exists to toggle "ignore self" (exclude the server's own IP from banning) for a jail.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Jail Reload Endpoint Works
|
|
|
|
**Test:** `Jail Reload Endpoint Works`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — reload endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jail control endpoints
|
|
|
|
**Expected Behavior:** `POST /api/v1/jails/{name}/reload` reloads the jail configuration and returns success.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Jail Stop Endpoint Works
|
|
|
|
**Test:** `Jail Stop Endpoint Works`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — stop endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jail control endpoints
|
|
|
|
**Expected Behavior:** `POST /api/v1/jails/{name}/stop` stops the jail and returns success.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Jail Start Endpoint Works
|
|
|
|
**Test:** `Jail Start Endpoint Works`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — start endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jail control endpoints
|
|
|
|
**Expected Behavior:** `POST /api/v1/jails/{name}/start` starts the jail and returns success.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Jail Idle Endpoint Works
|
|
|
|
**Test:** `Jail Idle Endpoint Works`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — idle endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jail control endpoints
|
|
|
|
**Expected Behavior:** `POST /api/v1/jails/{name}/idle` sets the jail to idle mode (monitoring without banning) and returns success.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Reload All Jails Endpoint Works
|
|
|
|
**Test:** `Reload All Jails Endpoint Works`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/jails.py` — reload all endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jail control endpoints
|
|
|
|
**Expected Behavior:** `POST /api/v1/jails/reload` reloads all jails and returns success.
|
|
|
|
---
|
|
|
|
## Task: 05 Jails — Geo Stats Endpoint Returns Counters
|
|
|
|
**Test:** `Geo Stats Endpoint Returns Counters`
|
|
**Suite:** `05_jails.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/05_jails.robot`
|
|
- `backend/app/routers/geo.py` — geo stats endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Geo stats endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/geo/stats` returns aggregated geolocation statistics (bans by country, etc.).
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Page Renders All Required Tabs
|
|
|
|
**Test:** `Config Page Renders All Required Tabs`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `frontend/src/pages/ConfigPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Configuration View — Jails/Filters/Actions tabs"
|
|
- `Docs/Features.md` — Configuration view
|
|
|
|
**Expected Behavior:** The configuration page renders tabs for Jails, Filters, Actions, Server, and Regex Tester.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Jails Tab Defaults To Active
|
|
|
|
**Test:** `Config Jails Tab Defaults To Active`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `frontend/src/pages/ConfigPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Jails/Filters/Actions tabs"
|
|
|
|
**Expected Behavior:** When navigating to `/config`, the "Jails" tab is active by default.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Filters Tab Loads
|
|
|
|
**Test:** `Config Filters Tab Loads`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `frontend/src/pages/ConfigPage.tsx`
|
|
- `backend/app/routers/config_misc.py` — filters endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Filters tab"
|
|
|
|
**Expected Behavior:** Clicking the "Filters" tab loads and displays the list of fail2ban filter configurations.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Actions Tab Loads
|
|
|
|
**Test:** `Config Actions Tab Loads`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `frontend/src/pages/ConfigPage.tsx`
|
|
- `backend/app/routers/config_misc.py` — actions endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Actions tab"
|
|
|
|
**Expected Behavior:** Clicking the "Actions" tab loads and displays the list of fail2ban action configurations.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Server Tab Loads
|
|
|
|
**Test:** `Config Server Tab Loads`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `frontend/src/pages/ConfigPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Server settings + log viewer"
|
|
|
|
**Expected Behavior:** The Server tab loads and displays server-wide settings.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Regex Tester Tab Loads
|
|
|
|
**Test:** `Config Regex Tester Tab Loads`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `frontend/src/pages/ConfigPage.tsx`
|
|
- `frontend/src/components/RegexTester.tsx` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "regex tester"
|
|
|
|
**Expected Behavior:** The Regex Tester tab loads with input fields for regex pattern and test log lines.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Regex Tester API Endpoint Validates Pattern
|
|
|
|
**Test:** `Config Regex Tester API Endpoint Validates Pattern`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/config_misc.py` — regex tester endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Regex tester endpoint
|
|
|
|
**Expected Behavior:** `POST /api/v1/config/regex-test` (or equivalent) accepts a regex pattern and test lines, returns matches/non-matches.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Jails Endpoint Lists Jail Configs
|
|
|
|
**Test:** `Config Jails Endpoint Lists Jail Configs`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/jail_config.py` — jail configs endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jail config endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/jails` returns a list of jail configuration files and their parsed settings.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Filters Endpoint Lists Filter Configs
|
|
|
|
**Test:** `Config Filters Endpoint Lists Filter Configs`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/jail_config.py` — filter configs endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Filter config endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/filters` returns a list of filter configuration files.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Actions Endpoint Lists Action Configs
|
|
|
|
**Test:** `Config Actions Endpoint Lists Action Configs`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/jail_config.py` — action configs endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Action config endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/actions` returns a list of action configuration files.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Global Settings Endpoint
|
|
|
|
**Test:** `Config Global Settings Endpoint`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/jail_config.py` — global settings endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Global settings endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/global` returns the global fail2ban configuration (e.g., `fail2ban.conf`).
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Service Status Endpoint
|
|
|
|
**Test:** `Config Service Status Endpoint`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/config_misc.py` — service status endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Service status endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/service-status` returns fail2ban service status and log configuration.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Security Headers Endpoint
|
|
|
|
**Test:** `Config Security Headers Endpoint`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/config_misc.py` — security headers endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Security.md` — Security headers
|
|
|
|
**Expected Behavior:** An endpoint returns the currently configured security headers (CSP, X-Frame-Options, etc.).
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Inline Edit Round Trip For First Jail
|
|
|
|
**Test:** `Config Inline Edit Round Trip For First Jail`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `frontend/src/pages/ConfigPage.tsx`
|
|
- `backend/app/routers/jail_config.py` — update endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "inline edit"
|
|
- `Docs/Features.md` — Config inline editing
|
|
|
|
**Expected Behavior:** Editing a jail config field inline, saving, and refreshing the page persists the change.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Raw Section Lazy Load
|
|
|
|
**Test:** `Config Raw Section Lazy Load`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `frontend/src/pages/ConfigPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "raw config"
|
|
|
|
**Expected Behavior:** The raw config section is lazily loaded (not fetched until expanded) to improve initial page load performance.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Raw Action File Endpoint
|
|
|
|
**Test:** `Config Raw Action File Endpoint`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/jail_config.py` — raw file endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Raw config endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/actions/{name}/raw` returns the raw contents of an action config file.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Jail Files Endpoint
|
|
|
|
**Test:** `Config Jail Files Endpoint`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/jail_config.py` — jail files endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Jail files endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/jails/files` returns a list of available jail configuration files.
|
|
|
|
---
|
|
|
|
## Task: 06 Config Jails Filters Actions — Config Invalid Regex Returns 4xx
|
|
|
|
**Test:** `Config Invalid Regex Returns 4xx`
|
|
**Suite:** `06_config_jails_filters_actions.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/06_config_jails_filters_actions.robot`
|
|
- `backend/app/routers/config_misc.py` — regex tester endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Regex tester validation
|
|
|
|
**Expected Behavior:** Submitting an invalid regex pattern to the regex tester endpoint returns HTTP 400 (or other 4xx) with a descriptive error message.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings GET Returns Expected Keys
|
|
|
|
**Test:** `Server Settings GET Returns Expected Keys`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py` — server settings endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Server settings"
|
|
- `Docs/API-Reference.md` — Server settings endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/server` returns JSON with expected keys: `log_level`, `db_purge_age`, `max_matches`, etc.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings Update Log Level
|
|
|
|
**Test:** `Server Settings Update Log Level`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py` — server settings update endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Server settings update
|
|
|
|
**Expected Behavior:** `PUT /api/v1/config/server` with `{log_level: "DEBUG"}` updates the log level and returns the updated config.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings Reject Invalid Log Level
|
|
|
|
**Test:** `Server Settings Reject Invalid Log Level`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py` — validation
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Server settings validation
|
|
|
|
**Expected Behavior:** Submitting an invalid log level (e.g., `"INVALID"`) returns HTTP 400 with a validation error.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings Update DB Purge Age
|
|
|
|
**Test:** `Server Settings Update DB Purge Age`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Server settings update
|
|
|
|
**Expected Behavior:** Updating `db_purge_age` persists the new value and applies it to the archive cleanup schedule.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings Update Max Matches
|
|
|
|
**Test:** `Server Settings Update Max Matches`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Server settings update
|
|
|
|
**Expected Behavior:** Updating `max_matches` persists the new value for log parsing.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings Reject Path Outside Allowlist
|
|
|
|
**Test:** `Server Settings Reject Path Outside Allowlist`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py` — path validation
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Security.md` — Path traversal prevention
|
|
|
|
**Expected Behavior:** Submitting a log file path outside the allowed directory (e.g., `"/etc/passwd"`) returns HTTP 400.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings Accept Stdout Special Target
|
|
|
|
**Test:** `Server Settings Accept Stdout Special Target`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Server settings special targets
|
|
|
|
**Expected Behavior:** `"stdout"` is accepted as a special log target value.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings Accept Syslog Special Target
|
|
|
|
**Test:** `Server Settings Accept Syslog Special Target`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Server settings special targets
|
|
|
|
**Expected Behavior:** `"syslog"` is accepted as a special log target value.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Server Settings Accept Safe File Path
|
|
|
|
**Test:** `Server Settings Accept Safe File Path`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Server settings path validation
|
|
|
|
**Expected Behavior:** A safe, allowlisted file path (e.g., `"/var/log/auth.log"`) is accepted.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Flush Logs Endpoint Works
|
|
|
|
**Test:** `Flush Logs Endpoint Works`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py` — flush logs endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Log management endpoints
|
|
|
|
**Expected Behavior:** `POST /api/v1/config/logs/flush` flushes buffered logs and returns success.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Log Preview Endpoint Returns Content
|
|
|
|
**Test:** `Log Preview Endpoint Returns Content`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py` — log preview endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Log preview endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/logs/preview` returns the most recent log lines as text or JSON.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Log Endpoint Returns Content Or 404
|
|
|
|
**Test:** `Log Endpoint Returns Content Or 404`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py` — log endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Log endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/config/logs` returns log content if available, or HTTP 404 if no log file is configured/found.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Log Observation Add Rejects Path Outside Allowlist
|
|
|
|
**Test:** `Log Observation Add Rejects Path Outside Allowlist`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py` — log observation endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Security.md` — Path traversal prevention
|
|
- `e2e/Instructions.md` — "log observation allowlist"
|
|
|
|
**Expected Behavior:** Adding a log observation path outside the allowlist returns HTTP 400 with a security error.
|
|
|
|
---
|
|
|
|
## Task: 07 Config Log And Serversettings — Log Observation Add Endpoint Exists
|
|
|
|
**Test:** `Log Observation Add Endpoint Exists`
|
|
**Suite:** `07_config_log_and_serversettings.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/07_config_log_and_serversettings.robot`
|
|
- `backend/app/routers/config_misc.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Log observation endpoints
|
|
|
|
**Expected Behavior:** `POST /api/v1/config/logs/observation` exists and accepts `{path: "/var/log/auth.log"}`.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Page Renders
|
|
|
|
**Test:** `History Page Renders`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `frontend/src/pages/HistoryPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Ban History — table, filters, per-IP timeline"
|
|
- `Docs/Features.md` — History view
|
|
|
|
**Expected Behavior:** The history page renders with a table, filters, and pagination controls.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Page Shows Archive Source Badge By Default
|
|
|
|
**Test:** `History Page Shows Archive Source Badge By Default`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `frontend/src/pages/HistoryPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "archive vs fail2ban source"
|
|
|
|
**Expected Behavior:** The history page shows an "Archive" data source badge by default (since history comes from the SQLite archive, not live fail2ban).
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Page Default 7d Range
|
|
|
|
**Test:** `History Page Default 7d Range`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `frontend/src/pages/HistoryPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — History time range defaults
|
|
|
|
**Expected Behavior:** The history page defaults to showing the last 7 days of ban history.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Endpoint Returns Paginated Data
|
|
|
|
**Test:** `History Endpoint Returns Paginated Data`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `backend/app/routers/history.py` — history endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — History endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/history?page=1&page_size=50` returns paginated ban history with `items`, `total`, `page`, `page_size`.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Archive Endpoint Returns Data
|
|
|
|
**Test:** `History Archive Endpoint Returns Data`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `backend/app/routers/history.py` — archive endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — History archive endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/history/archive` returns archived ban records.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Per IP Endpoint Returns Data
|
|
|
|
**Test:** `History Per IP Endpoint Returns Data`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `backend/app/routers/history.py` — per-IP endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Per-IP history endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/history/ip/{ip}` returns the ban timeline for a specific IP address.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Filter By Jail Returns Data
|
|
|
|
**Test:** `History Filter By Jail Returns Data`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `backend/app/routers/history.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — History filtering
|
|
|
|
**Expected Behavior:** `GET /api/v1/history?jail=ssh` returns only bans from the specified jail.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Filter By Source Fail2ban
|
|
|
|
**Test:** `History Filter By Source Fail2ban`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `backend/app/routers/history.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — History source filtering
|
|
|
|
**Expected Behavior:** Filtering by `source=fail2ban` returns only live fail2ban-sourced records.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History Filter By Source Archive
|
|
|
|
**Test:** `History Filter By Source Archive`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `backend/app/routers/history.py`
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — History source filtering
|
|
|
|
**Expected Behavior:** Filtering by `source=archive` returns only archived records.
|
|
|
|
---
|
|
|
|
## Task: 08 History — History URL Params Honored
|
|
|
|
**Test:** `History URL Params Honored`
|
|
**Suite:** `08_history.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/08_history.robot`
|
|
- `frontend/src/pages/HistoryPage.tsx` — URL param parsing
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Features.md` — Deep-linking with URL params
|
|
|
|
**Expected Behavior:** Navigating to `/history?range=30d&jail=ssh` pre-selects the 30-day range and ssh jail filter.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklists Page Renders
|
|
|
|
**Test:** `Blocklists Page Renders`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `frontend/src/pages/BlocklistsPage.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "External Blocklist Importer — CRUD"
|
|
- `Docs/Features.md` — Blocklist management
|
|
|
|
**Expected Behavior:** The blocklists page renders with a table of configured sources, import controls, and schedule settings.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklists Sources List Endpoint
|
|
|
|
**Test:** `Blocklists Sources List Endpoint`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — sources list endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Blocklist sources endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/blocklists` returns a list of configured blocklist sources.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Source Create Rejects Invalid Scheme
|
|
|
|
**Test:** `Blocklist Source Create Rejects Invalid Scheme`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — create endpoint validation
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Security.md` — SSRF prevention
|
|
- `e2e/Instructions.md` — "SSRF validation"
|
|
|
|
**Expected Behavior:** Creating a blocklist source with an invalid URL scheme (e.g., `ftp://`, `file://`) returns HTTP 400.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Source Create Rejects Loopback URL
|
|
|
|
**Test:** `Blocklist Source Create Rejects Loopback URL`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — SSRF validation
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Security.md` — SSRF prevention
|
|
|
|
**Expected Behavior:** Creating a blocklist source with a loopback URL (`http://127.0.0.1/...`, `http://localhost/...`) returns HTTP 400.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Source Create Rejects Private IP URL
|
|
|
|
**Test:** `Blocklist Source Create Rejects Private IP URL`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — SSRF validation
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Security.md` — SSRF prevention
|
|
|
|
**Expected Behavior:** Creating a blocklist source with a private IP URL (`http://192.168.1.1/...`, `http://10.0.0.1/...`) returns HTTP 400.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Source Create Rejects Link Local URL
|
|
|
|
**Test:** `Blocklist Source Create Rejects Link Local URL`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — SSRF validation
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Security.md` — SSRF prevention
|
|
|
|
**Expected Behavior:** Creating a blocklist source with a link-local URL (`http://169.254.1.1/...`) returns HTTP 400.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Schedule Endpoint Returns Config
|
|
|
|
**Test:** `Blocklist Schedule Endpoint Returns Config`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — schedule endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Blocklist schedule endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/blocklists/schedule` returns the current import schedule configuration (cron expression, enabled status).
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Schedule Update Works
|
|
|
|
**Test:** `Blocklist Schedule Update Works`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — schedule update endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Blocklist schedule update
|
|
|
|
**Expected Behavior:** `PUT /api/v1/blocklists/schedule` updates the import schedule and returns the updated config.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Manual Import Endpoint Reachable
|
|
|
|
**Test:** `Blocklist Manual Import Endpoint Reachable`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — manual import endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Blocklist manual import
|
|
|
|
**Expected Behavior:** `POST /api/v1/blocklists/import` triggers a manual import and returns a job ID or success status.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Import Log Endpoint Returns Paginated Data
|
|
|
|
**Test:** `Blocklist Import Log Endpoint Returns Paginated Data`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — import log endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Blocklist import log
|
|
|
|
**Expected Behavior:** `GET /api/v1/blocklists/log` returns paginated import log entries with timestamps, source, status, and error counts.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Delete Non Existent Returns 404
|
|
|
|
**Test:** `Blocklist Delete Non Existent Returns 404`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — delete endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Blocklist delete endpoint
|
|
|
|
**Expected Behavior:** `DELETE /api/v1/blocklists/{id}` for a non-existent source returns HTTP 404.
|
|
|
|
---
|
|
|
|
## Task: 09 Blocklists — Blocklist Create And Delete Cycle
|
|
|
|
**Test:** `Blocklist Create And Delete Cycle`
|
|
**Suite:** `09_blocklists.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/09_blocklists.robot`
|
|
- `backend/app/routers/blocklists.py` — create and delete endpoints
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "CRUD"
|
|
|
|
**Expected Behavior:** Creating a valid blocklist source, verifying it appears in the list, and then deleting it removes it from the list.
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Sidebar Is Visible On Dashboard
|
|
|
|
**Test:** `Sidebar Is Visible On Dashboard`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `frontend/src/components/Sidebar.tsx` (or `Layout.tsx`)
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "sidebar nav"
|
|
- `Docs/Features.md` — Layout
|
|
|
|
**Expected Behavior:** After login, the sidebar navigation is visible on the dashboard page.
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Sidebar Lists All Required Pages
|
|
|
|
**Test:** `Sidebar Lists All Required Pages`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `frontend/src/components/Sidebar.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "sidebar nav"
|
|
|
|
**Expected Behavior:** The sidebar contains links to: Dashboard, World Map, Jails, History, Blocklists, Configuration.
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Sidebar Sign Out Logs User Out
|
|
|
|
**Test:** `Sidebar Sign Out Logs User Out`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `frontend/src/components/Sidebar.tsx`
|
|
- `backend/app/routers/auth.py` — logout endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "Sign Out button"
|
|
|
|
**Expected Behavior:** Clicking "Sign Out" in the sidebar clears the session and redirects to `/login`.
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Theme Toggle Is Present In Sidebar
|
|
|
|
**Test:** `Theme Toggle Is Present In Sidebar`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `frontend/src/components/Sidebar.tsx`
|
|
- `frontend/src/hooks/useTheme.ts` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "theme toggle"
|
|
|
|
**Expected Behavior:** The sidebar contains a theme toggle button (light/dark mode).
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Active Page Highlighted In Sidebar
|
|
|
|
**Test:** `Active Page Highlighted In Sidebar`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `frontend/src/components/Sidebar.tsx`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "active link highlighting"
|
|
|
|
**Expected Behavior:** The current page's sidebar link is visually highlighted (different background/text color).
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Session Persists Across Page Reload
|
|
|
|
**Test:** `Session Persists Across Page Reload`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `frontend/src/hooks/useSession.ts`
|
|
- `backend/app/routers/auth.py` — session validation
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "session persistence"
|
|
|
|
**Expected Behavior:** Reloading the page while logged in does NOT redirect to login; the session cookie is still valid.
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Theme Toggle Changes Color Mode
|
|
|
|
**Test:** `Theme Toggle Changes Color Mode`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `frontend/src/components/Sidebar.tsx`
|
|
- `frontend/src/hooks/useTheme.ts`
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "theme toggle"
|
|
|
|
**Expected Behavior:** Clicking the theme toggle switches the UI between light and dark mode, and the preference persists in `localStorage`.
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Health Endpoint Returns Component Status
|
|
|
|
**Test:** `Health Endpoint Returns Component Status`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `backend/app/routers/health.py` — health endpoint
|
|
|
|
**Reference Docs:**
|
|
- `e2e/Instructions.md` — "health endpoints"
|
|
- `Docs/API-Reference.md` — Health endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/health` returns JSON with component statuses: `database`, `fail2ban`, `scheduler`, `cache`, etc.
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Liveness Endpoint Returns 200
|
|
|
|
**Test:** `Liveness Endpoint Returns 200`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `backend/app/routers/health.py` — liveness endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Liveness probe
|
|
- `Docs/Deployment.md` — Kubernetes probes
|
|
|
|
**Expected Behavior:** `GET /api/v1/health/live` always returns HTTP 200 (even if fail2ban is down), indicating the Python process is alive.
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Metrics Endpoint Returns Prometheus Text
|
|
|
|
**Test:** `Metrics Endpoint Returns Prometheus Text`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `backend/app/routers/metrics.py` (or equivalent)
|
|
|
|
**Reference Docs:**
|
|
- `Docs/Observability.md` — Prometheus metrics
|
|
- `Docs/API-Reference.md` — Metrics endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/metrics` returns Prometheus-formatted text with application metrics (request counts, ban counts, etc.).
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Setup Timezone Endpoint Returns IANA String
|
|
|
|
**Test:** `Setup Timezone Endpoint Returns IANA String`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `backend/app/routers/setup.py` — timezone endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Setup timezone endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/setup/timezone` returns a valid IANA timezone string (e.g., `"UTC"`, `"Europe/Berlin"`).
|
|
|
|
---
|
|
|
|
## Task: 10 General Layout — Setup Status Endpoint Returns Completed Flag
|
|
|
|
**Test:** `Setup Status Endpoint Returns Completed Flag`
|
|
**Suite:** `10_general_layout.robot`
|
|
|
|
**Step That Fails:** Parent suite setup (`Wait For Backend Health`).
|
|
|
|
**Files to Check:**
|
|
- `e2e/tests/10_general_layout.robot`
|
|
- `backend/app/routers/setup.py` — setup status endpoint
|
|
|
|
**Reference Docs:**
|
|
- `Docs/API-Reference.md` — Setup status endpoint
|
|
|
|
**Expected Behavior:** `GET /api/v1/setup` returns `{completed: true|false}` indicating whether initial setup has been completed.
|