import pytest from datetime import date, timedelta from flask import url_for from http import HTTPStatus from typing import List, Tuple from apollo_main_db.spotify.models import ViewPlaylistTypeEnum from src.constants import http_status from src.constants.core import BuzzCategories from src.legacy.spotify.constants import SPOTIFY_PLAYLIST_IMAGE_URL_MASK from tests.api.playlists.test_playlists_nmf import get_date, get_dates, get_nmf_playlists, get_nmf_tracklists from tests.api.tracks.test_tracks_playlists import get_nmf_track from tests.legacy.apollo_api.factories import ApolloKeyValueStorageFactory, ApolloMarketFactory from tests.legacy.spotify import factories from tests.legacy.util import generate_view_playlists pytest_plugins = ["tests.legacy.vendor_api.fixtures.vendor_responses", "tests.legacy.dsp_api.fixtures.dsp_responses"] @pytest.mark.parametrize( "playlists_ids", ( ( "2fC7gpl3V9MmCc8gBPHc66", "2gTVwMFCnX19DWgIwY0blq", "2p9jkSudWhl1Go1z0sWdPG", "35cYKVvuwQVueUm13M7pP0", "37i9dQZF1DWSAJ2OGLglOP", ), None, ("2fC7gpl3V9MmCc8gBPHc66",), ("2fC7gpl3V9MmCc8gBPHc98",), ("35cYKVvuwQVueUm13M7pP0", "37i9dQZF1DWSAJ2OGLglOP"), ), ) def test_personalized_playlists_view(db_session, user_id, client, patch_auth_user, playlists_ids): patch_auth_user(user_id) ids = { "2fC7gpl3V9MmCc8gBPHc66", "2gTVwMFCnX19DWgIwY0blq", "2p9jkSudWhl1Go1z0sWdPG", "35cYKVvuwQVueUm13M7pP0", "37i9dQZF1DWSAJ2OGLglOP", } for pl_id in ids: factories.SpotifyPersonalizedPlaylistFactory.create(playlist_id=pl_id) params = {} if playlists_ids: params["playlist_ids"] = playlists_ids url = url_for("spotify_blueprint.personalized-playlists", **params) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK data = response.json expected = ids & set(playlists_ids) if playlists_ids else ids assert len(data) == len(expected) for _id in data: assert _id in expected def test_track_playlists_trends_view(db_session, user_id, client, patch_auth_user): patch_auth_user(user_id) isrc = "QZES71982312" track_1 = factories.SpotifyTrack2Factory.create(isrc=isrc, id="1") track_2 = factories.SpotifyTrack2Factory.create(isrc=isrc, id="2") pl_1 = factories.SpotifyPlaylistFactory.create(id="1", name="pl 1") pl_2 = factories.SpotifyPlaylistFactory.create(id="2", name="pl 2") pl_3 = factories.SpotifyPlaylistFactory.create(id="3", name="pl 3") pl_4 = factories.SpotifyPlaylistFactory.create(id="4", name="pl 4") pl_5 = factories.SpotifyPlaylistFactory.create(id="5", name="pl 5") factories.SpotifyPlaylistTrackList2Factory.create(playlist_id=pl_1.id, track_id=track_1.id, playlist_index=2) factories.SpotifyPlaylistTrackList2Factory.create(playlist_id=pl_2.id, track_id=track_1.id, playlist_index=1) factories.SpotifyPlaylistTrackList2Factory.create(playlist_id=pl_3.id, track_id=track_1.id, playlist_index=1) factories.SpotifyPlaylistTrackList2Factory.create(playlist_id=pl_4.id, track_id=track_1.id, playlist_index=5) factories.SpotifyPlaylistTrackList2Factory.create(playlist_id=pl_4.id, track_id=track_2.id, playlist_index=2) factories.SpotifyPlaylistTrackList2Factory.create(playlist_id=pl_5.id, track_id=track_2.id, playlist_index=10) factories.SpotifyPlaylistTrackList2Factory.create(playlist_id=pl_5.id, track_id=track_2.id, playlist_index=2) today = date.today() factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=1, date=(today - timedelta(days=1)).isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=1, date=(today - timedelta(days=2)).isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_1.id, date=(today - timedelta(days=1)).isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=1, date=(today - timedelta(days=1)).isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=1, date=(today - timedelta(days=2)).isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=2, date=(today - timedelta(days=3)).isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_2.id, date=(today - timedelta(days=3)).isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_3.id, track_id=track_1.id, playlist_index=1, date=(today - timedelta(days=2)).isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_3.id, date=(today - timedelta(days=2)).isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_4.id, track_id=track_2.id, playlist_index=4, date=(today - timedelta(days=2)).isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_4.id, date=(today - timedelta(days=2)).isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_5.id, track_id=track_2.id, playlist_index=20, date=(today - timedelta(days=2)).isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_5.id, date=(today - timedelta(days=2)).isoformat() ) playlists_ids = [pl_1.id, pl_2.id, pl_3.id, pl_4.id, pl_5.id] positions = [1, -1, 0, -2, -18] url = url_for("v1_spotify_blueprint.track-playlists-trends-v1", isrc=isrc, playlist_ids=",".join(playlists_ids)) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK for i in range(5): assert response.json[playlists_ids[i]]["position"] == positions[i] assert "changed_date" in response.json[playlists_ids[i]] def test_tracks_playlists_stats_view(db_session, user_id, client, patch_auth_user): """Test for tracks-playlists-stats view.""" patch_auth_user(user_id) isrc_list = [f"isrc_{i}" for i in range(2)] tracks_per_isrc = 2 playlists_per_track = 4 history_date = date(2020, 1, 1) for i in range(1, tracks_per_isrc + 1): for k, isrc in enumerate(isrc_list, 1): track_id = f"track_id_{k * 10 + i}" factories.SpotifyTrack2Factory.create(isrc=isrc, id=track_id) for j in range(1, playlists_per_track + 1): playlist_id = f"playlist_id_{k * 100 + i * 10 + j}" factories.SpotifyPlaylistFactory.create( id=playlist_id, buzz_category_id=BuzzCategories.SONY if j % 2 == 0 else BuzzCategories.SPOTIFY ) if j != playlists_per_track: factories.SpotifyPlaylistTrackList2Factory.create(playlist_id=playlist_id, track_id=track_id) if j in (1, playlists_per_track): factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=playlist_id, date=history_date.isoformat() ) if j != 1: factories.SpotifyTrackPlaylistLastWeekHistoryFactory.create( date=history_date.isoformat(), isrc=isrc, playlist_id=playlist_id ) url = url_for("spotify_blueprint.tracks-playlists-stats", isrc=",".join(isrc_list), dates=history_date) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK assert len(response.json) == len(isrc_list) for isrc in isrc_list: response_item = next(i for i in response.json if i["isrc"] == isrc) assert response_item["current"] == [ {"category_id": BuzzCategories.SONY, "playlist_count": tracks_per_isrc * (playlists_per_track // 2 - 1)}, {"category_id": BuzzCategories.SPOTIFY, "playlist_count": tracks_per_isrc * playlists_per_track // 2}, ] assert response_item["history"] == [ { "date": history_date.isoformat(), "category_id": BuzzCategories.SONY, "added": 0, "removed": tracks_per_isrc, }, { "date": history_date.isoformat(), "category_id": BuzzCategories.SPOTIFY, "added": tracks_per_isrc, "removed": 0, }, ] @pytest.mark.parametrize( "playlist_ids,response_dict", ( ( ["1aaa"], { "items": [ { "id": "1aaa", "market": {"id": 1, "code": "us", "full_name": "the United States", "name": "United States"}, } ] }, ), ( ["1aaa", "3aaa"], { "items": [ { "id": "1aaa", "market": {"id": 1, "code": "us", "full_name": "the United States", "name": "United States"}, } ] }, ), ( ["4aaa", "2aaa"], { "items": [ {"id": "2aaa", "market": {"id": 2, "code": "au", "full_name": "Australia", "name": "Australia"}}, {"id": "4aaa", "market": {"id": 4, "code": "ua", "full_name": "Ukraine", "name": "Ukraine"}}, ] }, ), ), ) def test_playlists_markets_view(db_session, user_id, client, patch_auth_user, playlist_ids, response_dict): patch_auth_user(user_id) ApolloMarketFactory.create(id=1, code="us", name="United States", full_name="the United States", is_primary=True) ApolloMarketFactory.create(id=2, code="au", name="Australia", full_name="Australia", is_primary=True) ApolloMarketFactory.create(id=3, code="br", name="Brazil", full_name="Brazil", is_primary=True) ApolloMarketFactory.create(id=4, code="ua", name="Ukraine", full_name="Ukraine", is_primary=True) ApolloMarketFactory.create(id=5, code="pl", name="Poland", full_name="Poland", is_primary=False) factories.SpotifyPlaylistFactory.create(id="1aaa", country_code="us") factories.SpotifyPlaylistFactory.create(id="2aaa", country_code="au") factories.SpotifyPlaylistFactory.create(id="3aaa", country_code="pl") factories.SpotifyPlaylistFactory.create(id="4aaa", country_code="ua") url = url_for("v1_spotify_blueprint.playlists-markets-v1", id=",".join(playlist_ids)) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK assert response.json == response_dict @pytest.mark.parametrize( "playlist_ids,include_owner_data,response_dict", ( ( ["1aaa"], False, { "items": [ { "id": "1aaa", "name": "playlist 1", "country_code": "us", "updated_date": None, "followers": None, "image_url": SPOTIFY_PLAYLIST_IMAGE_URL_MASK.format(playlist_id="1aaa"), "curator_name": "user 1", "personalized": True, } ] }, ), ( ["4aaa", "2aaa"], False, { "items": [ { "id": "2aaa", "name": "playlist 2", "country_code": "au", "updated_date": None, "followers": None, "image_url": SPOTIFY_PLAYLIST_IMAGE_URL_MASK.format(playlist_id="2aaa"), "curator_name": "user 2", "personalized": False, }, { "id": "4aaa", "name": "playlist 4", "country_code": "ua", "updated_date": None, "followers": None, "image_url": SPOTIFY_PLAYLIST_IMAGE_URL_MASK.format(playlist_id="4aaa"), "curator_name": "user 4", "personalized": True, }, ] }, ), ( ["1aaa"], True, { "items": [ { "id": "1aaa", "name": "playlist 1", "country_code": "us", "updated_date": None, "followers": None, "image_url": SPOTIFY_PLAYLIST_IMAGE_URL_MASK.format(playlist_id="1aaa"), "curator_name": "User 1", "personalized": True, } ] }, ), ), ) def test_playlists_data_view( db_session, user_id, client, patch_auth_user, playlist_ids, include_owner_data, response_dict ): patch_auth_user(user_id) factories.SpotifyPlaylistFactory.create(id="1aaa", country_code="us", name="playlist 1", user_name="user 1") factories.SpotifyPlaylistFactory.create(id="2aaa", country_code="au", name="playlist 2", user_name="user 2") factories.SpotifyPlaylistFactory.create(id="3aaa", country_code="pl", name="playlist 3", user_name="user 3") factories.SpotifyPlaylistFactory.create(id="4aaa", country_code="ua", name="playlist 4", user_name="user 4") factories.SpotifyPersonalizedPlaylistFactory.create(playlist_id="1aaa") factories.SpotifyPersonalizedPlaylistFactory.create(playlist_id="4aaa") factories.BuzzUserFactory.create(user_name="user 1", display_name="User 1") url = url_for( "v1_spotify_blueprint.playlists-data-v1", id=",".join(playlist_ids), include_owner_data=include_owner_data ) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK assert response.json == response_dict @pytest.mark.parametrize( "isrc,recent_adds_only,markets,search,response_dict", ( ( "isrc11111111", False, None, None, { "count": 3, "items": [ { "added_date": (date.today() - timedelta(days=20)).isoformat(), "country_code": "au", "current_position": 2, "id": "2asf3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-2asf3.jpeg", "is_new": False, "name": "pl two", "personalized": False, "position_change_date": None, "track_id": "tr1", "trend": 0, "updated_date": None, }, { "added_date": (date.today() - timedelta(days=12)).isoformat(), "country_code": "us", "current_position": 11, "id": "1ws2d", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-1ws2d.jpeg", "is_new": False, "name": "pl one", "personalized": False, "position_change_date": (date.today() - timedelta(days=6)).isoformat(), "track_id": "tr1", "trend": 6, "updated_date": None, }, { "added_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "us", "current_position": 5, "id": "3asd3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-3asd3.jpeg", "is_new": False, "name": "pl three", "personalized": True, "position_change_date": None, "track_id": "tr1", "trend": None, "updated_date": None, }, ], }, ), ( "isrc11111111", True, None, None, { "count": 1, "items": [ { "added_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "us", "current_position": 5, "id": "3asd3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-3asd3.jpeg", "is_new": False, "name": "pl three", "personalized": True, "position_change_date": None, "track_id": "tr1", "trend": None, "updated_date": None, } ], }, ), ( "isrc22222222", False, None, None, { "count": 3, "items": [ { "added_date": (date.today() - timedelta(days=20)).isoformat(), "country_code": "us", "current_position": 9, "id": "3asd3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-3asd3.jpeg", "is_new": False, "name": "pl three", "personalized": True, "position_change_date": None, "track_id": "tr2", "trend": None, "updated_date": None, }, { "added_date": (date.today() - timedelta(days=12)).isoformat(), "country_code": "us", "current_position": 14, "id": "1ws2d", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-1ws2d.jpeg", "is_new": False, "name": "pl one", "personalized": False, "position_change_date": (date.today() - timedelta(days=12)).isoformat(), "track_id": "tr2", "trend": 9, "updated_date": None, }, { "added_date": (date.today() - timedelta(days=1)).isoformat(), "country_code": "au", "current_position": 5, "id": "2asf3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-2asf3.jpeg", "is_new": False, "name": "pl two", "personalized": False, "position_change_date": (date.today() - timedelta(days=1)).isoformat(), "track_id": "tr2", "trend": -1, "updated_date": None, }, ], }, ), ( "isrc22222222", True, None, None, { "count": 1, "items": [ { "added_date": (date.today() - timedelta(days=1)).isoformat(), "country_code": "au", "current_position": 5, "id": "2asf3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-2asf3.jpeg", "is_new": False, "name": "pl two", "personalized": False, "position_change_date": (date.today() - timedelta(days=1)).isoformat(), "track_id": "tr2", "trend": -1, "updated_date": None, } ], }, ), ( "isrc11111111", False, ["us"], None, { "count": 2, "items": [ { "added_date": (date.today() - timedelta(days=12)).isoformat(), "country_code": "us", "current_position": 11, "id": "1ws2d", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-1ws2d.jpeg", "is_new": False, "name": "pl one", "personalized": False, "position_change_date": (date.today() - timedelta(days=6)).isoformat(), "track_id": "tr1", "trend": 6, "updated_date": None, }, { "added_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "us", "current_position": 5, "id": "3asd3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-3asd3.jpeg", "is_new": False, "name": "pl three", "personalized": True, "position_change_date": None, "track_id": "tr1", "trend": None, "updated_date": None, }, ], }, ), ( "isrc11111111", False, None, "one", { "count": 1, "items": [ { "added_date": (date.today() - timedelta(days=12)).isoformat(), "country_code": "us", "current_position": 11, "id": "1ws2d", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-1ws2d.jpeg", "is_new": False, "name": "pl one", "personalized": False, "position_change_date": (date.today() - timedelta(days=6)).isoformat(), "track_id": "tr1", "trend": 6, "updated_date": None, } ], }, ), ), ) def test_track_playlists_view_v1( db_session, user_id, client, patch_auth_user, isrc, response_dict, recent_adds_only, markets, search ): patch_auth_user(user_id) today = date.today() date_1 = today - timedelta(days=1) date_2 = today - timedelta(days=3) date_3 = today - timedelta(days=6) date_4 = today - timedelta(days=20) date_5 = today - timedelta(days=12) date_6 = today - timedelta(days=50) track_1 = factories.SpotifyTrack2Factory(id="tr1", name="track 1", isrc="isrc11111111") track_2 = factories.SpotifyTrack2Factory(id="tr2", name="track 2", isrc="isrc22222222") pl_1 = factories.SpotifyPlaylistFactory.create(id="1ws2d", name="pl one", country_code="us") pl_2 = factories.SpotifyPlaylistFactory.create(id="2asf3", name="pl two", country_code="au") pl_3 = factories.SpotifyPlaylistFactory.create(id="3asd3", name="pl three", country_code="us") factories.SpotifyPersonalizedPlaylistFactory.create(playlist_id=pl_3.id) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=10, added_datetime=date_4, added_earliest_datetime=date_4, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=1, added_datetime=date_6, added_earliest_datetime=date_6, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_3.id, track_id=track_1.id, playlist_index=4, added_datetime=date_2, added_earliest_datetime=date_2, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=13, added_datetime=date_6, added_earliest_datetime=date_6, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_2.id, track_id=track_2.id, playlist_index=4, added_datetime=date_1, added_earliest_datetime=date_1, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_3.id, track_id=track_2.id, playlist_index=8, added_datetime=date_4, added_earliest_datetime=date_4, ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=4, date=date_3 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=8, date=date_5 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=7, date=date_4 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_3.id, track_id=track_1.id, playlist_index=12, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=4, date=date_5 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_2.id, playlist_index=5, date=date_1 ) url = url_for( "v1_spotify_blueprint.track-playlists-v1", isrc=isrc, recent_adds_only=recent_adds_only, market=markets, search=search, ) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK data = response.json assert data["count"] == response_dict["count"] assert data["items"] == response_dict["items"] @pytest.mark.parametrize( "isrc,recent_removals_only,markets,search,exclude_current_playlists,include,response_dict", ( ( "isrc11111111", False, None, None, False, [], { "count": 4, "items": [ { "removed_date": (date.today() - timedelta(days=1)).isoformat(), "country_code": "us", "id": "1ws2d", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-1ws2d.jpeg", "name": "pl one", "personalized": False, "track_id": "tr1", "updated_date": None, "added_date": None, }, { "removed_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "lv", "id": "3asd3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-3asd3.jpeg", "name": "pl three", "personalized": True, "track_id": "tr1", "updated_date": None, "added_date": None, }, { "removed_date": (date.today() - timedelta(days=6)).isoformat(), "country_code": "au", "id": "2asf3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-2asf3.jpeg", "name": "pl two", "personalized": False, "track_id": "tr1", "updated_date": None, "added_date": (date.today() - timedelta(days=25)).isoformat(), }, { "removed_date": (date.today() - timedelta(days=12)).isoformat(), "country_code": "us", "id": "4asd4", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-4asd4.jpeg", "name": "pl four", "personalized": False, "track_id": "tr1", "updated_date": None, "added_date": None, }, ], }, ), ( "isrc11111111", True, None, None, True, [], { "count": 2, "items": [ { "removed_date": (date.today() - timedelta(days=1)).isoformat(), "country_code": "us", "id": "1ws2d", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-1ws2d.jpeg", "name": "pl one", "personalized": False, "track_id": "tr1", "updated_date": None, "added_date": None, }, { "removed_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "lv", "id": "3asd3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-3asd3.jpeg", "name": "pl three", "personalized": True, "track_id": "tr1", "updated_date": None, "added_date": None, }, ], }, ), ( "isrc11111111", True, ["lv"], None, True, [], { "count": 1, "items": [ { "removed_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "lv", "id": "3asd3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-3asd3.jpeg", "name": "pl three", "personalized": True, "track_id": "tr1", "updated_date": None, "added_date": None, } ], }, ), ( "isrc22222222", True, None, None, True, [], { "count": 2, "items": [ { "removed_date": (date.today() - timedelta(days=1)).isoformat(), "country_code": "au", "id": "2asf3", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-2asf3.jpeg", "name": "pl two", "personalized": False, "track_id": "tr2", "updated_date": None, "added_date": None, }, { "removed_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "us", "id": "4asd4", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-4asd4.jpeg", "name": "pl four", "personalized": False, "track_id": "tr2", "updated_date": None, "added_date": None, }, ], }, ), ( "isrc22222222", True, None, "four", True, [], { "count": 1, "items": [ { "removed_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "us", "id": "4asd4", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-4asd4.jpeg", "name": "pl four", "personalized": False, "track_id": "tr2", "updated_date": None, "added_date": None, } ], }, ), ( "isrc22222222", True, None, "four", True, ["owner", "followers"], { "count": 1, "items": [ { "removed_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "us", "id": "4asd4", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-4asd4.jpeg", "name": "pl four", "personalized": False, "track_id": "tr2", "updated_date": None, "added_date": None, "category_id": 5, "category_name": "Spotify", "followers": 123456, } ], }, ), ( "isrc22222222", True, None, "four", True, ["categories"], { "count": 1, "items": [ { "removed_date": (date.today() - timedelta(days=3)).isoformat(), "country_code": "us", "id": "4asd4", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-4asd4.jpeg", "name": "pl four", "personalized": False, "track_id": "tr2", "updated_date": None, "added_date": None, "category_id": 5, "category_name": "Spotify", } ], "categories": [ { "category_id": 5, "category_name": "Spotify", } ], }, ), ), ) def test_previous_track_playlists_view_v1( db_session, user_id, client, patch_auth_user, isrc, response_dict, recent_removals_only, markets, search, exclude_current_playlists, include, ): patch_auth_user(user_id) today = date.today() date_1_day_ago = today - timedelta(days=1) date_3_days_ago = today - timedelta(days=3) date_5_days_ago = today - timedelta(days=5) date_6_days_ago = today - timedelta(days=6) date_12_days_ago = today - timedelta(days=12) date_13_days_ago = today - timedelta(days=13) date_20_days_ago = today - timedelta(days=20) date_25_days_ago = today - timedelta(days=25) track_1 = factories.SpotifyTrack2Factory(id="tr1", name="track 1", isrc="isrc11111111") track_2 = factories.SpotifyTrack2Factory(id="tr2", name="track 2", isrc="isrc22222222") track_3 = factories.SpotifyTrack2Factory(id="tr3", name="track 3", isrc="isrc11111111") pl_1 = factories.SpotifyPlaylistFactory.create(id="1ws2d", name="pl one", country_code="us", removed=0) pl_2 = factories.SpotifyPlaylistFactory.create(id="2asf3", name="pl two", country_code="au", removed=0) pl_3 = factories.SpotifyPlaylistFactory.create(id="3asd3", name="pl three", country_code="lv", removed=0) pl_4 = factories.SpotifyPlaylistFactory.create( id="4asd4", name="pl four", country_code="us", removed=0, buzz_category_id=5, user_name="user1" ) factories.SpotifyPersonalizedPlaylistFactory.create(playlist_id=pl_3.id) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=8, added_datetime=date_1_day_ago, added_earliest_datetime=date_25_days_ago, ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=4, date=date_1_day_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=8, date=date_20_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_1.id, date=date_1_day_ago.isoformat(), timestamp=date_1_day_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_1.id, date=date_20_days_ago.isoformat(), timestamp=date_20_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_3.id, playlist_index=14, date=date_5_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_3.id, playlist_index=18, date=date_13_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_1.id, date=date_5_days_ago.isoformat(), timestamp=date_5_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_1.id, date=date_13_days_ago.isoformat(), timestamp=date_13_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=7, date=date_6_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=12, date=date_12_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_2.id, date=date_6_days_ago.isoformat(), timestamp=date_6_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_2.id, date=date_12_days_ago.isoformat(), timestamp=date_12_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_3.id, track_id=track_1.id, playlist_index=7, date=date_3_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_3.id, track_id=track_1.id, playlist_index=12, date=date_20_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_3.id, date=date_3_days_ago.isoformat(), timestamp=date_3_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_3.id, date=date_20_days_ago.isoformat(), timestamp=date_20_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_4.id, track_id=track_1.id, playlist_index=7, date=date_12_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_4.id, track_id=track_1.id, playlist_index=12, date=date_20_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_4.id, date=date_12_days_ago.isoformat(), timestamp=date_12_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_4.id, date=date_20_days_ago.isoformat(), timestamp=date_20_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_2.id, playlist_index=4, date=date_1_day_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_2.id, playlist_index=8, date=date_20_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_2.id, date=date_1_day_ago.isoformat(), timestamp=date_1_day_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_2.id, date=date_20_days_ago.isoformat(), timestamp=date_20_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_4.id, track_id=track_2.id, playlist_index=14, date=date_3_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_4.id, track_id=track_2.id, playlist_index=13, date=date_25_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_4.id, date=date_3_days_ago.isoformat(), timestamp=date_3_days_ago.isoformat() ) factories.SpotifyPlaylistTrackListHistoryDates2Factory.create( playlist_id=pl_4.id, date=date_25_days_ago.isoformat(), timestamp=date_25_days_ago.isoformat() ) factories.BuzzCategoryFactory.create(id=5, name="Spotify") factories.BuzzUserFactory.create(id=1, user_name="user1", country_code="us") factories.SpotifyPlaylistFollowersFactory.create(playlist_id="4asd4", followers=123456) url = url_for( "v1_spotify_blueprint.track-previous-playlists-v1", isrc=isrc, recent_removals_only=recent_removals_only, market=markets, search=search, exclude_current_playlists=exclude_current_playlists, include=include, ) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK data = response.json assert data["count"] == response_dict["count"] assert data["items"] == response_dict["items"] def get_date_iso(days: int or None) -> str or None: if not days: return None return (date.today() - timedelta(days=days)).isoformat() def get_playlist_item( playlist_index: int, track_index: int, added_days: int or None, change_days: int or None, country_code: str, position: int, trend: int or None, is_new: bool = False, personalized: bool = False, streams_7_days: int or None = None, followers: int or None = None, include_track_count: bool = False, include_user_name: bool = False, category_id: int or None = None, include: Tuple[str] = None, # allowed values are "trend", "is_new", "position_change_date". ) -> dict: include = include or tuple() return { "id": f"pl{playlist_index}", "name": f"playlist {playlist_index}", "track_id": f"tr{track_index}", "added_date": get_date_iso(added_days), "country_code": country_code, "current_position": position, "image_url": f"https://dhfsk7jl2g0km.cloudfront.net/playlist-pl{playlist_index}.jpeg", **({"is_new": is_new} if "is_new" in include else {}), "personalized": personalized, **({"position_change_date": get_date_iso(change_days)} if "position_change_date" in include else {}), **({"trend": trend} if "trend" in include else {}), "updated_date": None, **({"track_count": playlist_index * 20} if include_track_count else {}), **({"username": f"user{playlist_index}"} if include_user_name else {}), **({"playlist_streams": streams_7_days} if streams_7_days is not None else {}), **({"followers": followers} if followers is not None else {}), **( { "category_name": {5: "Spotify"}.get(category_id), "category_id": category_id, } if category_id else {} ), } def get_playlist_result(*data, **kwargs) -> dict: return {"count": kwargs.get("count", len(data)), "items": list(data)} @pytest.mark.parametrize( "params,status,expected_result", ( ({}, HTTPStatus.BAD_REQUEST, None), ({"isrc": "isrc1", "order_by": "playlist_streams"}, HTTPStatus.BAD_REQUEST, None), ( {"isrc": "isrc1", "order_by": "-id"}, HTTPStatus.OK, get_playlist_result( get_playlist_item(3, 1, 3, None, "us", 5, None, personalized=True), get_playlist_item(2, 1, 50, None, "au", 2, 0), get_playlist_item(1, 1, 20, 6, "us", 11, 6), ), ), ( {"isrc": "isrc2"}, HTTPStatus.OK, get_playlist_result( get_playlist_item(3, 2, 20, None, "us", 9, None, personalized=True), get_playlist_item(1, 2, 50, 12, "us", 14, 9), get_playlist_item(2, 2, 1, 1, "au", 5, -1), ), ), ( {"isrc": "isrc1", "market": ["us"]}, HTTPStatus.OK, get_playlist_result( get_playlist_item(1, 1, 20, 6, "us", 11, 6), get_playlist_item(3, 1, 3, None, "us", 5, None, personalized=True), ), ), ( {"isrc": "isrc1", "search": "st 1"}, HTTPStatus.OK, get_playlist_result(get_playlist_item(1, 1, 20, 6, "us", 11, 6)), ), ( { "isrc": ["isrc1", "isrc2"], "include": "all", "streams_market": ["us", "gb", "ca"], "order_by": ["current_position"], "limit": 1, }, HTTPStatus.OK, get_playlist_result( get_playlist_item( 2, 1, 50, 1, "au", 2, -4, include_track_count=True, include_user_name=True, followers=0, streams_7_days=57978, category_id=5, ), count=3, ), ), ( {"isrc": "isrc1", "include": ["playlist_streams", "track_count"], "order_by": ["id"], "limit": 2}, HTTPStatus.OK, get_playlist_result( get_playlist_item(1, 1, 20, 6, "us", 11, 6, include_track_count=True, streams_7_days=12954), get_playlist_item(2, 1, 50, None, "au", 2, 0, include_track_count=True, streams_7_days=63622), count=3, ), ), ( {"isrc": "isrc1", "include": ["owner"], "order_by": ["id"], "limit": 2}, HTTPStatus.OK, get_playlist_result( get_playlist_item(1, 1, 20, 6, "us", 11, 6, category_id=5), get_playlist_item(2, 1, 50, None, "au", 2, 0, category_id=5), count=3, ), ), ), ) def test_track_playlists_view_v2(params, status, expected_result, user_id, client, patch_auth_user, db_session): patch_auth_user(user_id) today = date.today() dates = [today - timedelta(days=i) for i in (1, 3, 6, 20, 12, 50)] tracks = [factories.SpotifyTrack2Factory(id=f"tr{i}", name=f"track {i}", isrc=f"isrc{i}") for i in range(1, 4)] def owner_included(include=None): if include: return include == "all" or "owner" in include playlists = [ factories.SpotifyPlaylistFactory.create( id=f"pl{i + 1}", name=f"playlist {i + 1}", country_code=country_code, track_count=((i + 1) * 20), user_name=f"user{i + 1}", buzz_category_id=(5 if owner_included(params.get("include")) else None), ) for i, country_code in enumerate(("us", "au", "us", "gb", "ca")) ] [factories.SpotifyPersonalizedPlaylistFactory.create(playlist_id=playlists[i].id) for i in (2, 3)] [ factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=data[0].id, track_id=data[1].id, playlist_index=data[2], added_datetime=data[3], added_earliest_datetime=data[3], ) for data in ( (playlists[0], tracks[0], 10, dates[3]), (playlists[1], tracks[0], 1, dates[5]), (playlists[2], tracks[0], 4, dates[1]), (playlists[0], tracks[1], 13, dates[5]), (playlists[1], tracks[1], 4, dates[0]), (playlists[2], tracks[1], 8, dates[3]), ) ] [ factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=data[0].id, track_id=data[1].id, playlist_index=data[2], date=data[3] ) for data in ( (playlists[0], tracks[0], 4, dates[2]), (playlists[0], tracks[0], 8, dates[4]), (playlists[1], tracks[0], 7, dates[3]), (playlists[2], tracks[0], 12, dates[1]), (playlists[0], tracks[1], 4, dates[4]), (playlists[1], tracks[1], 5, dates[0]), ) ] [ factories.SpotifyPlaylistStreamSummaryFactory.create( playlist_id=data[0].id, market=data[1], streams_7_days=data[2] ) for data in ( (playlists[0], "us", 10200), (playlists[0], "gb", 2401), (playlists[0], "au", 353), (playlists[1], "us", 4566), (playlists[1], "ca", 53412), (playlists[1], "au", 5644), ) ] factories.BuzzCategoryFactory.create(id=5, name="Spotify") [ factories.BuzzUserFactory.create(id=i + 1, user_name=f"user{i + 1}", country_code=country_code) for i, country_code in enumerate(("us", "au", "us", "gb", "ca")) ] [ factories.SpotifyPlaylistFollowersFactory.create(playlist_id=data[0].id, followers=data[1]) for data in ((playlists[0], 43257), (playlists[2], 8674), (playlists[3], 4758423)) ] url = url_for("v2_spotify_blueprint.track-playlists-v2", **params) response = client.get(url) assert response.status_code == status if status == HTTPStatus.OK: data = response.json assert data["count"] == expected_result["count"] assert sorted(data["items"], key=lambda x: x["id"]) == sorted(expected_result["items"], key=lambda x: x["id"]) @pytest.mark.parametrize( "params,response_dict", ( ( {"id": "pl_1_id,pl_2_id", "market": "us", "start_date": "2021-04-30", "end_date": "2021-05-02"}, { "count": 2, "dates": {"end": "2021-05-02", "start": "2021-04-30"}, "items": [ { "coordinates": [ {"x": 1619740800, "y": None}, {"x": 1619827200, "y": 100}, {"x": 1619913600, "y": 80}, ], "country_code": "us", "playlist_id": "pl_1_id", }, { "coordinates": [ {"x": 1619740800, "y": None}, {"x": 1619827200, "y": 200}, {"x": 1619913600, "y": 130}, ], "country_code": "us", "playlist_id": "pl_2_id", }, ], "next": None, "previous": None, }, ), ( {"id": "pl_1_id", "market": "us,_gl", "start_date": "2021-05-01", "end_date": "2021-05-03"}, { "count": 2, "dates": {"end": "2021-05-03", "start": "2021-05-01"}, "items": [ { "coordinates": [ {"x": 1619827200, "y": 100}, {"x": 1619913600, "y": 80}, {"x": 1620000000, "y": 95}, ], "country_code": "us", "playlist_id": "pl_1_id", }, { "coordinates": [ {"x": 1619827200, "y": 130}, {"x": 1619913600, "y": 115}, {"x": 1620000000, "y": 155}, ], "country_code": "_gl", "playlist_id": "pl_1_id", }, ], "next": None, "previous": None, }, ), ( {"id": "pl_1_id", "market": "us,_gl", "start_date": "2021-06-01", "end_date": "2021-06-03"}, { "count": 0, "dates": {"end": "2021-06-03", "start": "2021-06-01"}, "items": [], "next": None, "previous": None, }, ), ), ) def test_playlists_listener_graph_view(db_session, user_id, client, patch_auth_user, params, response_dict): patch_auth_user(user_id) factories.SpotifyPlaylistLegacyUriFactory.create(playlist_uri="pl_1_uri", playlist_id="pl_1_id") factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 1), playlist_uri="pl_1_uri", listeners=100 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 2), playlist_uri="pl_1_uri", listeners=80 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 3), playlist_uri="pl_1_uri", listeners=95 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 1), playlist_uri="pl_1_uri", listeners=30 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 2), playlist_uri="pl_1_uri", listeners=35 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 3), playlist_uri="pl_1_uri", listeners=60 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 1), playlist_uri="pl_2_id", listeners=200 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 2), playlist_uri="pl_2_id", listeners=130 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 3), playlist_uri="pl_2_id", listeners=195 ) url = url_for("v1_spotify_blueprint.playlists-listeners-graph-v1", **params) response = client.get(url) assert response.status_code == HTTPStatus.OK data = response.json assert data == response_dict @pytest.mark.parametrize( "playlist_id,params,response_dict", ( ( "pl_1_id", {"market": "gb", "start_date": "2021-05-04", "end_date": "2021-05-06"}, { "current_range": 60, "dates": { "current_range": {"end": "2021-05-06", "start": "2021-05-04"}, "prev_range": {"end": "2021-05-03", "start": "2021-05-01"}, }, "prev_range": 30, }, ), ( "pl_1_id", {"start_date": "2021-05-01", "end_date": "2021-05-02"}, { "current_range": 195, "dates": { "current_range": {"end": "2021-05-02", "start": "2021-05-01"}, "prev_range": {"end": "2021-04-30", "start": "2021-04-29"}, }, "prev_range": None, }, ), ( "pl_2_id", {"market": "us", "start_date": "2021-05-04", "end_date": "2021-05-06"}, { "current_range": None, "dates": { "current_range": {"end": "2021-05-06", "start": "2021-05-04"}, "prev_range": {"end": "2021-05-03", "start": "2021-05-01"}, }, "prev_range": None, }, ), ( "pl_1_id", {"market": "us", "start_date": "2021-05-02", "end_date": "2021-05-04"}, { "current_range": 215, "dates": { "current_range": {"end": "2021-05-04", "start": "2021-05-02"}, "prev_range": {"end": "2021-05-01", "start": "2021-04-29"}, }, "prev_range": 100, }, ), ), ) def test_playlist_date_range_listeners_views( db_session, client, user_id, patch_auth_user, playlist_id, params, response_dict ): patch_auth_user(user_id) factories.SpotifyPlaylistLegacyUriFactory.create(playlist_uri="pl_1_uri", playlist_id="pl_1_id") factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 1), playlist_uri="pl_1_uri", listeners=100 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 2), playlist_uri="pl_1_uri", listeners=80 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 3), playlist_uri="pl_1_uri", listeners=95 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 4), playlist_uri="pl_1_uri", listeners=40 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 5), playlist_uri="pl_1_uri", listeners=55 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="us", date=date(2021, 5, 6), playlist_uri="pl_1_uri", listeners=10 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 1), playlist_uri="pl_1_uri", listeners=10 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 2), playlist_uri="pl_1_uri", listeners=5 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 3), playlist_uri="pl_1_uri", listeners=15 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 4), playlist_uri="pl_1_uri", listeners=30 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 5), playlist_uri="pl_1_uri", listeners=20 ) factories.SpotifyAnalyticsPlaylistStreamInfoFactory.create( market="gb", date=date(2021, 5, 6), playlist_uri="pl_1_uri", listeners=10 ) url = url_for("v1_spotify_blueprint.playlist-listeners-date-range-v1", playlist_id=playlist_id, **params) response = client.get(url) assert response.status_code == HTTPStatus.OK data = response.json assert data == response_dict @pytest.mark.parametrize( "date_list,expected_result", ( (get_dates(5, 20, 3, 2), get_dates(2, 3, 5, 20, as_str=True)), (get_dates(4), get_dates(4, as_str=True)), (get_dates(6, 15), get_dates(6, 15, as_str=True)), ), ) def test_nmf_available_dates_view(date_list, expected_result, db_session, user_id, client, patch_auth_user): patch_auth_user(user_id) for index, item in enumerate(date_list): factories.SpotifyNewMusicFridayDateFactory.create(date=item, id=(index + 1)) response = client.get(url_for("spotify_blueprint.nmf-available-dates")) assert response.status_code == HTTPStatus.OK assert response.json == expected_result @pytest.mark.parametrize( "playlists_data,expected_result", ( (get_nmf_playlists(with_name=True), get_nmf_playlists(dates_str=True, with_name=True)), ( get_nmf_playlists(count=1, zero_followers_index=1, with_name=True), get_nmf_playlists(count=1, zero_followers_index=1, dates_str=True, with_name=True), ), ( get_nmf_playlists(count=9, zero_followers_index=1, with_name=True), get_nmf_playlists(count=9, zero_followers_index=1, dates_str=True, with_name=True), ), ), ) def test_nmf_playlists_view(playlists_data, expected_result, db_session, user_id, client, patch_auth_user): patch_auth_user(user_id) generate_view_playlists( playlists_data, ViewPlaylistTypeEnum.NMF, playlist_id_field="playlistId", market_code_field="countryCode", last_date_field="fridayLastUpdatedDate", last_added_ts_field="trackLastAdded", add_extra=False, ) for item in playlists_data: if item["followers"]: factories.SpotifyPlaylistFollowersFactory.create( playlist_id=item["playlistId"], followers=item["followers"] ) response = client.get(url_for("spotify_blueprint.nmf-playlists")) assert response.status_code == HTTPStatus.OK assert response.json == expected_result @pytest.mark.parametrize( "params,expected_status,track_data,expected_result", ( ({}, HTTPStatus.BAD_REQUEST, None, None), ( {"nmf_date": date.today()}, HTTPStatus.OK, get_nmf_tracklists(with_image=True), get_nmf_tracklists(dates_str=True, is_response=True, with_image=True), ), ( {"nmf_date": date.today()}, HTTPStatus.OK, get_nmf_tracklists(count=1, with_image=True), get_nmf_tracklists(count=1, dates_str=True, is_response=True, with_image=True), ), ( {"nmf_date": date.today(), "limit": 2}, HTTPStatus.OK, get_nmf_tracklists(with_image=True), get_nmf_tracklists(limit=2, dates_str=True, is_response=True, with_image=True), ), ( {"nmf_date": date.today(), "offset": 1, "limit": 2}, HTTPStatus.OK, get_nmf_tracklists(with_image=True), get_nmf_tracklists(offset=1, limit=2, dates_str=True, is_response=True, with_image=True), ), ), ) def test_nmf_tracklist_view( params, expected_status, track_data, expected_result, db_session, user_id, client, patch_auth_user ): patch_auth_user(user_id) nmf_date = params.get("nmf_date") if nmf_date: for i in range(2): factories.SpotifyNewMusicFridayDateFactory.create(id=(i + 1), date=(nmf_date - timedelta(days=i))) generate_view_playlists( [p for t in track_data for p in t["playlists"]], ViewPlaylistTypeEnum.NMF, playlist_id_field="playlistId", market_code_field="countryCode", ) for index, track in enumerate(track_data): for playlist in track["playlists"]: for j in range(2): factories.SpotifyNewMusicFridayPlaylistTrackHistoryFactory.create( date_id=(j + 1), playlist_id=playlist["playlistId"], playlist_index=playlist["position"] - 1, track_id=track["trackId"], added=playlist["addedDate"], isrc=track["isrc"], ) factories.SpotifyPlaylistFactory.create(id=playlist["playlistId"], image=playlist["playlistImageUrl"]) response = client.get(url_for("spotify_blueprint.nmf-tracklist", **params)) assert response.status_code == expected_status if expected_status == HTTPStatus.OK: assert response.json["items"] == expected_result def test_nmf_completeness(db_session, user_id, client, patch_auth_user): patch_auth_user(user_id) last_updated = "2021-11-28T23:31:36.473541" updated_markets = ["ua", "us"] markets_delayed = ["ca", "de", "fr"] ApolloKeyValueStorageFactory.create(key="nmf_job_run_ts", value=last_updated) factories.SpotifyNewMusicFridayDateFactory.create(date=date(2021, 11, 28), id=2) factories.SpotifyNewMusicFridayDateFactory.create(date=date(2021, 11, 21), id=1) playlist_data = [ {"playlist_id": f"playlist_{index}", "market": item, "rank": index, "last_date": "2021-11-28"} for index, item in enumerate(updated_markets, 1) ] playlist_data.extend( [ {"playlist_id": f"playlist_{index}", "market": item, "rank": index, "last_date": "2021-11-21"} for index, item in enumerate(markets_delayed, 10) ] ) generate_view_playlists(playlist_data, ViewPlaylistTypeEnum.NMF, add_extra=False) response = client.get(url_for("spotify_blueprint.nmf-completeness")) assert last_updated == response.json["last_updated"] assert response.json["markets_delayed"] == markets_delayed assert False if set(response.json["markets_delayed"]).intersection(updated_markets) else True @pytest.mark.parametrize( "personalized_id,response_dict", ( ( "pl_1", { "count": 3, "items": [ { "added_date": (date.today() - timedelta(days=4)).isoformat(), "artists": ["artist three"], "current_position": 1, "isrc": "TCAEA1802695", "name": "track three", "track_id": "1Cv1YLb4q0RzL6pybtaMLo", "album_id": "album2", }, { "added_date": (date.today() - timedelta(days=30)).isoformat(), "artists": ["artist two"], "current_position": 4, "isrc": "RUB421901499", "name": "track two", "track_id": "24Yi9hE78yPEbZ4kxyoXAI", "album_id": "album1", }, { "added_date": (date.today() - timedelta(days=4)).isoformat(), "artists": ["artist one"], "current_position": 13, "isrc": "QZJRC1945204", "name": "track one", "track_id": "62aP9fBQKYKxi7PDXwcUAS", "album_id": "album1", }, ], }, ), ), ) def test_personalized_playlist_tracklist_view( db_session, mocker, user_id, client, patch_auth_user, personalized_id, response_dict, spotify_track_image_response, spotify_playlist_tracklist, ): patch_auth_user(user_id) today = date.today() date_1 = today - timedelta(days=2) date_2 = today - timedelta(days=12) date_3 = today - timedelta(days=30) date_4 = today - timedelta(days=4) track_1 = factories.SpotifyTrack2Factory.create(id="62aP9fBQKYKxi7PDXwcUAS", isrc="QZJRC1945204", name="track one") track_2 = factories.SpotifyTrack2Factory.create(id="24Yi9hE78yPEbZ4kxyoXAI", isrc="RUB421901499", name="track two") track_3 = factories.SpotifyTrack2Factory.create( id="1Cv1YLb4q0RzL6pybtaMLo", isrc="TCAEA1802695", name="track three" ) artist_1 = factories.SpotifyArtistFactory.create(id="art1", name="artist one") artist_2 = factories.SpotifyArtistFactory.create(id="art2", name="artist two") artist_3 = factories.SpotifyArtistFactory.create(id="art3", name="artist three") factories.SpotifyTrackArtistFactory.create(track_id=track_1.id, artist_id=artist_1.id, order=0) factories.SpotifyTrackArtistFactory.create(track_id=track_2.id, artist_id=artist_2.id, order=0) factories.SpotifyTrackArtistFactory.create(track_id=track_3.id, artist_id=artist_3.id, order=0) album_1 = factories.SpotifyAlbumFactory.create(id="album1", name="album one") album_2 = factories.SpotifyAlbumFactory.create(id="album2", name="album two") factories.SpotifyTrackAlbumFactory.create(track_id=track_1.id, album_id=album_1.id) factories.SpotifyTrackAlbumFactory.create(track_id=track_2.id, album_id=album_1.id) factories.SpotifyTrackAlbumFactory.create(track_id=track_3.id, album_id=album_2.id) pl_1 = factories.SpotifyPlaylistFactory.create(id="pl_1", name="playlist one") pl_2 = factories.SpotifyPlaylistFactory.create(id="pl_2", name="playlist two") factories.SpotifyPersonalizedPlaylistFactory.create(playlist_id=personalized_id) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=4, date=date_1 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=7, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=11, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=12, date=date_3 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=9, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_3.id, playlist_index=3, date=date_1 ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=12, added_datetime=date_4, added_earliest_datetime=date_4, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=3, added_datetime=date_3, added_earliest_datetime=date_3, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_3.id, playlist_index=0, added_datetime=date_4, added_earliest_datetime=date_4, ) url = url_for("spotify_blueprint.personalized-playlist-tracklist", playlist_id=personalized_id) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK data = response.json assert data == response_dict @pytest.mark.parametrize( "params,track_data,expected_status,expected_result", ( ({}, get_nmf_track(with_name=True), HTTPStatus.BAD_REQUEST, None), ( {"isrc": "GBAHT1800503"}, get_nmf_track(isrc="GBAHT1800503", limit=2, with_name=True), HTTPStatus.OK, { "count": 2, "previous": None, "next": None, "items": [ { "playlist_id": "pl_2", "top_market": 7, "position": 7, "code": "tw", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_2.jpeg", "dsp": "spotify", "region": "as", "name": "TW", "playlist_name": "plname_2", }, { "playlist_id": "pl_3", "top_market": 8, "position": 10, "code": "id", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_3.jpeg", "dsp": "spotify", "region": "as", "name": "ID", "playlist_name": "plname_3", }, ], "positions_avg": 8, "positions_top_total": 2, "total": 6, }, ), ( {"isrc": "GBAHT1800503", "include": ["inactive_markets"]}, get_nmf_track(isrc="GBAHT1800503", limit=2, with_name=True), HTTPStatus.OK, { "count": 2, "previous": None, "next": None, "items": [ { "playlist_id": "pl_2", "top_market": 7, "position": 7, "code": "tw", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_2.jpeg", "dsp": "spotify", "region": "as", "name": "TW", "playlist_name": "plname_2", }, { "playlist_id": "pl_3", "top_market": 8, "position": 10, "code": "id", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_3.jpeg", "dsp": "spotify", "region": "as", "name": "ID", "playlist_name": "plname_3", }, ], "positions_avg": 8, "positions_top_total": 2, "total": 2, }, ), ( {"isrc": "GBAHT1800503", "include": ["top_playlist_image_url", "regions"]}, get_nmf_track(isrc="GBAHT1800503", limit=3, with_name=True), HTTPStatus.OK, { "count": 3, "previous": None, "next": None, "items": [ { "playlist_id": "pl_2", "top_market": 7, "position": 7, "code": "tw", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_2.jpeg", "dsp": "spotify", "region": "as", "name": "TW", "playlist_name": "plname_2", }, { "playlist_id": "pl_3", "top_market": 8, "position": 10, "code": "id", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_3.jpeg", "dsp": "spotify", "region": "as", "name": "ID", "playlist_name": "plname_3", }, { "playlist_id": "pl_4", "top_market": 9, "position": 13, "code": "my", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_4.jpeg", "dsp": "spotify", "region": "as", "name": "MY", "playlist_name": "plname_4", }, ], "positions_avg": 10, "positions_top_total": 2, "top_playlist_image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_2.jpeg", "regions": [ {"code": "all", "name": "All markets", "total": 9, "placements": 3}, {"code": "as", "name": "Asia", "total": 6, "placements": 3}, ], "total": 9, }, ), ( {"isrc": "GBAHT1800503", "region": "as", "include": ["regions"]}, get_nmf_track(isrc="GBAHT1800503", limit=3, with_name=True), HTTPStatus.OK, { "count": 3, "previous": None, "next": None, "items": [ { "playlist_id": "pl_2", "top_market": 7, "position": 7, "code": "tw", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_2.jpeg", "dsp": "spotify", "region": "as", "name": "TW", "playlist_name": "plname_2", }, { "playlist_id": "pl_3", "top_market": 8, "position": 10, "code": "id", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_3.jpeg", "dsp": "spotify", "region": "as", "name": "ID", "playlist_name": "plname_3", }, { "playlist_id": "pl_4", "top_market": 9, "position": 13, "code": "my", "image_url": "https://dhfsk7jl2g0km.cloudfront.net/playlist-pl_4.jpeg", "dsp": "spotify", "region": "as", "name": "MY", "playlist_name": "plname_4", }, ], "total": 6, "positions_avg": 10, "positions_top_total": 2, "regions": [ {"code": "all", "name": "All markets", "total": 9, "placements": 3}, {"code": "as", "name": "Asia", "total": 6, "placements": 3}, ], }, ), ), ) def test_nmf_track_view( params, track_data, expected_status, expected_result, db_session, user_id, client, patch_auth_user ): patch_auth_user(user_id) latest_date = date.today() - timedelta(days=1) playlist_data = [{"last_date": latest_date.strftime("%Y-%m-%d"), **item} for item in track_data] playlist_data.append({"playlist_id": "randomId", "market": "kr", "rank": 20}) generate_view_playlists( playlist_data, ViewPlaylistTypeEnum.NMF, add_extra="inactive_markets" not in params.get("include", []) ) for item in track_data: factories.SpotifyNewMusicFridayPlaylistTrackHistoryFactory.create( playlist_id=item["playlist_id"], isrc=item["isrc"], playlist_index=item["index"], date_id=item["index"] ) factories.SpotifyNewMusicFridayDateFactory.create(id=item["index"], date=latest_date) factories.SpotifyPlaylistFactory.create( id="randomId", name="Random Playlist", ) response = client.get(url_for("spotify_blueprint.nmf-track", **params)) assert response.status_code == expected_status if expected_status == HTTPStatus.OK: assert response.json == expected_result @pytest.mark.parametrize( "isrc,personalized_id,playlist_type,response_dict", ( ( "QZJRC1945204", "pl_2", "current", { "added_date": (date.today() - timedelta(days=30)).isoformat(), "changed_date": None, "country_code": "us", "current_position": 13, "earliest_added_date": (date.today() - timedelta(days=7)).isoformat(), "isrc": "QZJRC1945204", "personalized": False, "playlist_id": "pl_1", "playlist_image": "XXX", "playlist_name": "playlist one", "track_id": "62aP9fBQKYKxi7PDXwcUAS", "track_name": "track one", }, ), ( "RUB421901499", "pl_1", "current", { "added_date": (date.today() - timedelta(days=15)).isoformat(), "changed_date": None, "country_code": "us", "current_position": 4, "earliest_added_date": (date.today() - timedelta(days=15)).isoformat(), "isrc": "RUB421901499", "personalized": True, "playlist_id": "pl_1", "playlist_image": "XXX", "playlist_name": "playlist one", "track_id": "24Yi9hE78yPEbZ4kxyoXAI", "track_name": "track two", }, ), ( "RUB421901499", "pl_2", "current", { "added_date": (date.today() - timedelta(days=15)).isoformat(), "changed_date": None, "country_code": "us", "current_position": 4, "earliest_added_date": (date.today() - timedelta(days=15)).isoformat(), "isrc": "RUB421901499", "personalized": False, "playlist_id": "pl_1", "playlist_image": "XXX", "playlist_name": "playlist one", "track_id": "24Yi9hE78yPEbZ4kxyoXAI", "track_name": "track two", }, ), ( "AUZS21100040", "pl_2", "past", { "changed_date": None, "country_code": "us", "earliest_added_date": (date.today() - timedelta(days=30)).isoformat(), "isrc": "AUZS21100040", "personalized": False, "playlist_id": "pl_1", "playlist_image": "XXX", "playlist_name": "playlist one", "removed_date": (date.today() - timedelta(days=7)).isoformat(), "track_id": "04oRIdTNvXIiFzyinEvnqX", "track_name": "track four", }, ), ), ) def test_playlist_track_view( db_session, user_id, client, patch_auth_user, isrc, playlist_type, response_dict, personalized_id, ): patch_auth_user(user_id) today = date.today() date_1 = today - timedelta(days=1) date_2 = today - timedelta(days=7) date_3 = today - timedelta(days=15) date_4 = today - timedelta(days=30) track_1 = factories.SpotifyTrack2Factory.create(id="62aP9fBQKYKxi7PDXwcUAS", isrc="QZJRC1945204", name="track one") track_2 = factories.SpotifyTrack2Factory.create(id="24Yi9hE78yPEbZ4kxyoXAI", isrc="RUB421901499", name="track two") track_3 = factories.SpotifyTrack2Factory.create( id="1Cv1YLb4q0RzL6pybtaMLo", isrc="TCAEA1802695", name="track three" ) track_4 = factories.SpotifyTrack2Factory.create(id="04oRIdTNvXIiFzyinEvnqX", isrc="AUZS21100040", name="track four") artist_1 = factories.SpotifyArtistFactory.create(id="art1", name="artist one") artist_2 = factories.SpotifyArtistFactory.create(id="art2", name="artist two") artist_3 = factories.SpotifyArtistFactory.create(id="art3", name="artist three") artist_4 = factories.SpotifyArtistFactory.create(id="art4", name="artist four") factories.SpotifyTrackArtistFactory.create(track_id=track_1.id, artist_id=artist_1.id, order=0) factories.SpotifyTrackArtistFactory.create(track_id=track_2.id, artist_id=artist_2.id, order=0) factories.SpotifyTrackArtistFactory.create(track_id=track_3.id, artist_id=artist_3.id, order=0) factories.SpotifyTrackArtistFactory.create(track_id=track_4.id, artist_id=artist_4.id, order=0) pl_1 = factories.SpotifyPlaylistFactory.create(id="pl_1", name="playlist one", image="XXX", country_code="us") pl_2 = factories.SpotifyPlaylistFactory.create(id="pl_2", name="playlist two", image="UUU", country_code="fr") factories.SpotifyPersonalizedPlaylistFactory.create(playlist_id=personalized_id) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=4, date=date_1 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=7, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=11, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=12, date=date_3 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=9, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_3.id, playlist_index=3, date=date_1 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_4.id, playlist_index=2, date=date_4 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_4.id, playlist_index=1, date=date_2 ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=12, added_datetime=date_4, added_earliest_datetime=date_4, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=3, added_datetime=date_3, added_earliest_datetime=date_3, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_3.id, playlist_index=0, added_datetime=date_4, added_earliest_datetime=date_4, ) url = url_for("spotify_blueprint.track-in-playlist", playlist_id="pl_1", isrc=isrc, playlist_type=playlist_type) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK data = response.json assert data == response_dict @pytest.mark.parametrize( "isrc,playlist_id,response_dict", ( ( "QZJRC1945204", "pl_1", { "QZJRC1945204": { "5": (date.today() - timedelta(days=1)).isoformat(), "7": (date.today() - timedelta(days=7)).isoformat(), } }, ), ( "QZJRC1945204", "pl_2", {"QZJRC1945204": {"2": (date.today() - timedelta(days=1)).isoformat()}}, ), ( "QZJRC1945204", "pl_3", {}, ), ( "XXXX21901499", "pl_2", {}, ), ( "RUB421901499", "pl_1", {}, ), ( "RUB421901499", "pl_2", { "RUB421901499": { "11": (date.today() - timedelta(days=7)).isoformat(), "8": (date.today() - timedelta(days=1)).isoformat(), } }, ), ), ) def test_playlist_track_position_changes_view( db_session, user_id, client, patch_auth_user, isrc, response_dict, playlist_id, ): patch_auth_user(user_id) today = date.today() date_1 = today - timedelta(days=1) date_2 = today - timedelta(days=7) track_1 = factories.SpotifyTrack2Factory.create(id="62aP9fBQKYKxi7PDXwcUAS", isrc="QZJRC1945204", name="track one") track_2 = factories.SpotifyTrack2Factory.create(id="24Yi9hE78yPEbZ4kxyoXAI", isrc="RUB421901499", name="track two") pl_1 = factories.SpotifyPlaylistFactory.create(id="pl_1", name="playlist one") pl_2 = factories.SpotifyPlaylistFactory.create(id="pl_2", name="playlist two") factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=4, date=date_1 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=6, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_1.id, playlist_index=1, date=date_1 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_2.id, playlist_index=7, date=date_1 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_2.id, playlist_index=10, date=date_2 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_2.id, track_id=track_2.id, playlist_index=8, date=date.today() ) url = url_for("spotify_blueprint.track-position-in-playlist", playlist_id=playlist_id, isrc=isrc) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK data = response.json assert data == response_dict @pytest.mark.parametrize( "playlist_id,response_dict", ( ( "1ws2d", { "tracklist": [ { "added_date": (date.today() - timedelta(days=1)).isoformat(), "album_id": "album_id_1", "artists": ["Motley Crue"], "current_position": 2, "isrc": "isrc11111111", "name": "Wild Side", "track_id": "tr1", }, { "added_date": (date.today() - timedelta(days=3)).isoformat(), "album_id": "album_id_2", "artists": ["Papa Roach"], "current_position": 3, "isrc": "isrc22222222", "name": "Born For Greatness", "track_id": "tr2", }, { "added_date": (date.today() - timedelta(days=6)).isoformat(), "album_id": "album_id_3", "artists": ["Stone Sour"], "current_position": 12, "isrc": "isrc33333333", "name": "Song #3", "track_id": "tr3", }, { "added_date": (date.today() - timedelta(days=20)).isoformat(), "album_id": "album_id_4", "artists": ["Sixx A.M."], "current_position": 13, "isrc": "isrc44444444", "name": "Life is Beautiful", "track_id": "tr4", }, ], "tracks_keys": {"ids": ["tr1", "tr2", "tr3", "tr4"]}, }, ), ("1ws2f", {"tracklist": [], "tracks_keys": {"ids": []}}), ), ) def test_personalized_playlist_playlists_view_v1( db_session, user_id, client, patch_auth_user, playlist_id, response_dict ): patch_auth_user(user_id) today = date.today() date_1 = today - timedelta(days=1) date_2 = today - timedelta(days=3) date_3 = today - timedelta(days=6) date_4 = today - timedelta(days=20) track_1 = factories.SpotifyTrack2Factory(id="tr1", name="Wild Side", isrc="isrc11111111") track_2 = factories.SpotifyTrack2Factory(id="tr2", name="Born For Greatness", isrc="isrc22222222") track_3 = factories.SpotifyTrack2Factory(id="tr3", name="Song #3", isrc="isrc33333333") track_4 = factories.SpotifyTrack2Factory(id="tr4", name="Life is Beautiful", isrc="isrc44444444") pl_1 = factories.SpotifyPlaylistFactory.create(id="1ws2d", name="pl one") factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_1.id, playlist_index=1, added_datetime=date_1, added_earliest_datetime=date_1, ) factories.SpotifyPlaylistTrackList2Factory( playlist_id=pl_1.id, track_id=track_2.id, playlist_index=2, added_datetime=date_2, added_earliest_datetime=date_2, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_3.id, playlist_index=11, added_datetime=date_3, added_earliest_datetime=date_3, ) factories.SpotifyPlaylistTrackList2Factory.create( playlist_id=pl_1.id, track_id=track_4.id, playlist_index=12, added_datetime=date_4, added_earliest_datetime=date_4, ) factories.SpotifyTrackAlbumFactory(track_id=track_1.id, album_id="album_id_1") factories.SpotifyTrackAlbumFactory(track_id=track_2.id, album_id="album_id_2") factories.SpotifyTrackAlbumFactory(track_id=track_3.id, album_id="album_id_3") factories.SpotifyTrackAlbumFactory(track_id=track_4.id, album_id="album_id_4") artist_1 = factories.SpotifyArtistFactory(id="artist_1", name="Motley Crue") artist_2 = factories.SpotifyArtistFactory(id="artist_2", name="Papa Roach") artist_3 = factories.SpotifyArtistFactory(id="artist_3", name="Stone Sour") artist_4 = factories.SpotifyArtistFactory(id="artist_4", name="Sixx A.M.") factories.SpotifyTrackArtistFactory(track_id=track_1.id, artist_id=artist_1.id) factories.SpotifyTrackArtistFactory(track_id=track_2.id, artist_id=artist_2.id) factories.SpotifyTrackArtistFactory(track_id=track_3.id, artist_id=artist_3.id) factories.SpotifyTrackArtistFactory(track_id=track_4.id, artist_id=artist_4.id) url = url_for("v1_spotify_blueprint.personalized-playlist-tracklist-v1", playlist_id=playlist_id) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK data = response.json assert data == response_dict @pytest.mark.parametrize( "playlist_id,response_dict", ( ( "MyTestsRocks", { "isrc11111111": { "earliest_added_date": (date.today() - timedelta(days=3)).isoformat(), "latest_added_date": (date.today() - timedelta(days=1)).isoformat(), "update_date": (date.today() - timedelta(days=1)).isoformat(), }, "isrc22222222": { "earliest_added_date": (date.today() - timedelta(days=6)).isoformat(), "latest_added_date": (date.today() - timedelta(days=1)).isoformat(), "update_date": (date.today() - timedelta(days=1)).isoformat(), }, }, ), ("NoDataTest", {}), ), ) def test_tracks_dates_in_playlist(db_session, user_id, client, patch_auth_user, playlist_id, response_dict): patch_auth_user(user_id) today = date.today() date_1 = today - timedelta(days=1) date_2 = today - timedelta(days=3) date_3 = today - timedelta(days=6) track_1 = factories.SpotifyTrack2Factory(id="tr1", name="Never Too Late", isrc="isrc11111111") track_2 = factories.SpotifyTrack2Factory(id="tr2", name="Rock`n Roll Queen", isrc="isrc22222222") pl_1 = factories.SpotifyPlaylistFactory.create( id="MyTestsRocks", name="pl one", country_code="us", update_timestamp=date_1 ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, playlist_index=1, track_id=track_1.id, date=date_1, ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, playlist_index=3, track_id=track_1.id, date=date_2, ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, playlist_index=2, track_id=track_2.id, date=date_1, ) factories.SpotifyPlaylistTrackListHistory2Factory.create( playlist_id=pl_1.id, playlist_index=5, track_id=track_2.id, date=date_3, ) url = url_for("spotify_blueprint.tracks-dates-in-playlist", playlist_id=playlist_id) response = client.get(url) assert response.status_code == http_status.HTTP_200_OK data = response.json assert data == response_dict def get_streams_info(account: int, market: str, date_diff: int, total_streams: int): return {"account": account, "market": market, "date": get_date(date_diff), "total_streams": total_streams} def get_db_markets(count: int = 10, markets: List[str] = None): if not markets: markets = ["us", "gb", "ca"] return [get_streams_info(1, markets[i % len(markets)], i * 3, 100 * i + i) for i in range(1, count + 1)] @pytest.mark.parametrize( "streams_info,expected_result", ((get_db_markets(), ["worldwide", "gb", "us", "ca"]), ([], ["worldwide"])) ) def test_markets_by_streams_view(streams_info, expected_result, user_id, client, patch_auth_user, db_session): patch_auth_user(user_id) for i in range(1, 10): factories.SpotifyAnalyticsAccountStreamInfoFactory(account=i * 10, date=get_date(i * 5)) for item in streams_info: factories.SpotifyAnalyticsAccountStreamInfoFactory(**item) response = client.get(url_for("spotify_blueprint.markets-by-streams")) assert response.status_code == HTTPStatus.OK assert response.json == expected_result