|
|
@@ -0,0 +1,76 @@
|
|
|
+"""Deleting a spool keeps its usage history, and its id is not given to a new spool.
|
|
|
+
|
|
|
+PostgreSQL deleted the usage with the spool, so recalculating the cost of its
|
|
|
+prints fell back to an estimate. SQLite kept the usage with the old spool id,
|
|
|
+and could give that id to the next spool, which then showed the deleted
|
|
|
+spool's prints as its own.
|
|
|
+"""
|
|
|
+
|
|
|
+from __future__ import annotations
|
|
|
+
|
|
|
+import pytest
|
|
|
+from httpx import AsyncClient
|
|
|
+from sqlalchemy import select
|
|
|
+
|
|
|
+from backend.app.models.archive import PrintArchive
|
|
|
+from backend.app.models.spool import Spool
|
|
|
+from backend.app.models.spool_usage_history import SpoolUsageHistory
|
|
|
+
|
|
|
+pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
|
|
|
+
|
|
|
+
|
|
|
+async def test_deleting_a_spool_keeps_the_usage_and_the_print_cost(
|
|
|
+ async_client: AsyncClient, db_session, printer_factory, archive_factory
|
|
|
+):
|
|
|
+ printer = await printer_factory()
|
|
|
+ archive = await archive_factory(printer.id, filament_used_grams=20.0, cost=None)
|
|
|
+ archive_id = archive.id
|
|
|
+ spool = Spool(material="PLA")
|
|
|
+ db_session.add(spool)
|
|
|
+ await db_session.flush()
|
|
|
+ spool_id = spool.id
|
|
|
+ db_session.add(
|
|
|
+ SpoolUsageHistory(spool_id=spool_id, printer_id=printer.id, archive_id=archive_id, weight_used=20, cost=0.5)
|
|
|
+ )
|
|
|
+ await db_session.commit()
|
|
|
+
|
|
|
+ deleted = await async_client.delete(f"/api/v1/inventory/spools/{spool_id}")
|
|
|
+ recalculated = await async_client.post("/api/v1/archives/recalculate-costs")
|
|
|
+
|
|
|
+ assert deleted.status_code in (200, 204), deleted.text
|
|
|
+ assert recalculated.status_code == 200, recalculated.text
|
|
|
+ db_session.expire_all()
|
|
|
+ usage = (await db_session.execute(select(SpoolUsageHistory.spool_id, SpoolUsageHistory.cost))).one()
|
|
|
+ assert tuple(usage) == (None, 0.5)
|
|
|
+ cost = (await db_session.execute(select(PrintArchive.cost).where(PrintArchive.id == archive_id))).scalar()
|
|
|
+ assert cost == 0.5
|
|
|
+
|
|
|
+
|
|
|
+async def test_a_new_spool_does_not_get_the_id_of_a_deleted_one(async_client: AsyncClient, db_session):
|
|
|
+ spool = Spool(material="PLA")
|
|
|
+ db_session.add(spool)
|
|
|
+ await db_session.commit()
|
|
|
+ old_id = spool.id
|
|
|
+
|
|
|
+ deleted = await async_client.delete(f"/api/v1/inventory/spools/{old_id}")
|
|
|
+ assert deleted.status_code in (200, 204), deleted.text
|
|
|
+ replacement = Spool(material="PETG")
|
|
|
+ db_session.add(replacement)
|
|
|
+ await db_session.commit()
|
|
|
+
|
|
|
+ assert replacement.id != old_id
|
|
|
+
|
|
|
+
|
|
|
+async def test_the_usage_list_shows_usage_of_a_deleted_spool(async_client: AsyncClient, db_session):
|
|
|
+ spool = Spool(material="PLA")
|
|
|
+ db_session.add(spool)
|
|
|
+ await db_session.flush()
|
|
|
+ db_session.add(SpoolUsageHistory(spool_id=spool.id, weight_used=12, cost=0.3))
|
|
|
+ await db_session.commit()
|
|
|
+ deleted = await async_client.delete(f"/api/v1/inventory/spools/{spool.id}")
|
|
|
+ assert deleted.status_code in (200, 204), deleted.text
|
|
|
+
|
|
|
+ response = await async_client.get("/api/v1/inventory/usage")
|
|
|
+
|
|
|
+ assert response.status_code == 200, response.text
|
|
|
+ assert [(row["spool_id"], row["weight_used"]) for row in response.json()] == [(None, 12)]
|