"""Tests for M6-T09: Energy data API.

Coverage
--------
GET  /api/energy/prices
  - unauthenticated → 401
  - no active contract → 200, kind=null, points=[], tariff=null
  - tibber active contract → 200, points from tibber_price, tariff=null
  - manual active contract → 200, points=[], tariff with effective prices
  - limit parameter caps tibber points

GET  /api/energy/costs
  - unauthenticated → 401
  - empty DB → 200, items=[]
  - returns rows ordered by period_start ascending
  - limit parameter caps results

GET  /api/energy/costs/summary
  - unauthenticated → 401
  - empty DB → 200, all-zeros (no active contract, no periods)
  - returns summarize() result structure

GET  /api/energy/dsmr/latest
  - unauthenticated → 401
  - no data → 200, found=false
  - with data → 200, found=true, correct payload

POST /api/energy/costs/recompute
  - unauthenticated → 401
  - missing CSRF → 403
  - end ≤ start → 422
  - window > 366 days → 422
  - valid call → 200, recomputed=int (idempotent)

POST /api/energy/tibber/test
  - unauthenticated → 401
  - missing CSRF → 403
  - token empty → 400 config-error
  - mock client success → 200 success with price data
  - mock client TibberAuthError → 502 failed
  - mock client TibberError → 502 failed
  - token never appears in success/failed responses

Auth/CSRF matrix: all write endpoints need session + CSRF.
"""

from __future__ import annotations

from datetime import UTC, datetime, timedelta
from typing import Any
from unittest.mock import patch

import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import Session

from app.integrations.tibber.client import PricePoint, TibberAuthError, TibberError
from app.models.energy import (
    DsmrReading,
    EnergyCostPeriod,
    EnergyContract,
    EnergyContractVersion,
    TibberPrice,
)

# ---------------------------------------------------------------------------
# Shared helpers
# ---------------------------------------------------------------------------

_CSRF = "test-csrf-token"

_MANUAL_VALUES: dict[str, Any] = {
    "energy": {
        "buy": {"normal": 0.40, "dal": 0.30},
        "sell": {"normal": 0.10, "dal": 0.10},
        "energy_tax": 0.1108,
        "ode": 0.0,
    },
    "standing": {
        "network_fee": 25.0,
        "management_fee": 9.87,
    },
    "credits": {
        "heffingskorting": 600.0,
    },
}

_TIBBER_VALUES: dict[str, Any] = {
    "energy": {
        "energy_tax": 0.1108,
        "sell_adjust": 0.0,
    },
    "standing": {
        "management_fee": 5.99,
        "network_fee": 25.0,
    },
    "credits": {
        "heffingskorting": 600.0,
    },
}


def _login(client: TestClient) -> None:
    resp = client.post(
        "/api/auth/login",
        json={"username": "admin", "password": "test-password"},
    )
    assert resp.status_code == 200, f"Login failed: {resp.status_code} {resp.text}"


def _set_app_config(engine, key: str, value: str) -> None:
    """Upsert a key/value pair into the app_config table.

    Used by tibber test helpers to inject a non-empty TIBBER_API_TOKEN without
    needing to patch get_app_settings (which is shared with auth infrastructure).
    """
    from sqlalchemy.orm import Session as _Session

    from app.models.config import AppConfigEntry

    now = datetime.now(UTC)
    with _Session(engine) as session:
        existing = session.execute(
            __import__("sqlalchemy").select(AppConfigEntry).where(AppConfigEntry.key == key)
        ).scalar_one_or_none()
        if existing is not None:
            existing.value = value
            existing.updated_at = now
        else:
            session.add(AppConfigEntry(key=key, value=value, updated_at=now))
        session.commit()


# ---------------------------------------------------------------------------
# Fixtures
# ---------------------------------------------------------------------------


@pytest.fixture()
def energy_client(auth_database):
    """TestClient + SQLAlchemy engine + FastAPI app for Energy API tests."""
    from app.main import create_app

    app_url = auth_database["app_url"]
    engine = create_engine(app_url, connect_args={"check_same_thread": False})
    fastapi_app = create_app()
    with TestClient(fastapi_app) as test_client:
        yield test_client, engine, fastapi_app
    engine.dispose()


