test_projects_batches_scope.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. """Project cards and orders keep to the caller's printers.
  2. Project cards previewed archives of any printer, and an order (batch) whose
  3. jobs run on a printer outside the caller's groups was listed, shown and
  4. editable, although cancelling or ungrouping it already treated it as missing.
  5. """
  6. from __future__ import annotations
  7. import pytest
  8. from httpx import AsyncClient
  9. from backend.app.models.print_batch import PrintBatch
  10. from backend.app.models.print_queue import PrintQueueItem
  11. from backend.tests.integration.test_printer_scope_1727 import TEAM_PERMISSIONS, _admin_token, _auth, _group, _user
  12. pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
  13. async def _member(client: AsyncClient, printer_ids: list[int]) -> tuple[dict[str, str], str]:
  14. admin = await _admin_token(client)
  15. perms = await _group(
  16. client,
  17. admin,
  18. "perms",
  19. permissions=[*TEAM_PERMISSIONS, "projects:read", "queue:read_all", "queue:update_own", "queue:update_all"],
  20. )
  21. team = await _group(client, admin, "team", printer_ids=printer_ids)
  22. return _auth((await _user(client, admin, "member", [perms, team]))[0]), admin
  23. async def _batch_on(db_session, archive_id: int, printer_id: int) -> int:
  24. batch = PrintBatch(name=f"order {printer_id}", archive_id=archive_id, quantity=1, status="active")
  25. db_session.add(batch)
  26. await db_session.flush()
  27. db_session.add(PrintQueueItem(printer_id=printer_id, archive_id=archive_id, batch_id=batch.id, status="pending"))
  28. await db_session.commit()
  29. return batch.id
  30. async def test_project_cards_preview_only_the_team_printers_archives(
  31. async_client: AsyncClient, printer_factory, archive_factory
  32. ):
  33. a, b = await printer_factory(name="A"), await printer_factory(name="B")
  34. member, admin = await _member(async_client, [a.id])
  35. project = (await async_client.post("/api/v1/projects/", headers=_auth(admin), json={"name": "P"})).json()["id"]
  36. on_a = await archive_factory(a.id, project_id=project, print_name="ours")
  37. await archive_factory(b.id, project_id=project, print_name="theirs")
  38. cards = (await async_client.get("/api/v1/projects/", headers=member)).json()
  39. previews = next(card for card in cards if card["id"] == project)["archives"]
  40. assert [p["id"] for p in previews] == [on_a.id]
  41. async def test_an_order_with_jobs_on_another_printer_is_missing(
  42. async_client: AsyncClient, db_session, printer_factory, archive_factory
  43. ):
  44. a, b = await printer_factory(name="A"), await printer_factory(name="B")
  45. member, _ = await _member(async_client, [a.id])
  46. ours = await _batch_on(db_session, (await archive_factory(a.id)).id, a.id)
  47. theirs = await _batch_on(db_session, (await archive_factory(b.id)).id, b.id)
  48. listed = await async_client.get("/api/v1/queue/batches", headers=member)
  49. detail = await async_client.get(f"/api/v1/queue/batches/{theirs}", headers=member)
  50. edited = await async_client.patch(f"/api/v1/queue/batches/{theirs}", headers=member, json={"name": "renamed"})
  51. own_edit = await async_client.patch(f"/api/v1/queue/batches/{ours}", headers=member, json={"name": "renamed"})
  52. assert [batch["id"] for batch in listed.json()] == [ours]
  53. assert (detail.status_code, edited.status_code) == (404, 404)
  54. assert own_edit.status_code == 200, own_edit.text
  55. async def test_a_hidden_order_takes_no_new_jobs_or_dispatches(
  56. async_client: AsyncClient, db_session, printer_factory, archive_factory
  57. ):
  58. a, b = await printer_factory(name="A"), await printer_factory(name="B")
  59. member, _ = await _member(async_client, [a.id])
  60. archive_on_a = await archive_factory(a.id)
  61. theirs = await _batch_on(db_session, (await archive_factory(b.id)).id, b.id)
  62. added = await async_client.post(
  63. "/api/v1/queue/", headers=member, json={"archive_id": archive_on_a.id, "printer_id": a.id, "batch_id": theirs}
  64. )
  65. dispatched = await async_client.post(f"/api/v1/queue/batches/{theirs}/dispatch", headers=member, json={})
  66. assert (added.status_code, dispatched.status_code) == (404, 404), (added.text, dispatched.text)
  67. async def test_dispatching_a_plate_of_a_hidden_order_is_refused(
  68. async_client: AsyncClient, db_session, printer_factory, archive_factory
  69. ):
  70. """Plate 1 runs on the caller's printer, plate 2 elsewhere: the order is hidden as a whole."""
  71. from backend.app.models.print_batch import PrintBatchPlate
  72. a, b = await printer_factory(name="A"), await printer_factory(name="B")
  73. member, _ = await _member(async_client, [a.id])
  74. archive = await archive_factory(a.id)
  75. batch = PrintBatch(name="mixed order", archive_id=archive.id, quantity=2, status="active")
  76. db_session.add(batch)
  77. await db_session.flush()
  78. db_session.add_all(
  79. [
  80. PrintBatchPlate(batch_id=batch.id, plate_id=1, quantity_target=2),
  81. PrintBatchPlate(batch_id=batch.id, plate_id=2, quantity_target=1),
  82. PrintQueueItem(printer_id=a.id, archive_id=archive.id, batch_id=batch.id, plate_id=1, status="pending"),
  83. PrintQueueItem(printer_id=b.id, archive_id=archive.id, batch_id=batch.id, plate_id=2, status="pending"),
  84. ]
  85. )
  86. await db_session.commit()
  87. response = await async_client.post(
  88. f"/api/v1/queue/batches/{batch.id}/dispatch", headers=member, json={"plate_id": 1, "only_plate": True}
  89. )
  90. assert response.status_code == 404, response.text