"""Transfer-ownership tests for /playlist//placement//streams. DAILY grain. The endpoint reads ``v_streams_by_track_playlist_country_feed_distributor_daily`` filtered by (``isrc``, ``store_id``, ``store_playlist_id``) and gated by the v2 ``permissions_filter`` macro on the ``s.product_id`` column. Visibility is keyed by the viewer's ownership window — see ``conftest._VISIBILITY``. Two test classes: - ``TestPlacementStreamsCanonical`` — every (profile, probe) on the canonical (ISRC, playlist) tuple. The visibility matrix says exactly what each cell must look like. - ``TestPlacementStreamsW1Sweep`` — runs the W1 probe across every product-5244974 ISRC that has any FACTS.QA coverage on the canonical playlist, to catch a per-ISRC permission leak that the single-ISRC test would miss. """ from __future__ import annotations import pytest import requests from tests.integration.config import QA_BASE_URL from tests.integration.transfer_ownership.conftest import ( CANONICAL_STORE_ID, CANONICAL_STORE_PLAYLIST_ID, ISRC, PROBES, PRODUCT_ISRCS, TRANSFER_PROFILES, WINDOW_PROBES, assert_visibility, profile_key_for, ) _BASE = f"{QA_BASE_URL}/playlist/{CANONICAL_STORE_PLAYLIST_ID}/placement" def _streams_url(isrc: str, probe: str) -> str: """Build the DAILY placement-streams URL for a (ISRC, probe) pair.""" return f"{_BASE}/{isrc}/streams?store_id={CANONICAL_STORE_ID}&{PROBES[probe]}" def _streams_payload(url: str, headers: dict) -> dict: """GET the endpoint and return the inner ``data`` body.""" response = requests.get(url, headers=headers) assert ( response.status_code == 200 ), f"GET {url} -> {response.status_code}: {response.text}" return response.json()["data"] class TestPlacementStreamsCanonical: """Visibility matrix on the canonical (ISRC, playlist) tuple.""" @pytest.mark.parametrize("hdrs", TRANSFER_PROFILES) @pytest.mark.parametrize("probe", WINDOW_PROBES) def test_visibility(self, hdrs, probe): """A former owner sees no post-cutoff streams; nested owners see all history through their cutoff; the employee and the current owner see every window.""" payload = _streams_payload(_streams_url(ISRC, probe), hdrs) # `data.streams` is a date-spine list of {streams, timestamp}; the # spine pads days without rows as `streams=null`, so we sum the # metric across items to distinguish "empty" (only null padding) # from "data" (at least one real row). assert_visibility( payload, profile_key=profile_key_for(hdrs), probe=probe, items_key="streams", metric_key="streams", ) # Probe one ISRC at a time across every product-5244974 ISRC. Only the ISRCs # with FACTS.QA stream data on the canonical playlist are usable here — the # rest collapse to all-null spines, which look identical between v2 (correct) # and a hypothetical buggy filter, so they tell us nothing. # # Data probe (2026-05-27): all 13 product-5244974 ISRCs have W1 coverage on # (mix, 286), ranging from 34 to 69,549 streams. The full PRODUCT_ISRCS list # is therefore a real 13-element sweep — every cell is meaningful. _W1_SWEEP_ISRCS = [pytest.param(isrc, id=isrc) for isrc in PRODUCT_ISRCS] class TestPlacementStreamsW1Sweep: """Per-ISRC W1 visibility sweep across the canonical playlist.""" @pytest.mark.parametrize("hdrs", TRANSFER_PROFILES) @pytest.mark.parametrize("isrc", _W1_SWEEP_ISRCS) def test_w1_visibility(self, hdrs, isrc): """Every transfer profile reaches product 5244974 during W1, so every ISRC on the product must surface non-zero streams under the `early` probe for every profile.""" payload = _streams_payload(_streams_url(isrc, "early"), hdrs) assert_visibility( payload, profile_key=profile_key_for(hdrs), probe="early", items_key="streams", metric_key="streams", )