test_plate_clear_notification.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. """Integration tests for the plate-clear-required notification (#2525).
  2. The event is opt-in: it fires after every print, at the same moment as the
  3. print-complete alert, so a provider only receives it when the toggle is
  4. explicitly enabled.
  5. """
  6. from unittest.mock import AsyncMock, patch
  7. import pytest
  8. from httpx import AsyncClient
  9. from backend.app.services.notification_service import notification_service
  10. class TestPlateClearNotificationDispatch:
  11. @pytest.mark.asyncio
  12. @pytest.mark.integration
  13. async def test_sends_to_a_provider_that_opted_in(self, notification_provider_factory, db_session):
  14. await notification_provider_factory(name="Opted In", on_plate_clear_required=True)
  15. send = AsyncMock()
  16. with patch.object(notification_service, "_send_to_providers", send):
  17. await notification_service.on_plate_clear_required(1, "Workshop", db_session)
  18. assert send.await_count == 1
  19. providers = send.await_args.args[0]
  20. assert [p.name for p in providers] == ["Opted In"]
  21. assert send.await_args.args[4] == "plate_clear_required"
  22. # _build_message_from_template folds in app_name/timestamp; the caller's
  23. # own variable is what matters here.
  24. assert send.await_args.kwargs["variables"]["printer"] == "Workshop"
  25. @pytest.mark.asyncio
  26. @pytest.mark.integration
  27. async def test_silent_for_a_provider_that_did_not_opt_in(self, notification_provider_factory, db_session):
  28. await notification_provider_factory(name="Default Off", on_plate_clear_required=False)
  29. send = AsyncMock()
  30. with patch.object(notification_service, "_send_to_providers", send):
  31. await notification_service.on_plate_clear_required(1, "Workshop", db_session)
  32. send.assert_not_awaited()
  33. @pytest.mark.asyncio
  34. @pytest.mark.integration
  35. async def test_skips_a_provider_scoped_to_a_different_printer(self, notification_provider_factory, db_session):
  36. await notification_provider_factory(name="Other Printer", on_plate_clear_required=True, printer_id=99)
  37. send = AsyncMock()
  38. with patch.object(notification_service, "_send_to_providers", send):
  39. await notification_service.on_plate_clear_required(1, "Workshop", db_session)
  40. send.assert_not_awaited()
  41. class TestPlateClearProviderField:
  42. @pytest.mark.asyncio
  43. @pytest.mark.integration
  44. async def test_defaults_to_off_on_create_and_round_trips_on_update(self, async_client: AsyncClient):
  45. create = await async_client.post(
  46. "/api/v1/notifications/",
  47. json={
  48. "name": "Plate Clear Test",
  49. "provider_type": "ntfy",
  50. "enabled": True,
  51. "config": {"server": "https://ntfy.sh", "topic": "test-topic"},
  52. },
  53. )
  54. assert create.status_code in (200, 201), create.text
  55. provider_id = create.json()["id"]
  56. assert create.json()["on_plate_clear_required"] is False
  57. update = await async_client.patch(
  58. f"/api/v1/notifications/{provider_id}",
  59. json={"on_plate_clear_required": True},
  60. )
  61. assert update.status_code == 200, update.text
  62. assert update.json()["on_plate_clear_required"] is True