File size: 4,673 Bytes
9da4e9c
 
 
 
 
 
 
 
 
 
 
 
 
5409901
 
9da4e9c
 
 
5409901
 
9da4e9c
 
5409901
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9da4e9c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from __future__ import annotations

import time
from pathlib import Path

from fastapi.testclient import TestClient

from racing_reports.config import Settings
from racing_reports.models import ReportResult
from racing_reports.web import app as web_app


def test_home_is_spa_with_teams_and_report_cards():
    """El nuevo home es un SPA que consume /api/. Equipos/ligas/partidos se cargan
    client-side; verificamos los selectores y las cards de reportes."""
    client = TestClient(web_app.app)
    resp = client.get("/")
    assert resp.status_code == 200
    assert 'x-model="league"' in resp.text       # selector de liga
    assert 'x-model="season"' in resp.text       # selector de temporada
    assert "Reporte previo" in resp.text
    assert "Bloques" in resp.text
    assert "post-partido" in resp.text            # card de post-partido
    assert "runPostMatch" in resp.text            # flujo de post-partido funcional
    assert "/api/leagues" in resp.text            # alpine consume la API meta
    assert "/api/reports/" in resp.text


def test_meta_endpoints_are_dataset_driven():
    """leagues/seasons/teams/matches salen del dataset bundleado (offline)."""
    from racing_reports.api import routes_meta as rm
    ls = rm._league_seasons()
    assert ls, "debe haber al menos una liga/temporada"
    league = next(iter(ls))
    season = ls[league][0]
    assert rm.teams(league, season), "debe listar equipos"
    # matches puede estar vacío para temporadas sin jugados, pero no debe romper
    assert isinstance(rm.matches(league, season, played_only=True), list)


def test_legacy_home_still_works():
    """La UI vieja sigue accesible vía /legacy para retrocompatibilidad."""
    client = TestClient(web_app.app)
    resp = client.get("/legacy")
    assert resp.status_code == 200
    assert "Reporte previo / Bloques" in resp.text
    assert "Reporte post-partido" in resp.text


def test_legacy_routes_require_password_when_set(monkeypatch, tmp_path):
    """Si ACCESS_PASSWORD está seteada, las rutas /view, /download, /status,
    /legacy, / NO deben servir contenido sin cookie válida."""
    # Settings con password forzada + DEFAULT_SETTINGS también, porque ambos
    # se usan en el app code.
    new_settings = Settings(
        cache_dir=tmp_path / "cache",
        output_dir=tmp_path / "outputs",
        access_password="secret-1234",
    )
    monkeypatch.setattr(web_app, "DEFAULT_SETTINGS", new_settings)
    from racing_reports import config as cfg
    monkeypatch.setattr(cfg, "DEFAULT_SETTINGS", new_settings)
    from racing_reports.api import deps
    monkeypatch.setattr(deps, "DEFAULT_SETTINGS", new_settings)

    client = TestClient(web_app.app)

    # / → redirect a /login
    assert client.get("/", follow_redirects=False).status_code in (303, 307)
    # /legacy → redirect a /login
    assert client.get("/legacy", follow_redirects=False).status_code in (303, 307)
    # /view sin cookie → 401
    assert client.get("/view", params={"path": str(tmp_path / "x.html")}).status_code == 401
    # /download sin cookie → 401
    assert client.get("/download", params={"path": str(tmp_path / "x.html")}).status_code == 401
    # /status/<id> sin cookie → 401
    assert client.get("/status/deadbeef").status_code == 401
    # API también
    assert client.get("/api/leagues").status_code == 401
    # /api/health sigue siendo público (no expone data)
    assert client.get("/api/health").status_code == 200


def test_generate_enqueues_job_and_reports_links(monkeypatch, tmp_path: Path):
    out = tmp_path / "pre_match.html"
    out.write_text("<html>ok</html>", encoding="utf-8")
    manifest = tmp_path / "manifest.json"
    manifest.write_text("{}", encoding="utf-8")

    class FakeRunner:
        def run(self, request):
            return ReportResult(
                output_dir=tmp_path,
                html_paths={"pre_match": out},
                manifest_path=manifest,
            )

    monkeypatch.setattr(web_app, "ReportRunner", lambda *a, **k: FakeRunner())
    client = TestClient(web_app.app)

    resp = client.post(
        "/generate",
        data={
            "flow": "pre",
            "team_a": "Racing de Santander",
            "team_b": "Huesca",
            "pre_match": "on",
        },
        follow_redirects=False,
    )
    assert resp.status_code == 303
    status_url = resp.headers["location"]

    body = ""
    for _ in range(50):
        body = client.get(status_url).text
        if "Volver al inicio" in body or "problema" in body:
            break
        time.sleep(0.05)
    assert "Reporte previo (head-to-head)" in body
    assert "/view?path=" in body