63 lines
1.7 KiB
Python
63 lines
1.7 KiB
Python
import asyncio
|
|||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from app.rounds.events import RoundEventBroadcaster, RoundEventCapacityError
|
||
|
|
|
||
|
|
|
||
|
|
async def test_publish_wakes_up_subscriber():
|
||
|
|
broadcaster = RoundEventBroadcaster()
|
||
|
|
queue = broadcaster.subscribe()
|
||
|
|
|
||
|
|
broadcaster.publish()
|
||
|
|
|
||
|
|
await asyncio.wait_for(queue.get(), timeout=1)
|
||
|
|
|
||
|
|
|
||
|
|
async def test_publish_with_no_subscribers_does_not_raise():
|
||
|
|
broadcaster = RoundEventBroadcaster()
|
||
|
|
broadcaster.publish() # no subscribers yet — must be a no-op, not an error
|
||
|
|
|
||
|
|
|
||
|
|
async def test_publish_coalesces_when_subscriber_has_not_drained():
|
||
|
|
"""The queue is maxsize=1: a second publish() before the subscriber reads
|
||
|
|
the first notification must not block or raise — it's fine to drop it,
|
||
|
|
since the subscriber will refetch full state anyway on the first one."""
|
||
|
|
broadcaster = RoundEventBroadcaster()
|
||
|
|
queue = broadcaster.subscribe()
|
||
|
|
|
||
|
|
broadcaster.publish()
|
||
|
|
broadcaster.publish() # would raise QueueFull if not guarded
|
||
|
|
|
||
|
|
assert queue.qsize() == 1
|
||
|
|
|
||
|
|
|
||
|
|
async def test_unsubscribe_stops_delivery():
|
||
|
|
broadcaster = RoundEventBroadcaster()
|
||
|
|
queue = broadcaster.subscribe()
|
||
|
|
broadcaster.unsubscribe(queue)
|
||
|
|
|
||
|
|
broadcaster.publish()
|
||
|
|
|
||
|
|
assert queue.empty()
|
||
|
|
|
||
|
|
|
||
|
|
async def test_subscribe_rejects_past_the_cap():
|
||
|
|
broadcaster = RoundEventBroadcaster(max_subscribers=3)
|
||
|
|
for _ in range(3):
|
||
|
|
broadcaster.subscribe()
|
||
|
|
|
||
|
|
with pytest.raises(RoundEventCapacityError):
|
||
|
|
broadcaster.subscribe()
|
||
|
|
|
||
|
|
|
||
|
|
async def test_unsubscribe_frees_a_capacity_slot():
|
||
|
|
broadcaster = RoundEventBroadcaster(max_subscribers=1)
|
||
|
|
queue = broadcaster.subscribe()
|
||
|
|
|
||
|
|
with pytest.raises(RoundEventCapacityError):
|
||
|
|
broadcaster.subscribe()
|
||
|
|
|
||
|
|
broadcaster.unsubscribe(queue)
|
||
|
|
broadcaster.subscribe() # no longer at capacity
|