def _make_active_manual_contract(engine) -> tuple[EnergyContract, EnergyContractVersion]:
    """Insert an active manual EnergyContract with one version and return both."""
    now = datetime.now(UTC)
    with Session(engine) as session:
        contract = EnergyContract(
            name="Test Manual",
            kind="manual",
            active=True,
            currency="EUR",
            created_at=now,
            updated_at=now,
        )
        session.add(contract)
        session.flush()
        version = EnergyContractVersion(
            contract_id=contract.id,
            effective_from=now - timedelta(days=30),
            effective_to=None,
            values=_MANUAL_VALUES,
            created_at=now,
        )
        session.add(version)
        session.commit()
        # capture ids before session closes
        contract_id = contract.id
        version_id = version.id

    # Return plain data structs (not ORM objects tied to closed session)
    class _ContractStub:
        id = contract_id

    class _VersionStub:
        id = version_id

    return _ContractStub(), _VersionStub()  # type: ignore[return-value]


def _make_active_tibber_contract(engine) -> tuple[int, int]:
    """Insert an active tibber EnergyContract with one version and return (contract_id, version_id)."""
    now = datetime.now(UTC)
    with Session(engine) as session:
        contract = EnergyContract(
            name="Test Tibber",
            kind="tibber",
            active=True,
            currency="EUR",
            created_at=now,
            updated_at=now,
        )
        session.add(contract)
        session.flush()
        version = EnergyContractVersion(
            contract_id=contract.id,
            effective_from=now - timedelta(days=30),
            effective_to=None,
            values=_TIBBER_VALUES,
            created_at=now,
        )
        session.add(version)
        session.commit()
        return contract.id, version.id


def _make_tibber_prices(engine, count: int = 3) -> list[datetime]:
    """Insert ``count`` TibberPrice rows starting from one hour ago; return starts_at list."""
    now = datetime.now(UTC).replace(second=0, microsecond=0)
    base = now - timedelta(hours=1)
    starts = [base + timedelta(minutes=15 * i) for i in range(count)]
    with Session(engine) as session:
        for s in starts:
            row = TibberPrice(
                starts_at=s,
                resolution="QUARTER_HOURLY",
                energy=0.18,
                tax=0.065,
                total=0.245,
                level="NORMAL",
                currency="EUR",
                fetched_at=now,
            )
            session.add(row)
        session.commit()
    return starts


def _make_cost_periods(engine, count: int = 3, version_id: int | None = None) -> list[datetime]:
    """Insert ``count`` EnergyCostPeriod rows starting from one hour ago; return period_start list."""
    now = datetime.now(UTC).replace(second=0, microsecond=0)
    base = now - timedelta(hours=2)
    starts = []
    with Session(engine) as session:
        for i in range(count):
            t0 = base + timedelta(minutes=15 * i)
            period = EnergyCostPeriod(
                period_start=t0,
                d1_kwh=0.1 * i,
                d2_kwh=0.05 * i,
                r1_kwh=0.0,
                r2_kwh=0.0,
                import_cost=0.05 * i,
                export_revenue=0.0,
                net_cost=0.05 * i,
                currency="EUR",
                pricing={"kind": "manual"},
                contract_version_id=version_id,
                degraded=False,
                computed_at=now,
            )
            session.add(period)
            starts.append(t0)
        session.commit()
    return starts


def _make_dsmr_reading(engine, recorded_at: datetime | None = None) -> datetime:
    """Insert one DsmrReading and return its recorded_at."""
    now = recorded_at or datetime.now(UTC)
    with Session(engine) as session:
        row = DsmrReading(
            recorded_at=now,
            source_id=42,
            payload={"electricity_delivered_1": "100.0", "test": True},
        )
        session.add(row)
        session.commit()
    return now


# ---------------------------------------------------------------------------
# GET /api/energy/prices — auth
# ---------------------------------------------------------------------------


def test_prices_unauthenticated_returns_401(energy_client):
    client, _, _app = energy_client
    resp = client.get("/api/energy/prices")
    assert resp.status_code == 401


# ---------------------------------------------------------------------------
# GET /api/energy/prices — no active contract
# ---------------------------------------------------------------------------


def test_prices_no_contract_returns_empty(energy_client):
    client, _, _app = energy_client
    _login(client)
    resp = client.get("/api/energy/prices")
    assert resp.status_code == 200
    body = resp.json()
    assert body["kind"] is None
    assert body["points"] == []
    assert body["tariff"] is None
    assert "currency" in body


