TorbatYar/backend/services/hospitality/app/tests/test_analytics.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

121 lines
3.7 KiB
Python

"""Phase 12.8 Analytics API / tenant / validation tests."""
from __future__ import annotations
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
@pytest.mark.asyncio
async def test_analytics_snapshot_refresh_counts_local_tables(client):
h = tenant_headers(TENANT_A)
venue = await client.post(
"/api/v1/venues",
json={"code": "an-v1", "name": "Analytics Venue", "status": "active"},
headers=h,
)
assert venue.status_code == 201, venue.text
venue_id = venue.json()["id"]
menu = await client.post(
"/api/v1/menus",
json={"venue_id": venue_id, "code": "an-menu", "name": "Analytics Menu"},
headers=h,
)
assert menu.status_code == 201, menu.text
report = await client.post(
"/api/v1/analytics-reports",
json={
"code": "daily-ops",
"name": "Daily Ops",
"metric_keys": ["venues_count", "menus_count"],
},
headers=h,
)
assert report.status_code == 201, report.text
report_id = report.json()["id"]
snapshot = await client.post(
"/api/v1/analytics-snapshots/refresh",
json={
"report_id": report_id,
"period_start": "2026-07-01",
"period_end": "2026-07-31",
},
headers=h,
)
assert snapshot.status_code == 201, snapshot.text
metrics = snapshot.json()["metrics"]
assert metrics["venues_count"] == 1
assert metrics["menus_count"] == 1
published = {e.event_type for e in get_event_publisher().published}
assert HospitalityEventType.ANALYTICS_REPORT_DEFINITION_CREATED.value in published
assert HospitalityEventType.ANALYTICS_SNAPSHOT_REFRESHED.value in published
@pytest.mark.asyncio
async def test_analytics_report_rejects_unknown_metric_key(client):
h = tenant_headers(TENANT_A)
bad = await client.post(
"/api/v1/analytics-reports",
json={
"code": "bad-report",
"name": "Bad Report",
"metric_keys": ["not_a_real_metric"],
},
headers=h,
)
assert bad.status_code == 422
@pytest.mark.asyncio
async def test_analytics_report_code_unique_per_tenant(client):
h = tenant_headers(TENANT_A)
first = await client.post(
"/api/v1/analytics-reports",
json={"code": "dup-report", "name": "Report A", "metric_keys": ["venues_count"]},
headers=h,
)
assert first.status_code == 201, first.text
duplicate = await client.post(
"/api/v1/analytics-reports",
json={"code": "dup-report", "name": "Report B", "metric_keys": ["venues_count"]},
headers=h,
)
assert duplicate.status_code == 409
@pytest.mark.asyncio
async def test_analytics_report_tenant_isolation(client):
h = tenant_headers(TENANT_A)
report = await client.post(
"/api/v1/analytics-reports",
json={"code": "iso-report", "name": "Iso Report", "metric_keys": ["venues_count"]},
headers=h,
)
assert report.status_code == 201, report.text
report_id = report.json()["id"]
denied = await client.get(
f"/api/v1/analytics-reports/{report_id}", headers=tenant_headers(TENANT_B)
)
assert denied.status_code == 404
@pytest.mark.asyncio
async def test_capabilities_phase_12_8(client):
resp = await client.get("/capabilities")
assert resp.status_code == 200
body = resp.json()
assert body["features"]["analytics"] is True
assert body["features"]["ai"] is False