Files
Labvoice/tests/test_workflows_inventory.py
T
2026-08-30 20:44:00 +02:00

93 lines
3.5 KiB
Python

"""workflows/inventory.py — stock reads + adjust_inventory (plan §6, §10)."""
import pytest
from mcp_server.errors import ClarificationNeededError, NotFoundError
# --- stock reads ------------------------------------------------------------
async def test_stock_for_resource_lists_containers(inventory):
stock = await inventory.stock_for_resource("ethanol_absolute")
assert [s.container_id for s in stock] == [31, 32]
assert stock[0].available == 50.0
assert stock[0].unit == "mL"
assert stock[0].amount == "50.0 mL"
async def test_stock_for_unknown_resource_raises_clarification(inventory, resolver_stub):
resolver_stub.mappings.clear()
with pytest.raises(ClarificationNeededError):
await inventory.stock_for_resource("unobtainium")
# --- adjust_inventory -------------------------------------------------------
async def test_adjust_adds_to_container_by_id(inventory, client):
result = await inventory.adjust_inventory(amount=500.0, unit="mL", container_id=31)
assert result.ok is True
assert result.container_id == 31
assert result.amount == "500.0 mL"
assert result.remaining == "550.0 mL"
assert client.items[12].containers[0].qty_stored == 550.0
async def test_adjust_supports_correction_negative_delta(inventory, client):
await inventory.adjust_inventory(amount=-2.0, unit="mL", container_id=31)
assert client.items[12].containers[0].qty_stored == 48.0
async def test_adjust_by_resource_key_uses_allocable_container(inventory, client):
result = await inventory.adjust_inventory(
amount=100.0, unit="mL", resource_key="ethanol_absolute"
)
assert result.resource_key == "ethanol_absolute"
assert result.container_id == 31
assert result.remaining == "150.0 mL"
async def test_adjust_converts_units(inventory, client):
"""“Add half a litre” against an mL-stocked container."""
await inventory.adjust_inventory(amount=0.5, unit="L", container_id=31)
assert client.items[12].containers[0].qty_stored == 550.0
async def test_adjust_rejects_non_whitelisted_unit(inventory):
with pytest.raises(ClarificationNeededError):
await inventory.adjust_inventory(amount=1.0, unit="fl-oz", container_id=31)
async def test_adjust_rejects_cross_dimension_unit(inventory):
with pytest.raises(ClarificationNeededError):
await inventory.adjust_inventory(amount=5.0, unit="g", container_id=31)
async def test_adjust_unknown_container_fails_cleanly(inventory):
with pytest.raises(NotFoundError):
await inventory.adjust_inventory(amount=1.0, unit="mL", container_id=9999)
async def test_adjust_requires_container_or_resource(inventory):
with pytest.raises(ClarificationNeededError):
await inventory.adjust_inventory(amount=1.0, unit="mL")
async def test_adjust_is_journaled(inventory, journal):
await inventory.adjust_inventory(amount=500.0, unit="mL", container_id=31)
assert journal.db_path.exists()
async def test_adjust_failure_does_not_silently_lose_data(inventory, client, monkeypatch):
"""If the write fails, the workflow surfaces the error (journaled saga)."""
from mcp_server.errors import ApiError
async def fail_write(entity_type, entity_id, subitem_id, qty_stored):
raise ApiError("write refused")
monkeypatch.setattr(inventory.client, "set_container_quantity", fail_write)
with pytest.raises(ApiError):
await inventory.adjust_inventory(amount=500.0, unit="mL", container_id=31)
assert client.items[12].containers[0].qty_stored == 50.0