# ---------------------------------------------------------------------------
# GET /api/energy/prices — manual contract
# ---------------------------------------------------------------------------


def test_prices_manual_contract_returns_tariff(energy_client):
    client, engine, _app = energy_client
    _login(client)
    _make_active_manual_contract(engine)

    resp = client.get("/api/energy/prices")
    assert resp.status_code == 200
    body = resp.json()

    assert body["kind"] == "manual"
    assert body["currency"] == "EUR"
    assert body["points"] == []
    assert body["tariff"] is not None

    tariff = body["tariff"]
    # buy_dal = 0.30 + 0.1108 + 0.0 = 0.4108
    assert abs(tariff["buy_dal"] - 0.4108) < 1e-6, f"buy_dal wrong: {tariff['buy_dal']}"
    # buy_normal = 0.40 + 0.1108 + 0.0 = 0.5108
    assert abs(tariff["buy_normal"] - 0.5108) < 1e-6, f"buy_normal wrong: {tariff['buy_normal']}"
    # sell_dal = 0.10 (no tax added)
    assert abs(tariff["sell_dal"] - 0.10) < 1e-6
    # sell_normal = 0.10
    assert abs(tariff["sell_normal"] - 0.10) < 1e-6


# ---------------------------------------------------------------------------
# GET /api/energy/prices — tibber contract
# ---------------------------------------------------------------------------


def test_prices_tibber_contract_returns_points(energy_client):
    client, engine, _app = energy_client
    _login(client)
    _make_active_tibber_contract(engine)
    _make_tibber_prices(engine, count=3)

    # Use a wide enough window to include our test prices.
    start = (datetime.now(UTC) - timedelta(hours=2)).isoformat()
    end = (datetime.now(UTC) + timedelta(hours=2)).isoformat()
    resp = client.get("/api/energy/prices", params={"start": start, "end": end})
    assert resp.status_code == 200
    body = resp.json()

    assert body["kind"] == "tibber"
    assert body["tariff"] is None
    assert isinstance(body["points"], list)
    assert len(body["points"]) == 3

    # Verify ascending order.
    starts_at_list = [p["starts_at"] for p in body["points"]]
    assert starts_at_list == sorted(starts_at_list)

    # Check buy/sell calculations: buy=total=0.245, sell=total-energy_tax-sell_adjust=0.245-0.1108-0.0
    for p in body["points"]:
        assert abs(p["buy"] - 0.245) < 1e-6
        assert abs(p["sell"] - (0.245 - 0.1108)) < 1e-4
        assert p["level"] == "NORMAL"


def test_prices_tibber_limit_caps_results(energy_client):
    client, engine, _app = energy_client
    _login(client)
    _make_active_tibber_contract(engine)
    _make_tibber_prices(engine, count=5)

    start = (datetime.now(UTC) - timedelta(hours=3)).isoformat()
    end = (datetime.now(UTC) + timedelta(hours=2)).isoformat()
    resp = client.get(
        "/api/energy/prices", params={"start": start, "end": end, "limit": 2}
    )
    assert resp.status_code == 200
    body = resp.json()
    assert len(body["points"]) <= 2


# ---------------------------------------------------------------------------
# GET /api/energy/costs — auth
# ---------------------------------------------------------------------------


def test_costs_unauthenticated_returns_401(energy_client):
    client, _, _app = energy_client
    resp = client.get("/api/energy/costs")
    assert resp.status_code == 401


# ---------------------------------------------------------------------------
# GET /api/energy/costs — empty
# ---------------------------------------------------------------------------


def test_costs_empty_returns_empty(energy_client):
    client, _, _app = energy_client
    _login(client)
    resp = client.get("/api/energy/costs")
    assert resp.status_code == 200
    body = resp.json()
    assert body["items"] == []
    assert body["total"] == 0


# ---------------------------------------------------------------------------
# GET /api/energy/costs — with data
# ---------------------------------------------------------------------------


def test_costs_returns_sorted_ascending(energy_client):
    client, engine, _app = energy_client
    _login(client)
    _make_active_manual_contract(engine)
    _make_cost_periods(engine, count=3)

    resp = client.get("/api/energy/costs")
    assert resp.status_code == 200
    body = resp.json()
    assert body["total"] == 3

    period_starts = [item["period_start"] for item in body["items"]]
    assert period_starts == sorted(period_starts), "Items must be ascending by period_start"


