feat: add Spotify authentication and sessions
This commit is contained in:
parent
000b435b9a
commit
cdab1b4dd5
5 changed files with 304 additions and 0 deletions
45
backend/tests/test_spotify_auth.py
Normal file
45
backend/tests/test_spotify_auth.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
"""Tests for Spotify PKCE and token handling."""
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
import httpx2
|
||||
|
||||
from app.adapters.spotify.auth import (
|
||||
TokenSet,
|
||||
derive_code_challenge,
|
||||
refresh_access_token,
|
||||
)
|
||||
|
||||
|
||||
def test_code_challenge_is_unpadded_base64url_sha256() -> None:
|
||||
verifier = "a-fixed-code-verifier"
|
||||
expected = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest())
|
||||
|
||||
challenge = derive_code_challenge(verifier)
|
||||
|
||||
assert challenge == expected.rstrip(b"=").decode()
|
||||
assert "=" not in challenge
|
||||
|
||||
|
||||
def test_refresh_keeps_existing_refresh_token_when_omitted() -> None:
|
||||
async def run() -> None:
|
||||
async def handler(request: httpx2.Request) -> httpx2.Response:
|
||||
assert request.url == "https://accounts.spotify.com/api/token"
|
||||
return httpx2.Response(200, json={"access_token": "new", "expires_in": 3600})
|
||||
|
||||
tokens = TokenSet("old", "keep-me", time.monotonic() + 3600)
|
||||
async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as http:
|
||||
refreshed = await refresh_access_token(http, client_id="client", tokens=tokens)
|
||||
|
||||
assert refreshed.access_token == "new"
|
||||
assert refreshed.refresh_token == "keep-me"
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_token_expiry_uses_sixty_second_skew() -> None:
|
||||
assert TokenSet("access", "refresh", time.monotonic() + 59).is_expired
|
||||
assert not TokenSet("access", "refresh", time.monotonic() + 61).is_expired
|
||||
Loading…
Add table
Add a link
Reference in a new issue