TorbatYar/backend/services/hospitality/app/tests/test_kitchen.py
Mortezakoohjani 5c6a2e78cf feat(platform): seed service registry, deploy all modules, and fix homepage catalog.
Register all active platform services and base features in core DB so admin can manage them, add delivery/hospitality/sports-center backend phases, update apps catalog and production deploy tooling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 12:39:51 +03:30

160 lines
5.1 KiB
Python

"""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