def test_costs_limit_caps_results(energy_client):
    client, engine, _app = energy_client
    _login(client)
    _make_active_manual_contract(engine)
    _make_cost_periods(engine, count=5)

    resp = client.get("/api/energy/costs?limit=2")
    assert resp.status_code == 200
    body = resp.json()
    assert body["total"] <= 2
    assert len(body["items"]) <= 2


def test_costs_schema_fields_present(energy_client):
    client, engine, _app = energy_client
    _login(client)
    _make_active_manual_contract(engine)
    _make_cost_periods(engine, count=1)

    resp = client.get("/api/energy/costs")
    assert resp.status_code == 200
    item = resp.json()["items"][0]
    for field in (
        "period_start",
        "d1_kwh", "d2_kwh", "r1_kwh", "r2_kwh",
        "import_cost", "export_revenue", "net_cost",
        "currency", "degraded",
    ):
        assert field in item, f"Missing field: {field}"


# ---------------------------------------------------------------------------
# GET /api/energy/costs/summary — auth
# ---------------------------------------------------------------------------


def test_summary_unauthenticated_returns_401(energy_client):
    client, _, _app = energy_client
    resp = client.get("/api/energy/costs/summary")
    assert resp.status_code == 401


# ---------------------------------------------------------------------------
# GET /api/energy/costs/summary — empty
# ---------------------------------------------------------------------------


def test_summary_empty_returns_zeros(energy_client):
    client, _, _app = energy_client
    _login(client)
    resp = client.get("/api/energy/costs/summary")
    assert resp.status_code == 200
    body = resp.json()
    assert body["period_count"] == 0
    assert body["metered_net"] == 0.0
    assert "total_payable" in body
    assert "currency" in body


# ---------------------------------------------------------------------------
# GET /api/energy/costs/summary — with data
# ---------------------------------------------------------------------------


def test_summary_returns_correct_structure(energy_client):
    client, engine, _app = energy_client
    _login(client)
    _make_active_manual_contract(engine)
    _make_cost_periods(engine, count=2)

    start = (datetime.now(UTC) - timedelta(hours=3)).isoformat()
    end = datetime.now(UTC).isoformat()
    resp = client.get(
        "/api/energy/costs/summary", params={"start": start, "end": end}
    )
    assert resp.status_code == 200
    body = resp.json()
    for field in (
        "currency",
        "metered_import",
        "metered_export",
        "metered_net",
        "fixed_costs",
        "credits",
        "total_payable",
        "period_count",
        "degraded_count",
        "days",
    ):
        assert field in body, f"Missing field in summary: {field}"


# ---------------------------------------------------------------------------
# GET /api/energy/dsmr/latest — auth
# ---------------------------------------------------------------------------


def test_dsmr_latest_unauthenticated_returns_401(energy_client):
    client, _, _app = energy_client
    resp = client.get("/api/energy/dsmr/latest")
    assert resp.status_code == 401


# ---------------------------------------------------------------------------
# GET /api/energy/dsmr/latest — no data
# ---------------------------------------------------------------------------


def test_dsmr_latest_no_data_returns_not_found(energy_client):
    client, _, _app = energy_client
    _login(client)
    resp = client.get("/api/energy/dsmr/latest")
    assert resp.status_code == 200
    body = resp.json()
    assert body["found"] is False
    assert body["recorded_at"] is None
    assert body["payload"] is None


# ---------------------------------------------------------------------------
# GET /api/energy/dsmr/latest — with data
# ---------------------------------------------------------------------------


def test_dsmr_latest_returns_most_recent(energy_client):
    client, engine, _app = energy_client
    _login(client)

    # Insert two readings; the more recent one should be returned.
    older = datetime.now(UTC) - timedelta(minutes=5)
    newer = datetime.now(UTC) - timedelta(seconds=30)

    with Session(engine) as session:
        session.add(DsmrReading(recorded_at=older, source_id=1, payload={"order": "first"}))
        session.add(DsmrReading(recorded_at=newer, source_id=2, payload={"order": "second"}))
        session.commit()

    resp = client.get("/api/energy/dsmr/latest")
    assert resp.status_code == 200
    body = resp.json()
    assert body["found"] is True
    assert body["payload"]["order"] == "second"
    assert body["recorded_at"] is not None


