| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- """A queued job moved to another printer leaves the old printer's settings behind."""
- from __future__ import annotations
- import json
- import pytest
- from httpx import AsyncClient
- from sqlalchemy import select
- from backend.app.models.print_queue import PrintQueueItem, PrintQueueVariant
- pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
- RESOLVED_FOR_A = {
- "ams_mapping": "[2]",
- "skip_filament_check": True,
- "nozzle_mapping": json.dumps([1]),
- "nozzle_rack_choice": json.dumps({"0": 3}),
- }
- async def _item(db_session, printer_id: int, archive_id: int, **extra) -> int:
- item = PrintQueueItem(
- printer_id=printer_id,
- archive_id=archive_id,
- status="pending",
- position=1,
- plate_id=2,
- use_ams=False,
- **{**RESOLVED_FOR_A, **extra},
- )
- db_session.add(item)
- await db_session.commit()
- return item.id
- async def _row(db_session, item_id: int) -> PrintQueueItem:
- db_session.expire_all()
- return await db_session.get(PrintQueueItem, item_id)
- def _resolved(item: PrintQueueItem) -> tuple:
- return item.ams_mapping, item.skip_filament_check, item.nozzle_mapping, item.nozzle_rack_choice
- async def test_a_bulk_move_drops_what_was_worked_out_for_the_old_printer(
- async_client: AsyncClient, db_session, printer_factory, archive_factory
- ):
- a, b = await printer_factory(name="A"), await printer_factory(name="B")
- a_id, b_id = a.id, b.id
- archive_id = (await archive_factory(a_id)).id
- moved = await _item(db_session, a_id, archive_id)
- stays = await _item(db_session, b_id, archive_id)
- model_job = await _item(db_session, a_id, archive_id, target_model="X1C", target_location="Lab")
- response = await async_client.patch(
- "/api/v1/queue/bulk", json={"item_ids": [moved, stays, model_job], "printer_id": b_id}
- )
- assert response.status_code == 200, response.text
- item = await _row(db_session, moved)
- assert item.printer_id == b_id
- assert _resolved(item) == (None, False, None, None)
- assert (item.plate_id, item.use_ams) == (2, False)
- assert _resolved(await _row(db_session, stays)) == tuple(RESOLVED_FOR_A.values())
- pinned = await _row(db_session, model_job)
- assert (pinned.printer_id, pinned.target_model, pinned.target_location) == (b_id, None, None)
- async def test_a_bulk_move_leaves_jobs_with_printer_alternatives_alone(
- async_client: AsyncClient, db_session, printer_factory, archive_factory
- ):
- a, b = await printer_factory(name="A"), await printer_factory(name="B")
- a_id, b_id = a.id, b.id
- archive_id = (await archive_factory(a_id)).id
- item_id = await _item(db_session, a_id, archive_id, target_model="X1C")
- from backend.app.models.library import LibraryFile
- file = LibraryFile(filename="part.3mf", file_path="part.3mf", file_type="3mf", file_size=1)
- db_session.add(file)
- await db_session.flush()
- db_session.add(PrintQueueVariant(queue_item_id=item_id, position=0, target_model="X1C", library_file_id=file.id))
- await db_session.commit()
- response = await async_client.patch("/api/v1/queue/bulk", json={"item_ids": [item_id], "printer_id": b_id})
- assert response.json()["skipped_count"] == 1
- assert (await _row(db_session, item_id)).printer_id == a_id
- async def test_editing_a_job_onto_another_printer_keeps_only_what_was_sent_for_it(
- async_client: AsyncClient, db_session, printer_factory, archive_factory
- ):
- a, b = await printer_factory(name="A"), await printer_factory(name="B")
- a_id, b_id = a.id, b.id
- archive_id = (await archive_factory(a_id)).id
- item_id = await _item(db_session, a_id, archive_id)
- # What the edit dialog sends: the new printer's mapping, no Print Anyway.
- response = await async_client.patch(f"/api/v1/queue/{item_id}", json={"printer_id": b_id, "ams_mapping": [5]})
- assert response.status_code == 200, response.text
- item = await _row(db_session, item_id)
- assert _resolved(item) == ("[5]", False, None, None)
- async def test_editing_a_job_on_the_same_printer_keeps_its_settings(
- async_client: AsyncClient, db_session, printer_factory, archive_factory
- ):
- a = await printer_factory(name="A")
- a_id = a.id
- archive_id = (await archive_factory(a_id)).id
- item_id = await _item(db_session, a_id, archive_id)
- response = await async_client.patch(f"/api/v1/queue/{item_id}", json={"printer_id": a_id})
- assert response.status_code == 200, response.text
- assert _resolved(await _row(db_session, item_id)) == tuple(RESOLVED_FOR_A.values())
- async def test_copies_of_a_model_job_wait_for_any_printer_of_the_model(
- async_client: AsyncClient, db_session, printer_factory, archive_factory
- ):
- from backend.tests.integration.test_print_batch_orders import _create_order
- a = await printer_factory(name="A", model="X1C")
- a_id = a.id
- archive_id = (await archive_factory(a_id)).id
- order = await _create_order(async_client, archive_id, [{"plate_id": 2, "quantity_target": 3}])
- # Run 1 as the scheduler leaves it: its model, the printer it picked, and
- # what it worked out for that printer.
- source_id = await _item(db_session, a_id, archive_id, target_model="X1C", batch_id=order["id"])
- response = await async_client.post(f"/api/v1/queue/batches/{order['id']}/dispatch", json={})
- assert response.status_code == 200, response.text
- db_session.expire_all()
- copies = (
- (
- await db_session.execute(
- select(PrintQueueItem)
- .where(PrintQueueItem.batch_id == order["id"])
- .where(PrintQueueItem.id != source_id)
- )
- )
- .scalars()
- .all()
- )
- assert copies
- for copy in copies:
- assert (copy.printer_id, copy.target_model) == (None, "X1C")
- assert _resolved(copy) == (None, False, None, None)
- assert (copy.plate_id, copy.use_ams) == (2, False)
|