Files
BanGUI/backend/tests/test_deprecation_middleware.py
2026-05-15 20:41:05 +02:00

94 lines
3.5 KiB
Python

"""Tests for the deprecation header middleware."""
from datetime import UTC, datetime, timedelta
from pathlib import Path
import pytest
from httpx import ASGITransport, AsyncClient
from app.main import create_app
from app.middleware.deprecation import (
_DEPRECATED_ENDPOINTS,
_is_deprecated,
register_deprecated_endpoint,
)
def _make_utc(days_from_now: int) -> datetime:
return datetime.now(UTC) + timedelta(days=days_from_now)
@pytest.fixture
def clean_registry() -> list:
"""Clear the deprecated endpoints registry before and after each test."""
original = list(_DEPRECATED_ENDPOINTS)
_DEPRECATED_ENDPOINTS.clear()
yield _DEPRECATED_ENDPOINTS
_DEPRECATED_ENDPOINTS.clear()
_DEPRECATED_ENDPOINTS.extend(original)
class TestIsDeprecated:
def test_path_matches_registered_prefix(self, clean_registry: list) -> None:
register_deprecated_endpoint("/api/v1/jails", _make_utc(180))
assert _is_deprecated("/api/v1/jails") is not None
assert _is_deprecated("/api/v1/jails/test-jail") is not None
def test_path_does_not_match_unregistered_prefix(self, clean_registry: list) -> None:
register_deprecated_endpoint("/api/v1/jails", _make_utc(180))
assert _is_deprecated("/api/v1/bans") is None
def test_empty_registry_returns_none(self, clean_registry: list) -> None:
assert _is_deprecated("/api/v1/jails") is None
class TestDeprecationHeadersIntegration:
@pytest.mark.asyncio
async def test_deprecated_endpoint_gets_headers(self, clean_registry: list, tmp_path: Path) -> None:
register_deprecated_endpoint("/api/v1/jails", _make_utc(180), successor_url="/api/v2/jails")
from app.config import Settings
config_dir = tmp_path / "fail2ban"
config_dir.mkdir()
settings = Settings(
database_path="/tmp/test.db",
fail2ban_socket="/tmp/fake.sock",
fail2ban_config_dir=str(config_dir),
session_secret="test-secret-key-do-not-use-in-production",
session_duration_minutes=60,
timezone="UTC",
log_level="debug",
)
app = create_app(settings=settings)
async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
response = await client.get("/api/v1/jails")
# 307 = setup redirect (app redirects unauthenticated/unconfigured requests)
assert response.status_code in (200, 307, 401, 403, 404)
assert "Deprecation" in response.headers or "Sunset" in response.headers
@pytest.mark.asyncio
async def test_non_deprecated_endpoint_no_headers(self, clean_registry: list, tmp_path: Path) -> None:
register_deprecated_endpoint("/api/v1/jails", _make_utc(180))
from app.config import Settings
config_dir = tmp_path / "fail2ban"
config_dir.mkdir()
settings = Settings(
database_path="/tmp/test.db",
fail2ban_socket="/tmp/fake.sock",
fail2ban_config_dir=str(config_dir),
session_secret="test-secret-key-do-not-use-in-production",
session_duration_minutes=60,
timezone="UTC",
log_level="debug",
)
app = create_app(settings=settings)
async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
response = await client.get("/api/v1/bans")
# No Deprecation header on non-deprecated path
assert "Deprecation" not in response.headers