import os import pytest from app.logger import log from app.data import NMF_PLAYLISTS from app.utils import get_friday ALL_MARKETS = list(NMF_PLAYLISTS.keys()) TEST_MARKET = os.environ.get('MARKET', ALL_MARKETS) """ https://theorchard.atlassian.net/browse/IN-15869 Check end-to-end New Music Friday spotify playlist freshness: 1. Get NMF playlist for specified market 2. For chosen ISRC check position is the same in Insights """ @pytest.mark.parametrize("input_market", [TEST_MARKET] if isinstance(TEST_MARKET, str) else TEST_MARKET, ids=lambda code: f"{code} - {NMF_PLAYLISTS[code]['name']} - {NMF_PLAYLISTS[code]['id']}") def test_nmf_playlist_freshness(spotify, graphql, snowflake, input_market): test_playlist = NMF_PLAYLISTS[input_market]["id"] log.info("Step1: Get NMF playlist data in Spotify") spotify_nmf_data = spotify.get_all_tracks(test_playlist) log.info(f"Step2: Get NMF playlist data by {input_market} in Insights") total_fetched = 0 def get_variables(num): return { "limit": 200, "offset": num, "appearsOnMarket": input_market, "order": { "by": "POSITION_IN_MARKET", "dir": "ASC", "market": input_market, } } insights_nmf_data = graphql.fetch_data('NMFSongsByDate', get_variables(total_fetched)) insights_nmf_entries = insights_nmf_data['newMusicFridayByDate']['entries']['entries'] log.info(f"Step3: assert market {input_market} received") market_received = all(m["market"] != input_market for m in insights_nmf_data['newMusicFridayByDate']['markets']) if not market_received: if os.environ.get('NO_FAIL', 'false').lower() == 'true': pytest.skip(f"{input_market} market is not received yet") else: assert False, f"{input_market} market is not received" friday_date = get_friday() log.info(f"Step4: assert Insights NMF playlist has valid date = {friday_date}") assert insights_nmf_data['newMusicFridayByDate']['date'] == friday_date, \ f"Insights NMF playlist has different date than {friday_date}" log.info("Step5: check Insights NMF playlist has the same number of ISRCs as in Spotify") if insights_nmf_data['newMusicFridayByDate']['entries']['total'] != len(spotify_nmf_data): log.warning(f"Insights NMF playlist has different number of ISRCs than in Spotify:" f"\n Spotify: {len(spotify_nmf_data)}" f"\n Insights: {insights_nmf_data['newMusicFridayByDate']['entries']['total']}" ) log.info("Step6: Compare ISRCs in Spotify and Insights playlists") spotify_entries = [(pos + 1, track['isrc'], track['name']) for pos, track in enumerate(spotify_nmf_data)] insights_entries = [ (pos + 1, entry['isrc']['isrc'], entry['trackName']) for pos, entry in enumerate(insights_nmf_entries) ] for pos, isrc, name in spotify_entries: log.debug(f"SPOTIFY position {pos}: {isrc} - {name}") for pos, isrc, name in insights_entries: log.debug(f"INSIGHTS position {pos}: {isrc} - {name}") spotify_isrc_set = {isrc.lower() for _, isrc, _ in spotify_entries} insights_isrc_set = {isrc.lower() for _, isrc, _ in insights_entries} # A single missing/extra ISRC shifts every position after it, turning the rest of a # plain positional diff into noise. Report the actual missing/extra ISRCs first; # only fall back to a positional diff once we know both playlists have the same set. missing_from_insights = [e for e in spotify_entries if e[1].lower() not in insights_isrc_set] missing_from_spotify = [e for e in insights_entries if e[1].lower() not in spotify_isrc_set] if missing_from_insights or missing_from_spotify: error_lines = [ f" - position {pos} in Spotify: {isrc} \"{name}\" is missing from Insights" for pos, isrc, name in missing_from_insights ] + [ f" - position {pos} in Insights: {isrc} \"{name}\" is not present on Spotify" for pos, isrc, name in missing_from_spotify ] pytest.fail( f"[{input_market}] {len(missing_from_insights)} ISRC(s) missing from Insights, " f"{len(missing_from_spotify)} ISRC(s) extra in Insights:\n" + "\n".join(error_lines) ) order_mismatches = [ f" - position {s_pos}: Spotify has {s_isrc} \"{s_name}\", Insights has {i_isrc} \"{i_name}\"" for (s_pos, s_isrc, s_name), (i_pos, i_isrc, i_name) in zip(spotify_entries, insights_entries) if s_isrc.lower() != i_isrc.lower() ] assert not order_mismatches, ( f"[{input_market}] Same ISRCs present in both playlists, but ordered differently:\n" + "\n".join(order_mismatches) ) log.info(f"Step7: assert Insights NMF playlist's ISRC has correct position in market {input_market}") tested_isrc_index = 0 start_position_spotify = tested_isrc_index + 1 tested_isrc = spotify_nmf_data[tested_isrc_index]['isrc'] insights_isrc_placements = insights_nmf_entries[tested_isrc_index]['placements'] log.debug(insights_isrc_placements) placement = next((x for x in insights_isrc_placements if x["market"] == input_market), None) assert placement['position'] == start_position_spotify, \ f"{tested_isrc} ISRC has different position in Insights for this market"