# ---------------------------------------------------------------------------
# POST /api/energy/costs/recompute — auth / CSRF
# ---------------------------------------------------------------------------


def test_recompute_unauthenticated_returns_401(energy_client):
    client, _, _app = energy_client
    now = datetime.now(UTC)
    resp = client.post(
        "/api/energy/costs/recompute",
        params={"start": now.isoformat(), "end": (now + timedelta(hours=1)).isoformat()},
    )
    assert resp.status_code == 401


def test_recompute_missing_csrf_returns_403(energy_client):
    client, _, _app = energy_client
    _login(client)
    now = datetime.now(UTC)
    resp = client.post(
        "/api/energy/costs/recompute",
        params={"start": now.isoformat(), "end": (now + timedelta(hours=1)).isoformat()},
    )
    assert resp.status_code == 403


# ---------------------------------------------------------------------------
# POST /api/energy/costs/recompute — validation
# ---------------------------------------------------------------------------


def test_recompute_end_before_start_returns_422(energy_client):
    client, _, _app = energy_client
    _login(client)
    now = datetime.now(UTC)
    resp = client.post(
        "/api/energy/costs/recompute",
        params={
            "start": now.isoformat(),
            "end": (now - timedelta(hours=1)).isoformat(),
        },
        headers={"X-CSRF-Token": _CSRF},
    )
    assert resp.status_code == 422


def test_recompute_window_too_large_returns_422(energy_client):
    client, _, _app = energy_client
    _login(client)
    now = datetime.now(UTC)
    resp = client.post(
        "/api/energy/costs/recompute",
        params={
            "start": (now - timedelta(days=400)).isoformat(),
            "end": now.isoformat(),
        },
        headers={"X-CSRF-Token": _CSRF},
    )
    assert resp.status_code == 422


# ---------------------------------------------------------------------------
# POST /api/energy/costs/recompute — success (idempotent)
# ---------------------------------------------------------------------------


def test_recompute_returns_count(energy_client):
    client, _, _app = energy_client
    _login(client)
    # A window with no data is fine — recompute returns 0 but is not an error.
    now = datetime.now(UTC)
    params = {
        "start": (now - timedelta(hours=1)).isoformat(),
        "end": now.isoformat(),
    }
    resp = client.post(
        "/api/energy/costs/recompute",
        params=params,
        headers={"X-CSRF-Token": _CSRF},
    )
    assert resp.status_code == 200
    body = resp.json()
    assert "recomputed" in body
    assert isinstance(body["recomputed"], int)


def test_recompute_is_idempotent(energy_client):
    """Calling recompute twice with the same window must produce the same result."""
    client, _, _app = energy_client
    _login(client)
    now = datetime.now(UTC)
    params = {
        "start": (now - timedelta(hours=1)).isoformat(),
        "end": now.isoformat(),
    }
    headers = {"X-CSRF-Token": _CSRF}

    resp1 = client.post("/api/energy/costs/recompute", params=params, headers=headers)
    resp2 = client.post("/api/energy/costs/recompute", params=params, headers=headers)
    assert resp1.status_code == 200
    assert resp2.status_code == 200
    assert resp1.json()["recomputed"] == resp2.json()["recomputed"]


# ---------------------------------------------------------------------------
# POST /api/energy/tibber/test — auth / CSRF
# ---------------------------------------------------------------------------


def test_tibber_test_unauthenticated_returns_401(energy_client):
    client, _, _app = energy_client
    resp = client.post("/api/energy/tibber/test")
    assert resp.status_code == 401


def test_tibber_test_missing_csrf_returns_403(energy_client):
    client, _, _app = energy_client
    _login(client)
    resp = client.post("/api/energy/tibber/test")
    assert resp.status_code == 403


# ---------------------------------------------------------------------------
# POST /api/energy/tibber/test — token empty → 400 config-error
# ---------------------------------------------------------------------------


def test_tibber_test_no_token_returns_config_error(energy_client):
    """When tibber_api_token is empty, expect 400 config-error regardless of CSRF."""
    client, _, _app = energy_client
    _login(client)
    resp = client.post(
        "/api/energy/tibber/test",
        headers={"X-CSRF-Token": _CSRF},
    )
    # Token is empty by default (no config in test DB).
    assert resp.status_code == 400
    body = resp.json()
    assert body["result"] == "config-error"
    assert "message" in body


