test_spoolman_slot_requests.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. """Spoolman slot requests the database would refuse are refused up front (SSA-8, SSA-9).
  2. An ams_id the table's CHECK does not admit (it allows AMS units 0-7, AMS-HT
  3. 128-191 and the external slot 255) came back as a 500. The link route also
  4. wrote the spool's tag to Spoolman before the local insert failed, leaving a
  5. half-applied link. And an archived Spoolman spool could be assigned to a slot,
  6. then charged the next print's usage; the built-in inventory refuses that.
  7. """
  8. from unittest.mock import AsyncMock, MagicMock, patch
  9. import pytest
  10. from httpx import AsyncClient
  11. from backend.tests.integration.test_spoolman_assignment_verification import ( # noqa: F401
  12. SPOOL,
  13. _spoolman_client,
  14. printer_id,
  15. )
  16. pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
  17. async def _assign(async_client, printer_id, spool=SPOOL, **slot):
  18. client = _spoolman_client()
  19. client.get_spool = AsyncMock(return_value=spool)
  20. with (
  21. patch("backend.app.api.routes.spoolman_inventory._get_client", AsyncMock(return_value=client)),
  22. patch("backend.app.api.routes.spoolman_inventory.printer_manager") as pm,
  23. ):
  24. pm.get_client = MagicMock(return_value=None)
  25. pm.get_status = MagicMock(return_value=None)
  26. response = await async_client.post(
  27. "/api/v1/spoolman/inventory/slot-assignments",
  28. json={"spoolman_spool_id": 10, "printer_id": printer_id, **{"ams_id": 0, "tray_id": 0, **slot}},
  29. )
  30. return response
  31. @pytest.mark.parametrize("ams_id", [8, 50, 127, 192, 254])
  32. async def test_an_ams_id_no_slot_has_is_refused(async_client: AsyncClient, printer_id, ams_id):
  33. assert (await _assign(async_client, printer_id, ams_id=ams_id)).status_code == 422
  34. @pytest.mark.parametrize("ams_id", [0, 7, 128, 191, 255])
  35. async def test_every_real_slot_is_accepted(async_client: AsyncClient, printer_id, ams_id):
  36. response = await _assign(async_client, printer_id, ams_id=ams_id)
  37. assert response.status_code == 200, response.text
  38. @pytest.mark.parametrize(("ams_id", "tray_id"), [(32, 8), (255, 8)])
  39. async def test_slots_4_to_8_of_the_ams3h_and_the_external_inputs_are_accepted(
  40. async_client: AsyncClient, printer_id, ams_id, tray_id
  41. ):
  42. # The H3C's AMS 3H has nine slots; its per-hotend external inputs 247-253 are (255, 2-8).
  43. response = await _assign(async_client, printer_id, ams_id=ams_id, tray_id=tray_id)
  44. assert response.status_code == 200, response.text
  45. @pytest.mark.parametrize(("ams_id", "tray_id"), [(0, 4), (7, 8), (128, 4)])
  46. async def test_slots_4_to_8_of_any_other_unit_are_refused(async_client: AsyncClient, printer_id, ams_id, tray_id):
  47. response = await _assign(async_client, printer_id, ams_id=ams_id, tray_id=tray_id)
  48. assert response.status_code == 422, response.text
  49. async def test_an_archived_spool_is_refused(async_client: AsyncClient, printer_id):
  50. response = await _assign(async_client, printer_id, spool={**SPOOL, "archived": True})
  51. assert response.status_code == 400, response.text
  52. @pytest.mark.parametrize(("ams_id", "tray_id"), [(50, 0), (0, 4)])
  53. async def test_a_link_to_no_real_slot_writes_nothing_to_spoolman(
  54. async_client: AsyncClient, printer_id, ams_id, tray_id
  55. ):
  56. client = _spoolman_client()
  57. with patch("backend.app.api.routes.spoolman.get_spoolman_client", AsyncMock(return_value=client)):
  58. response = await async_client.post(
  59. "/api/v1/spoolman/spools/10/link",
  60. json={
  61. "tray_uuid": "A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4",
  62. "printer_id": printer_id,
  63. "ams_id": ams_id,
  64. "tray_id": tray_id,
  65. },
  66. )
  67. assert response.status_code == 422, response.text
  68. client.merge_spool_extra.assert_not_awaited()
  69. async def test_a_link_puts_no_archived_spool_on_a_slot(async_client: AsyncClient, printer_id):
  70. client = _spoolman_client()
  71. client.get_spool = AsyncMock(return_value={**SPOOL, "archived": True})
  72. with patch("backend.app.api.routes.spoolman.get_spoolman_client", AsyncMock(return_value=client)):
  73. response = await async_client.post(
  74. "/api/v1/spoolman/spools/10/link",
  75. json={"spool_tag": "A1B2C3D4E5F6A1B2", "printer_id": printer_id, "ams_id": 0, "tray_id": 0},
  76. )
  77. assert response.status_code == 400, response.text
  78. client.merge_spool_extra.assert_not_awaited()