| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- """An order or grouping reports itself finished however its last job ended."""
- from __future__ import annotations
- from types import SimpleNamespace
- from unittest.mock import MagicMock, patch
- import pytest
- from httpx import AsyncClient
- from sqlalchemy import update
- from backend.app.models.print_queue import PrintQueueItem
- from backend.tests.integration.test_print_batch_orders import _create_order, _queue_item
- pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
- async def _batch_status(client: AsyncClient, batch_id: int) -> str:
- response = await client.get(f"/api/v1/queue/batches/{batch_id}")
- assert response.status_code == 200, response.text
- return response.json()["status"]
- async def test_a_grouping_whose_last_job_is_cancelled_is_cancelled(
- async_client: AsyncClient, printer_factory, archive_factory
- ):
- printer = await printer_factory()
- archive = await archive_factory(printer.id)
- ids = [
- (await async_client.post("/api/v1/queue/", json={"printer_id": printer.id, "archive_id": archive.id})).json()[
- "id"
- ]
- for _ in range(2)
- ]
- grouping = (await async_client.post("/api/v1/queue/batches", json={"name": "G", "item_ids": ids})).json()
- for item_id in ids:
- assert (await async_client.post(f"/api/v1/queue/{item_id}/cancel")).status_code == 200
- assert await _batch_status(async_client, grouping["id"]) == "cancelled"
- async def test_an_order_whose_last_run_is_closed_by_the_sweep_is_completed(
- async_client: AsyncClient, db_session, printer_factory, archive_factory
- ):
- import backend.app.core.database as database
- from backend.app.services.print_scheduler import PrintScheduler
- printer = await printer_factory()
- archive = await archive_factory(printer.id)
- order = await _create_order(async_client, archive.id, [{"plate_id": 1, "quantity_target": 1}])
- run = await _queue_item(async_client, printer.id, archive.id, order["id"], plate_id=1)
- await db_session.execute(update(PrintQueueItem).where(PrintQueueItem.id == run["id"]).values(status="printing"))
- await db_session.commit()
- scheduler = PrintScheduler()
- scheduler._terminal_since[printer.id] = -10_000.0
- with (
- patch("backend.app.services.print_scheduler.async_session", database.async_session),
- patch(
- "backend.app.services.print_scheduler.printer_manager.get_status",
- MagicMock(return_value=SimpleNamespace(state="FINISH", connected=True)),
- ),
- ):
- await scheduler._close_stranded_printing_items()
- assert await _batch_status(async_client, order["id"]) == "completed"
- async def test_a_grouping_whose_file_is_deleted_is_cancelled(async_client: AsyncClient, db_session, printer_factory):
- from backend.app.models.library import LibraryFile
- from backend.app.services.library_trash import release_queue_references
- printer = await printer_factory()
- file = LibraryFile(filename="part.3mf", file_path="part.3mf", file_type="3mf", file_size=1)
- db_session.add(file)
- await db_session.commit()
- item = PrintQueueItem(printer_id=printer.id, library_file_id=file.id, status="pending", position=1)
- db_session.add(item)
- await db_session.commit()
- grouping = (await async_client.post("/api/v1/queue/batches", json={"name": "G", "item_ids": [item.id]})).json()
- await release_queue_references(db_session, [file.id])
- await db_session.commit()
- assert await _batch_status(async_client, grouping["id"]) == "cancelled"
- async def _grouping(client: AsyncClient, printer_id: int, archive_id: int) -> tuple[dict, list[int]]:
- ids = [
- (await client.post("/api/v1/queue/", json={"printer_id": printer_id, "archive_id": archive_id})).json()["id"]
- for _ in range(2)
- ]
- grouping = (await client.post("/api/v1/queue/batches", json={"name": "G", "item_ids": ids})).json()
- return grouping, ids
- async def test_a_grouping_whose_last_job_fails_at_dispatch_is_finished(
- async_client: AsyncClient, db_session, printer_factory, archive_factory
- ):
- from backend.app.services.print_scheduler import PrintScheduler
- printer = await printer_factory()
- archive = await archive_factory(printer.id)
- grouping, (done, last) = await _grouping(async_client, printer.id, archive.id)
- await db_session.execute(update(PrintQueueItem).where(PrintQueueItem.id == done).values(status="completed"))
- await db_session.commit()
- await PrintScheduler()._fail_dispatch(db_session, await db_session.get(PrintQueueItem, last), "Printer not found")
- assert await _batch_status(async_client, grouping["id"]) == "completed"
- async def test_a_grouping_whose_last_open_job_is_deleted_is_finished(
- async_client: AsyncClient, printer_factory, archive_factory
- ):
- printer = await printer_factory()
- archive = await archive_factory(printer.id)
- grouping, (first, last) = await _grouping(async_client, printer.id, archive.id)
- assert (await async_client.post(f"/api/v1/queue/{first}/cancel")).status_code == 200
- assert (await async_client.delete(f"/api/v1/queue/{last}")).status_code == 200
- assert await _batch_status(async_client, grouping["id"]) == "cancelled"
|