"""Auth unit tests — mint/verify/revoke/expiry/scopes over a temp SQLite DB."""
import auth


def test_mint_returns_plaintext_and_verifies():
    tok = auth.mint("acme", scopes="emotion features", ttl_days=31)
    assert isinstance(tok, str) and len(tok) > 20
    p = auth.verify(tok)
    assert p is not None
    assert p.account == "acme"
    assert p.scopes == frozenset({"emotion", "features"})
    assert p.has_scope("emotion") and not p.has_scope("separate")


def test_wildcard_scope():
    tok = auth.mint("star", scopes="*", ttl_days=31)
    p = auth.verify(tok)
    assert p.has_scope("anything")


def test_unknown_token_is_none():
    assert auth.verify("definitely-not-a-real-token") is None
    assert auth.verify("") is None


def test_revoke_invalidates():
    tok = auth.mint("rev", scopes="*", ttl_days=31)
    tid = next(r["id"] for r in auth.list_tokens() if r["account"] == "rev")
    assert auth.verify(tok) is not None
    assert auth.revoke(tid) is True
    assert auth.verify(tok) is None


def test_expired_token_is_none():
    tok = auth.mint("expired", scopes="*", ttl_days=-1)  # already in the past
    assert auth.verify(tok) is None


def test_never_expires():
    tok = auth.mint("forever", scopes="*", ttl_days=None)
    p = auth.verify(tok)
    assert p is not None and p.expires_at is None


def test_only_hash_is_stored():
    tok = auth.mint("secrethash", scopes="*", ttl_days=31)
    import db
    with db.cursor() as c:
        rows = [dict(r) for r in c.execute("SELECT token_hash, prefix FROM tokens")]
    # the plaintext must never appear verbatim in storage
    assert all(tok != r["token_hash"] for r in rows)
    assert any(r["prefix"] == tok[:6] for r in rows)


def test_dev_bootstrap_token():
    # conftest sets DOUANIER_DEV_TOKEN=test-secret → recognized as wildcard
    p = auth.verify("test-secret")
    assert p is not None and p.account == "dev" and p.has_scope("emotion")
