from __future__ import annotations from datetime import datetime, timezone, timedelta from src.auth import OAuthContext, _parse_scope, public_oauth_context, oauth_warning_messages, REQUIRED_OAUTH_SCOPES def test_parse_scope_accepts_space_and_commas(): assert _parse_scope("openid profile jobs,manage-repos write-repos") >= {"openid", "profile", "jobs", "manage-repos", "write-repos"} def test_public_oauth_context_never_exposes_token(): ctx = OAuthContext( username="alice", token="hf_secret_token", profile={"preferred_username": "alice", "picture": "https://example.com/a.png"}, scopes=set(REQUIRED_OAUTH_SCOPES), expires_at=datetime.now(timezone.utc) + timedelta(hours=1), is_pro=True, can_pay=False, ) data = public_oauth_context(ctx) assert "token" not in str(data).lower() assert "hf_secret_token" not in str(data) assert data["username"] == "alice" assert data["missing_scopes"] == [] def test_oauth_warnings_report_missing_scopes_and_billing(): ctx = OAuthContext(username="alice", token="secret", scopes={"jobs"}, can_pay=False) warnings = "\n".join(oauth_warning_messages(ctx)) assert "Missing OAuth scopes" in warnings assert "payment" in warnings or "billing" in warnings