"""Phase 12.6 Kitchen API / tenant / validation tests.""" from __future__ import annotations import uuid import pytest from app.events.publisher import get_event_publisher from app.events.types import HospitalityEventType from app.tests.conftest import TENANT_A, TENANT_B, tenant_headers async def _seed_venue(client, tenant_id, *, venue_code: str = "v1"): h = tenant_headers(tenant_id) venue = await client.post( "/api/v1/venues", json={"code": venue_code, "name": "Cafe", "status": "active", "venue_format": "cafe"}, headers=h, ) assert venue.status_code == 201, venue.text return {"headers": h, "venue_id": venue.json()["id"]} @pytest.mark.asyncio async def test_kitchen_station_ticket_item_lifecycle(client): seed = await _seed_venue(client, TENANT_A, venue_code="kit-v1") h = seed["headers"] station = await client.post( "/api/v1/kitchen-stations", json={"venue_id": seed["venue_id"], "code": "grill", "name": "Grill Station"}, headers=h, ) assert station.status_code == 201, station.text station_id = station.json()["id"] source_id = str(uuid.uuid4()) ticket = await client.post( "/api/v1/kitchen-tickets", json={ "venue_id": seed["venue_id"], "station_id": station_id, "source_type": "pos_ticket", "source_id": source_id, "code": "kt-1", }, headers=h, ) assert ticket.status_code == 201, ticket.text ticket_id = ticket.json()["id"] assert ticket.json()["status"] == "queued" item = await client.post( "/api/v1/kitchen-ticket-items", json={ "venue_id": seed["venue_id"], "kitchen_ticket_id": ticket_id, "menu_item_id": str(uuid.uuid4()), "quantity": 2, }, headers=h, ) assert item.status_code == 201, item.text item_id = item.json()["id"] assert item.json()["status"] == "queued" item_status = await client.post( f"/api/v1/kitchen-ticket-items/{item_id}/status", json={"status": "preparing"}, headers=h, ) assert item_status.status_code == 200, item_status.text assert item_status.json()["status"] == "preparing" ticket_status = await client.post( f"/api/v1/kitchen-tickets/{ticket_id}/status", json={"status": "ready"}, headers=h, ) assert ticket_status.status_code == 200, ticket_status.text assert ticket_status.json()["status"] == "ready" bumped = await client.post( f"/api/v1/kitchen-tickets/{ticket_id}/status", json={"status": "bumped"}, headers=h, ) assert bumped.status_code == 200, bumped.text blocked = await client.post( f"/api/v1/kitchen-tickets/{ticket_id}/status", json={"status": "queued"}, headers=h, ) assert blocked.status_code == 409 published = {e.event_type for e in get_event_publisher().published} assert HospitalityEventType.KITCHEN_STATION_CREATED.value in published assert HospitalityEventType.KITCHEN_TICKET_CREATED.value in published assert HospitalityEventType.KITCHEN_TICKET_STATUS_CHANGED.value in published assert HospitalityEventType.KITCHEN_TICKET_ITEM_ADDED.value in published @pytest.mark.asyncio async def test_kitchen_tenant_isolation(client): seed = await _seed_venue(client, TENANT_A, venue_code="kit-iso-v1") station = await client.post( "/api/v1/kitchen-stations", json={"venue_id": seed["venue_id"], "code": "iso-station", "name": "Iso Station"}, headers=seed["headers"], ) assert station.status_code == 201, station.text station_id = station.json()["id"] denied = await client.get( f"/api/v1/kitchen-stations/{station_id}", headers=tenant_headers(TENANT_B) ) assert denied.status_code == 404 @pytest.mark.asyncio async def test_kitchen_ticket_item_quantity_validation(client): seed = await _seed_venue(client, TENANT_A, venue_code="kit-qty-v1") h = seed["headers"] ticket = await client.post( "/api/v1/kitchen-tickets", json={ "venue_id": seed["venue_id"], "source_type": "pos_ticket", "source_id": str(uuid.uuid4()), "code": "kit-qty-t1", }, headers=h, ) assert ticket.status_code == 201, ticket.text ticket_id = ticket.json()["id"] bad = await client.post( "/api/v1/kitchen-ticket-items", json={ "venue_id": seed["venue_id"], "kitchen_ticket_id": ticket_id, "menu_item_id": str(uuid.uuid4()), "quantity": 0, }, headers=h, ) assert bad.status_code == 422 @pytest.mark.asyncio async def test_capabilities_phase_12_6(client): resp = await client.get("/capabilities") assert resp.status_code == 200 body = resp.json() assert body["features"]["kitchen"] is True assert body["features"]["kitchen_engine"] is True assert body["features"]["pos_engine"] is False