test_spool_weight_entry.py 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. """A weight entered for a new spool is kept, and a negative one is refused.
  2. Creating a spool (one, several, or from a CSV) left ``weight_locked`` off even
  3. when a used weight was entered, so the AMS remain% sync could overwrite a
  4. part-used spool's weight on its first pass; editing a spool's weight locks it.
  5. A weight above 0 entered at creation is now locked too. And ``weight_used`` had
  6. no lower bound in the API: a negative value gave a spool more than its label.
  7. Print tracking may still take a spool past its label (mis-labelled spools).
  8. """
  9. import pytest
  10. from httpx import AsyncClient
  11. from sqlalchemy import select
  12. from backend.app.models.spool import Spool
  13. from backend.tests.integration.test_inventory_csv import _csv_upload
  14. pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
  15. BASE = {"material": "PLA", "brand": "Bambu", "color_name": "White", "rgba": "FFFFFFFF", "label_weight": 1000}
  16. async def _spools(db_session):
  17. db_session.expire_all()
  18. return (await db_session.execute(select(Spool).order_by(Spool.id))).scalars().all()
  19. @pytest.mark.parametrize(("weight_used", "locked"), [(250, True), (0, False)])
  20. async def test_a_new_spool_keeps_the_weight_entered(async_client: AsyncClient, weight_used, locked):
  21. response = await async_client.post("/api/v1/inventory/spools", json={**BASE, "weight_used": weight_used})
  22. assert response.status_code == 200, response.text
  23. assert response.json()["weight_locked"] is locked
  24. async def test_an_explicit_unlock_is_respected(async_client: AsyncClient):
  25. response = await async_client.post(
  26. "/api/v1/inventory/spools", json={**BASE, "weight_used": 250, "weight_locked": False}
  27. )
  28. assert response.json()["weight_locked"] is False
  29. async def test_copies_keep_the_weight_entered(async_client: AsyncClient, db_session):
  30. response = await async_client.post(
  31. "/api/v1/inventory/spools/bulk", json={"spool": {**BASE, "weight_used": 400}, "quantity": 2}
  32. )
  33. assert response.status_code == 200, response.text
  34. assert [s.weight_locked for s in await _spools(db_session)] == [True, True]
  35. async def test_an_imported_weight_is_kept(async_client: AsyncClient, db_session):
  36. csv_text = "material,brand,color_name,weight_used\nPLA,Bambu,White,300\nPETG,Bambu,Black,0\n"
  37. response = await async_client.post("/api/v1/inventory/spools/import", files=_csv_upload(csv_text))
  38. assert response.status_code == 200, response.text
  39. by_material = {s.material: s.weight_locked for s in await _spools(db_session)}
  40. assert by_material == {"PLA": True, "PETG": False}
  41. async def test_a_negative_weight_is_refused(async_client: AsyncClient):
  42. created = await async_client.post("/api/v1/inventory/spools", json={**BASE, "weight_used": -10})
  43. assert created.status_code == 422
  44. spool = (await async_client.post("/api/v1/inventory/spools", json=BASE)).json()
  45. edited = await async_client.patch(f"/api/v1/inventory/spools/{spool['id']}", json={"weight_used": -1})
  46. assert edited.status_code == 422
  47. async def test_more_than_the_label_is_still_taken(async_client: AsyncClient):
  48. """A mis-labelled spool really can give more than its label."""
  49. response = await async_client.post("/api/v1/inventory/spools", json={**BASE, "weight_used": 1100})
  50. assert response.status_code == 200, response.text
  51. async def test_a_negative_weight_stored_before_still_lists(async_client: AsyncClient, db_session):
  52. db_session.add(Spool(material="PLA", label_weight=1000, core_weight=250, weight_used=-20))
  53. await db_session.commit()
  54. response = await async_client.get("/api/v1/inventory/spools")
  55. assert response.status_code == 200, response.text