test_spool_assignment_notifications.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. """Unit tests for spool assignment notification service."""
  2. import logging
  3. from types import SimpleNamespace
  4. from unittest.mock import AsyncMock, patch
  5. import pytest
  6. from backend.app.services.spool_assignment_notifications import notify_missing_spool_assignments_on_print_start
  7. class _FakeAssignmentsResult:
  8. def __init__(self, rows):
  9. self._rows = rows
  10. def fetchall(self):
  11. return self._rows
  12. class _FakeSession:
  13. def __init__(self, printer_name: str, assignments: list[SimpleNamespace]):
  14. self._printer = SimpleNamespace(name=printer_name)
  15. self._assignments = assignments
  16. async def __aenter__(self):
  17. return self
  18. async def __aexit__(self, exc_type, exc, tb):
  19. return False
  20. async def get(self, model, key):
  21. return self._printer
  22. async def execute(self, statement):
  23. return _FakeAssignmentsResult(self._assignments)
  24. @pytest.mark.asyncio
  25. async def test_missing_assignment_broadcasts_websocket_event_and_push_notification():
  26. """When a mapped tray is unassigned, service emits websocket and notification events."""
  27. logger = logging.getLogger(__name__)
  28. data = {
  29. "ams_mapping": [1],
  30. "raw_data": {},
  31. }
  32. # Assignment exists for A1 (global tray 0), but print uses A2 (global tray 1).
  33. assignments = [SimpleNamespace(ams_id=0, tray_id=0)]
  34. with (
  35. patch(
  36. "backend.app.services.spool_assignment_notifications.async_session",
  37. return_value=_FakeSession("Printer A", assignments),
  38. ),
  39. patch("backend.app.services.spool_assignment_notifications.printer_manager.get_status", return_value=None),
  40. patch(
  41. "backend.app.services.spool_assignment_notifications.ws_manager.send_missing_spool_assignment",
  42. new_callable=AsyncMock,
  43. ) as mock_ws,
  44. patch(
  45. "backend.app.services.spool_assignment_notifications.notification_service.on_print_missing_spool_assignment",
  46. new_callable=AsyncMock,
  47. ) as mock_notify,
  48. ):
  49. await notify_missing_spool_assignments_on_print_start(1, data, logger)
  50. mock_ws.assert_awaited_once()
  51. ws_kwargs = mock_ws.await_args.kwargs
  52. assert ws_kwargs["printer_id"] == 1
  53. assert ws_kwargs["printer_name"] == "Printer A"
  54. assert ws_kwargs["missing_slots"] == [{"slot": "A2", "profile": "Unknown", "color": "Unknown"}]
  55. mock_notify.assert_awaited_once()
  56. notify_kwargs = mock_notify.await_args.kwargs
  57. assert notify_kwargs["printer_id"] == 1
  58. assert notify_kwargs["printer_name"] == "Printer A"
  59. assert notify_kwargs["missing_slots"] == [{"slot": "A2", "profile": "Unknown", "color": "Unknown"}]