Files

116 lines
3.7 KiB
Python

"""Engagement data — SHAPE pins only.
The master ships placeholders; an engagement copy fills them in. So these
tests pin the *shape* of the cell and never its emptiness — asserting that
``client`` is blank would fail the moment the copy is used for real, which
is precisely backwards.
"""
from __future__ import annotations
from typing import Any
import nbformat
from tests.conftest import NOTEBOOK
IDENTITY_KEYS = {"client", "prepared_date", "prepared_by"}
VOLUME_KEYS = {
"voice_inbound_monthly",
"voice_outbound_monthly",
"digital_sessions_monthly",
"email_monthly",
"messaging_monthly",
"social_posts_monthly",
"social_responses_monthly",
"translations_monthly",
"evaluations_monthly",
"ai_actions_monthly",
"routed_interactions_monthly",
}
COMMERCIAL_KEYS = {
"agent_users",
"licence_model",
"currency",
"contracted_rate_per_token",
"concession_pct",
}
TTS_KEYS = {"tts_chars_per_call", "tts_voice_tier"}
def test_engagement_shape(engagement: dict[str, Any]) -> None:
assert set(engagement) == (
IDENTITY_KEYS | VOLUME_KEYS | COMMERCIAL_KEYS | TTS_KEYS
)
def test_identity_fields_are_strings(engagement: dict[str, Any]) -> None:
"""Blank in the master, filled in the copy — either way, strings."""
for key in IDENTITY_KEYS:
assert isinstance(engagement[key], str)
def test_volumes_are_non_negative_numbers(engagement: dict[str, Any]) -> None:
for key in VOLUME_KEYS:
value = engagement[key]
assert isinstance(value, (int, float)) and not isinstance(value, bool)
assert value >= 0, f"{key} must not be negative"
def test_commercial_terms_are_well_formed(engagement: dict[str, Any]) -> None:
assert isinstance(engagement["agent_users"], int)
assert engagement["agent_users"] >= 0
assert engagement["licence_model"] in ("named", "concurrent")
assert isinstance(engagement["currency"], str) and engagement["currency"]
assert 0.0 <= float(engagement["concession_pct"]) < 1.0
contracted = engagement["contracted_rate_per_token"]
assert contracted is None or float(contracted) >= 0
def test_currency_is_one_the_rate_card_publishes(engagement: dict[str, Any]) -> None:
from genesyscalc.ratecard import LIST_PRICE_BY_CURRENCY
assert engagement["currency"] in LIST_PRICE_BY_CURRENCY
def test_tts_settings(engagement: dict[str, Any]) -> None:
from genesyscalc.tts import TTS_PRICE_PER_MILLION_CHARS
assert isinstance(engagement["tts_chars_per_call"], int)
assert engagement["tts_chars_per_call"] >= 0
assert engagement["tts_voice_tier"] in TTS_PRICE_PER_MILLION_CHARS
def test_master_carries_no_client_identity(engagement: dict[str, Any]) -> None:
"""The one emptiness check that IS correct: masters stay client-clean.
This guards the master in THIS repo. An engagement copy lives outside
Palladium, so it never runs this suite — filling the cell there does not
break anything (CLAUDE.md § Confidentiality).
"""
assert engagement["client"] == "", (
"a client name in the master means the copy-out step was skipped — "
"copy the directory out of Palladium before entering client data"
)
def test_engagement_cell_sits_above_the_widget_cell() -> None:
"""Client data must not re-run on a sidebar change (Mercury re-runs only
cells below a changed widget)."""
nb = nbformat.read(NOTEBOOK, as_version=4)
eng = [
i
for i, c in enumerate(nb.cells)
if "engagement-data" in c.metadata.get("tags", [])
]
widgets = [
i
for i, c in enumerate(nb.cells)
if c.cell_type == "code" and "mr.Select(" in c.source
]
assert len(eng) == 1 and widgets
assert eng[0] < min(widgets)