# ---------------------------------------------------------------------------
# POST /api/energy/tibber/test — mock success
# ---------------------------------------------------------------------------


def test_tibber_test_success(energy_client):
    """Token stored in DB app_config + mocked HTTP → 200 success with price data."""
    client, engine, _app = energy_client
    _login(client)

    # Set TIBBER_API_TOKEN in the app_config table so get_app_settings returns it.
    _set_app_config(engine, "TIBBER_API_TOKEN", "fake-tibber-token")

    mock_price = PricePoint(
        starts_at=datetime(2026, 6, 23, 14, 0, 0, tzinfo=UTC),
        total=0.245,
        energy=0.18,
        tax=0.065,
        currency="EUR",
        level="NORMAL",
        resolution="QUARTER_HOURLY",
    )

    with patch(
        "app.api.routes.api.energy.fetch_current_price",
        return_value=mock_price,
    ):
        resp = client.post(
            "/api/energy/tibber/test",
            headers={"X-CSRF-Token": _CSRF},
        )

    assert resp.status_code == 200
    body = resp.json()
    assert body["result"] == "success"
    assert body["price"] is not None
    assert body["price"]["total"] == 0.245
    assert body["price"]["currency"] == "EUR"
    assert body["price"]["level"] == "NORMAL"

    # Token must NOT appear anywhere in the response.
    assert "fake-tibber-token" not in str(body)


# ---------------------------------------------------------------------------
# POST /api/energy/tibber/test — mock TibberAuthError → 502
# ---------------------------------------------------------------------------


def test_tibber_test_auth_error_returns_502(energy_client):
    """Bad token stored in DB + mocked TibberAuthError → 502 failed."""
    client, engine, _app = energy_client
    _login(client)

    _set_app_config(engine, "TIBBER_API_TOKEN", "bad-tibber-token")

    with patch(
        "app.api.routes.api.energy.fetch_current_price",
        side_effect=TibberAuthError("auth failed"),
    ):
        resp = client.post(
            "/api/energy/tibber/test",
            headers={"X-CSRF-Token": _CSRF},
        )

    assert resp.status_code == 502
    body = resp.json()
    assert body["result"] == "failed"
    assert "bad-tibber-token" not in str(body)


# ---------------------------------------------------------------------------
# POST /api/energy/tibber/test — mock TibberError → 502
# ---------------------------------------------------------------------------


def test_tibber_test_network_error_returns_502(energy_client):
    """Token in DB + mocked TibberError (network timeout) → 502 failed."""
    client, engine, _app = energy_client
    _login(client)

    _set_app_config(engine, "TIBBER_API_TOKEN", "some-tibber-token")

    with patch(
        "app.api.routes.api.energy.fetch_current_price",
        side_effect=TibberError("network timeout"),
    ):
        resp = client.post(
            "/api/energy/tibber/test",
            headers={"X-CSRF-Token": _CSRF},
        )

    assert resp.status_code == 502
    body = resp.json()
    assert body["result"] == "failed"
    assert "some-tibber-token" not in str(body)


# ---------------------------------------------------------------------------
# POST /api/energy/tibber/test — token never in response (extra check)
# ---------------------------------------------------------------------------


def test_tibber_test_token_not_in_response(energy_client):
    """Even in the success response, the Tibber token must not appear."""
    client, engine, _app = energy_client
    _login(client)

    secret_token = "super-secret-tibber-token-xyz"
    _set_app_config(engine, "TIBBER_API_TOKEN", secret_token)

    mock_price = PricePoint(
        starts_at=datetime(2026, 6, 23, 14, 0, 0, tzinfo=UTC),
        total=0.30,
        energy=0.22,
        tax=0.08,
        currency="EUR",
        level="CHEAP",
        resolution="QUARTER_HOURLY",
    )

    with patch(
        "app.api.routes.api.energy.fetch_current_price",
        return_value=mock_price,
    ):
        resp = client.post(
            "/api/energy/tibber/test",
            headers={"X-CSRF-Token": _CSRF},
        )

    assert resp.status_code == 200
    assert secret_token not in resp.text


