Files
ietf-draft-analyzer/tests/test_web.py
Christian Nennemann dea36e931a Add test coverage for CLI commands, Flask routes, and shared DB methods
74 new tests across 3 files:
- test_cli.py: CLI help, version, config, report generation, wg/viz/pipeline subcommands
- test_web.py: All public pages, admin pages (dev/prod), API JSON endpoints, CSV export, 404s
- test_db_shared.py: rated_count, gap_count, false_positive_names, category_counts, source_counts, draft_author_count_map, search_gaps, search_authors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 03:49:09 +01:00

270 lines
6.8 KiB
Python

"""Tests for Flask web routes using the test client.
Uses the real data/drafts.db so templates can render with actual data.
"""
from __future__ import annotations
import sys
import os
import pytest
# Ensure src is on path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
from webui.app import create_app
@pytest.fixture
def client():
"""Create a Flask test client in dev mode (admin enabled)."""
# Reset auth module state so create_app can re-initialize
import webui.auth as auth_mod
auth_mod._initialized = False
auth_mod._dev_mode = False
app = create_app(dev=True)
app.config["TESTING"] = True
with app.test_client() as c:
yield c
@pytest.fixture
def prod_client():
"""Create a Flask test client in production mode (admin disabled)."""
import webui.auth as auth_mod
auth_mod._initialized = False
auth_mod._dev_mode = False
app = create_app(dev=False)
app.config["TESTING"] = True
with app.test_client() as c:
yield c
# ── Public pages ──────────────────────────────────────────────────────
def test_overview_page(client):
resp = client.get("/")
assert resp.status_code == 200
def test_drafts_page(client):
resp = client.get("/drafts")
assert resp.status_code == 200
def test_authors_page(client):
resp = client.get("/authors")
assert resp.status_code == 200
def test_timeline_page(client):
resp = client.get("/timeline")
assert resp.status_code == 200
def test_search_page_empty(client):
resp = client.get("/search")
assert resp.status_code == 200
def test_search_page_with_query(client):
resp = client.get("/search?q=agent")
assert resp.status_code == 200
def test_about_page(client):
resp = client.get("/about")
assert resp.status_code == 200
def test_ratings_page(client):
resp = client.get("/ratings")
assert resp.status_code == 200
def test_citations_page(client):
resp = client.get("/citations")
assert resp.status_code == 200
def test_ideas_page(client):
resp = client.get("/ideas")
assert resp.status_code == 200
def test_idea_clusters_page(client):
resp = client.get("/idea-clusters")
assert resp.status_code == 200
def test_architecture_page(client):
resp = client.get("/architecture")
assert resp.status_code == 200
def test_impressum_page(client):
resp = client.get("/impressum")
assert resp.status_code == 200
def test_datenschutz_page(client):
resp = client.get("/datenschutz")
assert resp.status_code == 200
# ── 404 handling ──────────────────────────────────────────────────────
def test_404_for_nonexistent_page(client):
resp = client.get("/this-page-does-not-exist")
assert resp.status_code == 404
def test_404_for_nonexistent_draft(client):
resp = client.get("/drafts/draft-nonexistent-foobar-xyz")
assert resp.status_code == 404
# ── Admin pages (dev mode) ───────────────────────────────────────────
def test_gaps_page_dev(client):
resp = client.get("/gaps")
assert resp.status_code == 200
def test_monitor_page_dev(client):
resp = client.get("/monitor")
assert resp.status_code == 200
def test_proposals_page_dev(client):
resp = client.get("/proposals")
assert resp.status_code == 200
# ── Admin pages (production = 404) ───────────────────────────────────
def test_gaps_page_prod_hidden(prod_client):
resp = prod_client.get("/gaps")
assert resp.status_code == 404
def test_monitor_page_prod_hidden(prod_client):
resp = prod_client.get("/monitor")
assert resp.status_code == 404
def test_proposals_page_prod_hidden(prod_client):
resp = prod_client.get("/proposals")
assert resp.status_code == 404
# ── API endpoints ─────────────────────────────────────────────────────
def test_api_stats(client):
resp = client.get("/api/stats")
assert resp.status_code == 200
data = resp.get_json()
assert isinstance(data, dict)
assert "total_drafts" in data or "drafts" in data or len(data) > 0
def test_api_drafts(client):
resp = client.get("/api/drafts")
assert resp.status_code == 200
data = resp.get_json()
assert isinstance(data, dict)
def test_api_ratings(client):
resp = client.get("/api/ratings")
assert resp.status_code == 200
data = resp.get_json()
assert isinstance(data, dict)
def test_api_timeline(client):
resp = client.get("/api/timeline")
assert resp.status_code == 200
data = resp.get_json()
assert isinstance(data, (dict, list))
def test_api_categories(client):
resp = client.get("/api/categories")
assert resp.status_code == 200
data = resp.get_json()
assert isinstance(data, dict)
def test_api_ideas(client):
resp = client.get("/api/ideas")
assert resp.status_code == 200
data = resp.get_json()
assert isinstance(data, dict)
def test_api_search_empty(client):
resp = client.get("/api/search")
assert resp.status_code == 200
data = resp.get_json()
assert "drafts" in data
def test_api_search_with_query(client):
resp = client.get("/api/search?q=agent")
assert resp.status_code == 200
data = resp.get_json()
assert isinstance(data, dict)
def test_api_draft_detail_not_found(client):
resp = client.get("/api/drafts/nonexistent-draft-xyz")
assert resp.status_code == 404
data = resp.get_json()
assert "error" in data
def test_api_architecture(client):
resp = client.get("/api/architecture")
assert resp.status_code == 200
data = resp.get_json()
assert isinstance(data, dict)
def test_api_idea_clusters(client):
resp = client.get("/api/idea-clusters")
assert resp.status_code == 200
def test_api_citations(client):
resp = client.get("/api/citations")
assert resp.status_code == 200
def test_api_author_network(client):
resp = client.get("/api/authors/network")
assert resp.status_code == 200
# ── CSV export format ─────────────────────────────────────────────────
def test_api_drafts_csv(client):
resp = client.get("/api/drafts?format=csv")
assert resp.status_code == 200
assert "text/csv" in resp.content_type
def test_api_categories_csv(client):
resp = client.get("/api/categories?format=csv")
assert resp.status_code == 200
assert "text/csv" in resp.content_type