"""AURORA-1845: user/форма читаются из БД один раз на соединение, а не на каждое сообщение.""" from types import SimpleNamespace from unittest.mock import AsyncMock, MagicMock import pytest from src.api.v1.websocket import ConnectionCache, FormEventProcess def _processor(user=None, form=object()): proc = FormEventProcess(MagicMock()) proc.user_service = MagicMock(get=AsyncMock(return_value=user or SimpleNamespace(id=7, role_id=2))) proc.bf_service = MagicMock(get=AsyncMock(return_value=form)) proc.sheet_service = MagicMock(update_cell=AsyncMock(return_value=[])) return proc EVENT = {"event": "cell_updated", "data": {"line_id": 1, "column": "c", "value": 1}} async def _send(proc, cache, n): for _ in range(n): await proc.process(event_data=EVENT, form_id=5, user_id=7, sheet="S", cache=cache) @pytest.mark.asyncio async def test_cache_reads_user_and_form_once_per_connection(): proc = _processor() cache = ConnectionCache() await _send(proc, cache, 5) assert proc.user_service.get.await_count == 1 assert proc.bf_service.get.await_count == 1 assert proc.sheet_service.update_cell.await_count == 5 @pytest.mark.asyncio async def test_without_cache_reads_every_message(): proc = _processor() await _send(proc, None, 3) assert proc.user_service.get.await_count == 3 assert proc.bf_service.get.await_count == 3 @pytest.mark.asyncio async def test_cache_expires_after_ttl(): now = [0.0] cache = ConnectionCache(ttl=30, clock=lambda: now[0]) proc = _processor() await _send(proc, cache, 2) now[0] = 31 await _send(proc, cache, 2) assert proc.user_service.get.await_count == 2 assert proc.bf_service.get.await_count == 2 @pytest.mark.asyncio async def test_missing_form_is_not_cached(): proc = _processor(form=None) cache = ConnectionCache() for _ in range(3): res = await proc.process(event_data=EVENT, form_id=5, user_id=7, sheet="S", cache=cache) assert res is None assert proc.bf_service.get.await_count == 3 proc.sheet_service.update_cell.assert_not_awaited() @pytest.mark.asyncio async def test_missing_user_is_not_cached(): proc = _processor() proc.user_service.get = AsyncMock(return_value=None) cache = ConnectionCache() assert cache.get_user(7) is None cache.set_user(None) assert cache.get_user(7) is None