"""Test plumbing: import path + notebook content served from tagged cells. Content and client data live in the notebook, never in ``.py`` — the cells tagged ``topic-bank`` and ``engagement-data`` in ``notebooks/cx_discovery.ipynb``. The fixtures below read those cells with nbformat and exec them, so pytest pins the exact content the deliverable ships (no kernel needed — tagged cells are self-contained by contract). The sys.path insert makes discoverylib importable even without the study venv active (the normal setup is ``pip install -e ".[dev]"`` into the study-local ``.venv/``). """ from __future__ import annotations import pathlib import sys from typing import Any import pytest STUDY_ROOT = pathlib.Path(__file__).resolve().parent.parent sys.path.insert(0, str(STUDY_ROOT)) NOTEBOOK = STUDY_ROOT / "notebooks" / "cx_discovery.ipynb" def tagged_cell_ns(tag: str) -> dict[str, Any]: """Exec the single cell carrying ``tag`` and return its namespace.""" import nbformat nb = nbformat.read(NOTEBOOK, as_version=4) cells = [c for c in nb.cells if tag in c.metadata.get("tags", [])] assert len(cells) == 1, ( f"expected exactly one cell tagged {tag!r} in {NOTEBOOK.name}, " f"found {len(cells)}" ) ns: dict[str, Any] = {} exec(compile(cells[0].source, f"{NOTEBOOK.name} [{tag}]", "exec"), ns) return ns @pytest.fixture(scope="session") def topic_bank() -> dict[str, Any]: """The executed namespace of the notebook's topic-bank cell.""" return tagged_cell_ns("topic-bank") @pytest.fixture(scope="session") def topics(topic_bank: dict[str, Any]) -> tuple[Any, ...]: """The TOPICS tuple as the deliverable defines it.""" return topic_bank["TOPICS"] # type: ignore[no-any-return] @pytest.fixture(scope="session") def topic_by_key(topics: tuple[Any, ...]) -> dict[str, Any]: return {t.key: t for t in topics} @pytest.fixture(scope="session") def engagement() -> dict[str, Any]: """The ENGAGEMENT dict as the deliverable's engagement-data cell ships it.""" return tagged_cell_ns("engagement-data")["ENGAGEMENT"] # type: ignore[no-any-return]