fix: harden request handling, pipeline containment, and startup boundaries

This commit is contained in:
Justin Visser 2026-08-10 21:50:48 +02:00
parent 2cc33a721c
commit 3555256a02
18 changed files with 656 additions and 107 deletions

View file

@ -3,10 +3,12 @@
import time
from collections.abc import AsyncGenerator
import pytest
from fastapi.testclient import TestClient
from pydantic import TypeAdapter
from app.adapters.spotify.auth import TokenSet
from app.adapters.spotify.errors import SpotifyAuthenticationError
from app.adapters.spotify.session import SessionStore, SpotifySession
from app.api.routes import SESSION_COOKIE_NAME
from app.api.schemas import StreamEvent
@ -37,13 +39,16 @@ class FakePipeline:
class FakePlaylistWriter:
"""Capture playlist writes without external calls."""
def __init__(self) -> None:
def __init__(self, error: Exception | None = None) -> None:
"""Create an empty write trace."""
self.error = error
self.name: str | None = None
self.track_uris: list[str] = []
async def create_playlist(self, name: str, description: str) -> CreatedPlaylist:
"""Record the prefixed name and return a stable playlist."""
if self.error is not None:
raise self.error
self.name = name
return CreatedPlaylist("playlist", "https://open.spotify.com/playlist/playlist")
@ -52,7 +57,13 @@ class FakePlaylistWriter:
self.track_uris = track_uris
def test_recommendations_stream_lines_validate_against_frozen_schemas() -> None:
def test_recommendations_stream_lines_validate_against_frozen_schemas(
monkeypatch: pytest.MonkeyPatch,
) -> None:
async def fail_if_polled(request: object) -> bool:
raise AssertionError("Request disconnect state must not be polled")
monkeypatch.setattr("starlette.requests.Request.is_disconnected", fail_if_polled)
app = create_app()
with TestClient(app) as client:
_authenticate(client, session_store=app.state.session_store)
@ -103,6 +114,26 @@ def test_playlist_endpoint_prefixes_name_and_adds_tracks() -> None:
assert writer.track_uris == ["spotify:track:track"]
def test_playlist_authentication_failure_signals_relogin() -> None:
app = create_app()
writer = FakePlaylistWriter(SpotifyAuthenticationError("expired"))
with TestClient(app) as client:
_authenticate(client, session_store=app.state.session_store)
app.state.spotify_client_factory = lambda session: writer
response = client.post(
"/api/playlists",
json={
"schema_version": 1,
"name": "Night drive",
"track_uris": ["spotify:track:track"],
},
)
assert response.status_code == 401
assert response.json() == {"detail": "Spotify authentication expired"}
def _authenticate(client: TestClient, session_store: SessionStore) -> None:
session_id = session_store.create(
SpotifySession(