"""Render-level tests for ``participant/metrics.sql``. Covers the artist-only (label-participant) directed-join fast path: when the caller's permissions resolve to ONLY ``label_participant_ids``, the template resolves those to their ``global_participant_id``(s) via ``global_participant_represents_label_participant`` and INNER JOINs that set onto the metrics rollup — on top of (not instead of) the permissions filter. """ from analytics.queries.participant_metrics import ParticipantMetrics def _render(**permissions): params = dict( distributors=["theorchard", "sme"], store_ids=[1, 286], country_ids=[], rollup_grain=True, transfer_product_ownership_enabled=False, **permissions, ) sql, bind = ParticipantMetrics(params).prepare_query() return " ".join(sql.split()), bind ARTIST_ONLY = dict( permission_label_ids=None, permission_subaccount_ids=None, permission_artist_ids=None, permission_label_participant_ids=[4, 5, 6], ) def test_artist_only_adds_represents_cte_and_directed_join(): sql, bind = _render(**ARTIST_ONLY) # CTE resolving label_participant_id -> global_participant_id assert "WITH artist_global_participants AS (" in sql assert "FROM global_participant_represents_label_participant" in sql # CTE is the driving (left) side of the DIRECTED join onto the rollup, so # the tiny resolved-gpid set is scanned first and probes the metrics table. assert "FROM artist_global_participants agp" in sql assert "INNER DIRECTED JOIN" in sql assert "ON s.global_participant_id = agp.global_participant_id" in sql # the permissions gate is NOT replaced — the product filter stays so a # merged artist's catalog is not summed across inaccessible vendors. assert "label_participant_participated_in_orchard_product" in sql # label_participant_ids feed BOTH the CTE and the permissions gate. assert list(bind.values()).count(4) == 2 def test_artist_only_qualifies_global_participant_id(): # Adding the CTE join makes a bare ``global_participant_id`` ambiguous; # every reference must be qualified to the metrics alias ``s``. sql, _ = _render(**ARTIST_ONLY) assert "GROUP BY s.global_participant_id" in sql assert "COUNT(DISTINCT s.global_participant_id) OVER()" in sql assert "s.global_participant_id AS id" in sql def test_label_access_unchanged_no_directed_join(): sql, _ = _render( permission_label_ids=[7123], permission_subaccount_ids=None, permission_artist_ids=None, permission_label_participant_ids=None, ) assert "artist_global_participants" not in sql assert "global_participant_represents_label_participant" not in sql assert "DIRECTED" not in sql assert "GROUP BY s.global_participant_id" in sql def test_mixed_label_and_participant_no_directed_join(): # Only PURE label-participant access triggers the fast path. sql, _ = _render( permission_label_ids=[7123], permission_subaccount_ids=None, permission_artist_ids=None, permission_label_participant_ids=[4, 5, 6], ) assert "artist_global_participants" not in sql def test_full_access_no_directed_join(): sql, _ = _render( permission_label_ids=[], permission_subaccount_ids=[], permission_artist_ids=[], permission_label_participant_ids=[], ) assert "artist_global_participants" not in sql