test_archive_updated_scope.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. """Live archive updates reach only sockets that may see the archive's printer,
  2. or a printer one of its prints ran on (archive redesign)."""
  3. from __future__ import annotations
  4. from types import SimpleNamespace
  5. from unittest.mock import AsyncMock, patch
  6. import pytest
  7. from backend.app.core import websocket
  8. from backend.app.core.printer_scope import PrinterScope
  9. pytestmark = pytest.mark.asyncio
  10. def _socket(printer_ids):
  11. scope = PrinterScope() if printer_ids is None else PrinterScope(frozenset(printer_ids))
  12. return SimpleNamespace(state=SimpleNamespace(bambuddy_printer_scope=scope), send_text=AsyncMock())
  13. @pytest.mark.parametrize(
  14. ("archive_printer", "expected"),
  15. [
  16. (1, {"team_a": True, "team_b": False, "everyone": True}),
  17. (None, {"team_a": True, "team_b": True, "everyone": True}), # printer-less: in every scope
  18. (websocket._UNKNOWN_PRINTER, {"team_a": False, "team_b": False, "everyone": True}),
  19. ],
  20. )
  21. async def test_an_update_follows_the_archive_printer(archive_printer, expected):
  22. manager = websocket.ConnectionManager()
  23. sockets = {"team_a": _socket({1}), "team_b": _socket({2}), "everyone": _socket(None)}
  24. manager.active_connections = list(sockets.values())
  25. with patch.object(websocket, "_archive_printer_ids", new=AsyncMock(return_value=(archive_printer, set()))):
  26. await manager.send_archive_updated({"id": 7, "cost": 1.5})
  27. assert {name: s.send_text.await_count == 1 for name, s in sockets.items()} == expected
  28. async def test_an_update_reaches_the_printers_its_prints_ran_on():
  29. """Plate 1 printed on 1, plate 2 on 2: the archive names 2, both see it."""
  30. manager = websocket.ConnectionManager()
  31. sockets = {"team_a": _socket({1}), "team_b": _socket({2}), "team_c": _socket({3})}
  32. manager.active_connections = list(sockets.values())
  33. with patch.object(websocket, "_archive_printer_ids", new=AsyncMock(return_value=(2, {1, 2}))):
  34. await manager.send_archive_updated({"id": 7, "cost": 1.5})
  35. assert {name: s.send_text.await_count == 1 for name, s in sockets.items()} == {
  36. "team_a": True,
  37. "team_b": True,
  38. "team_c": False,
  39. }
  40. async def test_a_socket_that_sees_only_a_print_of_it_is_not_told_its_printer():
  41. """The archive names 2, outside team_a's scope (#1727)."""
  42. import json
  43. manager = websocket.ConnectionManager()
  44. team_a, team_b = _socket({1}), _socket({2})
  45. manager.active_connections = [team_a, team_b]
  46. with patch.object(websocket, "_archive_printer_ids", new=AsyncMock(return_value=(2, {1, 2}))):
  47. await manager.send_archive_updated({"id": 7})
  48. assert json.loads(team_a.send_text.await_args.args[0]) == {"type": "archive_updated", "data": {}}
  49. assert json.loads(team_b.send_text.await_args.args[0])["printer_id"] == 2
  50. async def test_an_archive_that_cannot_be_looked_up_reaches_only_unrestricted_sockets():
  51. with patch("backend.app.core.database.async_session", side_effect=RuntimeError("db down")):
  52. assert await websocket._archive_printer_ids(7) == (websocket._UNKNOWN_PRINTER, set())
  53. assert await websocket._archive_printer_ids(None) == (websocket._UNKNOWN_PRINTER, set())