"""Tests for require_bearer (Python).

Mirror of auth.test.ts: valid bearer, missing header, lowercase 'bearer',
whitespace-only token, empty token, wrong token, case-insensitive header
lookup, constant-time comparison sanity (matched + byte-flipped both
compared, no early exit), and empty/whitespace expected token.
"""

from __future__ import annotations

import pytest

from auth import require_bearer

TOKEN = "super-secret-token-xyz"


def test_valid_bearer_passes() -> None:
    assert require_bearer({"authorization": f"Bearer {TOKEN}"}, TOKEN) is None


def test_missing_header_returns_401() -> None:
    res = require_bearer({}, TOKEN)
    assert res is not None
    assert res.status_code == 401


def test_lowercase_bearer_prefix_is_accepted() -> None:
    assert require_bearer({"Authorization": f"bearer {TOKEN}"}, TOKEN) is None


def test_whitespace_only_token_fails() -> None:
    res = require_bearer({"authorization": "Bearer    "}, TOKEN)
    assert res is not None
    assert res.status_code == 401


def test_empty_token_after_prefix_fails() -> None:
    res = require_bearer({"authorization": "Bearer "}, TOKEN)
    assert res is not None
    assert res.status_code == 401


def test_wrong_token_fails() -> None:
    res = require_bearer({"authorization": f"Bearer not-{TOKEN}"}, TOKEN)
    assert res is not None
    assert res.status_code == 401


@pytest.mark.parametrize(
    "header_name",
    ["authorization", "Authorization", "AUTHORIZATION"],
)
def test_case_insensitive_header_lookup(header_name: str) -> None:
    assert require_bearer({header_name: f"Bearer {TOKEN}"}, TOKEN) is None


def test_constant_time_compare_matched_and_byte_flipped() -> None:
    """Both inputs hit the comparator -- no prefix-match short-circuit."""
    matched = TOKEN
    flipped = TOKEN[:-1] + ("a" if TOKEN.endswith("z") else "z")
    assert matched != flipped
    assert len(matched) == len(flipped)

    ok = require_bearer({"authorization": f"Bearer {matched}"}, TOKEN)
    bad = require_bearer({"authorization": f"Bearer {flipped}"}, TOKEN)

    assert ok is None
    assert bad is not None and bad.status_code == 401

    # Length-mismatch tokens also fail (no padding bypass).
    short = require_bearer(
        {"authorization": f"Bearer {TOKEN[:5]}"}, TOKEN
    )
    assert short is not None and short.status_code == 401

    longer = require_bearer(
        {"authorization": f"Bearer {TOKEN}extra"}, TOKEN
    )
    assert longer is not None and longer.status_code == 401


def test_empty_expected_token_always_fails() -> None:
    req = {"authorization": f"Bearer {TOKEN}"}
    assert require_bearer(req, "").status_code == 401  # type: ignore[union-attr]
    assert require_bearer(req, "   ").status_code == 401  # type: ignore[union-attr]
