import jwt import pytest from fastapi import FastAPI, HTTPException from fastapi.testclient import TestClient from modules.auth.supabase_bearer import verify_supabase_token_dep from routers.tlsync_token import TLSYNC_TOKEN_AUDIENCE, create_tlsync_token, router def test_create_tlsync_token_is_short_lived_and_signed(monkeypatch): monkeypatch.setenv("TLSYNC_SECRET", "test-tlsync-secret-with-at-least-32-bytes") monkeypatch.setenv("TLSYNC_TOKEN_TTL_SECONDS", "120") response = create_tlsync_token({"sub": "user-123"}) assert response["token_type"] == "Bearer" assert response["expires_in"] == 120 assert response["token"] payload = jwt.decode( response["token"], "test-tlsync-secret-with-at-least-32-bytes", algorithms=["HS256"], audience=TLSYNC_TOKEN_AUDIENCE, ) assert payload["sub"] == "user-123" assert payload["exp"] == response["expires_at"] assert payload["exp"] - payload["iat"] == 120 assert payload["jti"] def test_create_tlsync_token_requires_tlsync_secret(monkeypatch): monkeypatch.delenv("TLSYNC_SECRET", raising=False) with pytest.raises(HTTPException) as excinfo: create_tlsync_token({"sub": "user-123"}) assert excinfo.value.status_code == 503 def test_create_tlsync_token_requires_authenticated_subject(monkeypatch): monkeypatch.setenv("TLSYNC_SECRET", "test-tlsync-secret-with-at-least-32-bytes") with pytest.raises(HTTPException) as excinfo: create_tlsync_token({}) assert excinfo.value.status_code == 401 def test_tlsync_token_route_uses_authenticated_user_claims(monkeypatch): monkeypatch.setenv("TLSYNC_SECRET", "test-tlsync-secret-with-at-least-32-bytes") monkeypatch.setenv("TLSYNC_TOKEN_TTL_SECONDS", "60") app = FastAPI() app.include_router(router, prefix="/api/tlsync") app.dependency_overrides[verify_supabase_token_dep] = lambda: {"sub": "route-user-123"} response = TestClient(app).get("/api/tlsync/token", headers={"Authorization": "Bearer supabase-jwt"}) assert response.status_code == 200 body = response.json() payload = jwt.decode( body["token"], "test-tlsync-secret-with-at-least-32-bytes", algorithms=["HS256"], audience=TLSYNC_TOKEN_AUDIENCE, ) assert payload["sub"] == "route-user-123" assert body["expires_in"] == 60