44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
"""SSE-шина: доставка событий подписчику; эндпойнт /api/events требует вход."""
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
def test_hub_delivers_to_subscriber():
|
|
from app.core.events import EventHub
|
|
|
|
async def run():
|
|
hub = EventHub()
|
|
hub.bind_loop(asyncio.get_running_loop())
|
|
q = hub.subscribe(1)
|
|
hub.publish([1, 2], {"type": "match", "match_id": 5})
|
|
event = await asyncio.wait_for(q.get(), timeout=1)
|
|
assert event == {"type": "match", "match_id": 5}
|
|
hub.unsubscribe(1, q)
|
|
|
|
asyncio.run(run())
|
|
|
|
|
|
def test_hub_isolates_users():
|
|
from app.core.events import EventHub
|
|
|
|
async def run():
|
|
hub = EventHub()
|
|
hub.bind_loop(asyncio.get_running_loop())
|
|
q1 = hub.subscribe(1)
|
|
q2 = hub.subscribe(2)
|
|
hub.publish([2], {"type": "invitations"}) # только пользователю 2
|
|
got2 = await asyncio.wait_for(q2.get(), timeout=1)
|
|
assert got2 == {"type": "invitations"}
|
|
assert q1.empty() # пользователю 1 ничего не пришло
|
|
|
|
asyncio.run(run())
|
|
|
|
|
|
def test_events_requires_auth(client: TestClient):
|
|
# Без сессии SSE-эндпойнт не отдаёт поток (401 на зависимости get_current_user).
|
|
r = client.get("/api/events")
|
|
assert r.status_code == 401
|