Spaces:
Sleeping
Sleeping
| """ | |
| Archivo: test_security.py | |
| Fecha de modificación: 04/06/2026 | |
| Autor: Equipo AgroVisión | |
| Descripción: | |
| Pruebas del *hardening* del gateway: cabeceras de seguridad en las respuestas y el | |
| rate limiting de `/api` (429 al exceder el cupo). Recrea la app con un límite bajo. | |
| Ejecución: | |
| uv run python -m pytest tests/integration/test_security.py | |
| """ | |
| from __future__ import annotations | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from backend.config import get_settings | |
| def _reset(monkeypatch: pytest.MonkeyPatch) -> None: | |
| monkeypatch.delenv("COUNTING_ENABLED", raising=False) | |
| get_settings.cache_clear() | |
| yield | |
| get_settings.cache_clear() | |
| def test_cabeceras_de_seguridad_presentes() -> None: | |
| """Toda respuesta incluye las cabeceras de hardening.""" | |
| from backend.main import create_app | |
| with TestClient(create_app()) as client: | |
| r = client.get("/api/status") | |
| assert r.headers.get("X-Content-Type-Options") == "nosniff" | |
| assert r.headers.get("X-Frame-Options") == "SAMEORIGIN" | |
| assert "Referrer-Policy" in r.headers | |
| def test_rate_limit_devuelve_429(monkeypatch: pytest.MonkeyPatch) -> None: | |
| """Al exceder el cupo de /api, el gateway responde 429 con Retry-After.""" | |
| monkeypatch.setenv("RATE_LIMIT_PER_MIN", "3") | |
| get_settings.cache_clear() | |
| from backend.main import create_app | |
| with TestClient(create_app()) as client: | |
| codes = [client.get("/api/status").status_code for _ in range(4)] | |
| assert codes[:3] == [200, 200, 200] | |
| assert codes[3] == 429 | |
| def test_rate_limit_desactivado_no_bloquea(monkeypatch: pytest.MonkeyPatch) -> None: | |
| """Con RATE_LIMIT_PER_MIN=0 no se aplica límite.""" | |
| monkeypatch.setenv("RATE_LIMIT_PER_MIN", "0") | |
| get_settings.cache_clear() | |
| from backend.main import create_app | |
| with TestClient(create_app()) as client: | |
| codes = [client.get("/api/status").status_code for _ in range(10)] | |
| assert all(c == 200 for c in codes) | |