| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- """Bulk edit leaves a row a dispatch claimed during the edit (DM/BULK).
- The bulk edit checked the claim on the rows it loaded, then awaited cost and
- budget checks per row before changing it. A row the scheduler claimed for
- dispatch in between was changed anyway, so its printer or cost centre no
- longer matched the upload already under way.
- """
- from datetime import datetime, timezone
- from unittest.mock import AsyncMock, patch
- import pytest
- from sqlalchemy import update
- from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
- from backend.app.models.finance import CostCenter
- from backend.app.models.print_queue import PrintQueueItem
- pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
- async def test_a_row_claimed_during_the_edit_is_skipped(
- async_client, db_session, test_engine, printer_factory, archive_factory
- ):
- printer = await printer_factory()
- other_printer = await printer_factory(name="Other")
- archive = await archive_factory(printer.id)
- center = CostCenter(name="Lab", is_active=True, is_private=False)
- db_session.add(center)
- claimed = PrintQueueItem(printer_id=printer.id, archive_id=archive.id, status="pending", target_model="X1C")
- free = PrintQueueItem(printer_id=printer.id, archive_id=archive.id, status="pending")
- db_session.add_all([claimed, free])
- await db_session.commit()
- other = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
- async def dispatch_claims(*_args, exclude_queue_item_id=None, **_kwargs):
- if exclude_queue_item_id == claimed.id:
- async with other() as db:
- await db.execute(
- update(PrintQueueItem)
- .where(PrintQueueItem.id == claimed.id)
- .values(dispatching_at=datetime.now(timezone.utc))
- )
- await db.commit()
- with patch("backend.app.api.routes.print_queue.validate_print_budget", AsyncMock(side_effect=dispatch_claims)):
- response = await async_client.patch(
- "/api/v1/queue/bulk",
- json={"item_ids": [claimed.id, free.id], "cost_center_id": center.id, "printer_id": other_printer.id},
- )
- assert response.status_code == 200, response.text
- assert (response.json()["updated_count"], response.json()["skipped_count"]) == (1, 1)
- async with other() as db:
- claimed_row = await db.get(PrintQueueItem, claimed.id)
- free_row = await db.get(PrintQueueItem, free.id)
- assert (claimed_row.printer_id, claimed_row.cost_center_id, claimed_row.target_model) == (printer.id, None, "X1C")
- assert (free_row.printer_id, free_row.cost_center_id) == (other_printer.id, center.id)
|