"""Tests for Handlers. It should test endpoints routes, request validation, response encoding, error handling. """ import datetime from unittest.mock import patch import uuid import pytest from flask import url_for from flask.testing import FlaskClient from application import app from charts import handlers from charts.connectors import snowflake from charts.logic import track, cache_prime, charts, digest from charts.logic.dataloaders.chart_groups import chart_ids_dataloader from charts.logic.dataloaders.charts import aggregated_values_dataloader from charts.logic.dataloaders.charts import metadata_dataloader from charts.logic.dataloaders.charts.dates_dataloader import chart_dates_dataloader from charts.logic.dataloaders.charts.chart_date_entry_dataloader import chart_date_entry_dataloader from charts.logic.dataloaders.charts.chart_date_entry_summary_dataloader import chart_date_entry_summary_dataloader from charts.logic.dataloaders.charts.dates import placements_dataloader from charts.logic.dataloaders.charts.dates.placements.private_dataloader import chart_placement_private_data_dataloader from charts.logic.dataloaders.charts.dates.placements import public_dataloader @pytest.fixture def fixture_client() -> FlaskClient: with app.test_client() as client: yield client @pytest.fixture def client() -> FlaskClient: app.config["TESTING"] = True app_context = app.test_request_context() app_context.push() with app.test_client() as client: yield client class TestHelloAndErrorHandling: @patch.object(handlers, "jsonify", side_effect=Exception()) def test_hello_on_exception(self, mock_jsonify, fixture_client): """Test an uncaught Exception results in a 500 status code.""" result = fixture_client.get("/hello/") assert result.status_code == 500 assert result.get_json() == { 'code': 'internal_error', 'message': 'The server encountered an internal error and was unable to ' 'complete your request.'} def test_hello(self, fixture_client): """Test an uncaught Exception results in a 500 status code.""" result = fixture_client.get("/hello/") assert result.status_code == 200 assert result.get_json() == {'status': 'ok'} class TestArtists: artist_id = 123456 base_url = f'/artists/{artist_id}' @pytest.mark.parametrize( 'query_args, expected_chart_filter', [ ( 'chart_id=qw-wq-qe&chart_platform=amazon', {'id': 'qw-wq-qe', 'platform': 'amazon'} ), ( 'chart_country=US&chart_unrelated=shall_not_pass', {'country': 'US'} ), ( 'chart_genre=alien_songs&chart_target=some_target&chart_type=some_type', {'genre': 'alien_songs', 'target': 'some_target', 'type': 'some_type', } ), ]) def test_get_artist_aggregated_rankings(self, query_args, expected_chart_filter, fixture_client): route = f'{self.base_url}/aggregated?{query_args}' with patch.object(handlers.artist, 'get_artist_aggregated_rankings') as logic_mock: fixture_client.get(route) assert logic_mock.call_count == 1 kwargs = logic_mock.call_args[1] assert kwargs['artist_id'] == self.artist_id assert kwargs['chart_filter'] == expected_chart_filter @pytest.mark.parametrize( 'query_args, expected_kwargs', [ ( 'chart_id=&chart_date=', { 'artist_id': 123456, 'chart_id': '', 'chart_date': '', 'chart_filter': {}, 'isrc': None, 'only_current': False, 'public_sound_recording_id': None } ), ( '', { 'artist_id': 123456, 'chart_id': None, 'chart_date': None, 'chart_filter': {}, 'isrc': None, 'only_current': False, 'public_sound_recording_id': None } ), ( 'chart_id=xxx-yyyy-zzzz&chart_date=2020-01-31', { 'artist_id': 123456, 'chart_id': 'xxx-yyyy-zzzz', 'chart_date': '2020-01-31', 'chart_filter': { 'id': 'xxx-yyyy-zzzz', }, 'isrc': None, 'only_current': False, 'public_sound_recording_id': None } ), ]) def test_get_artist_current_appearances(self, query_args, expected_kwargs, fixture_client): route = f'{self.base_url}/current-appearances?{query_args}' with patch.object(handlers.artist, 'artist_current_appearances') as logic_mock: fixture_client.get(route) assert logic_mock.call_count == 1 kwargs = logic_mock.call_args[1] assert kwargs == expected_kwargs class TestChart: chart_from_model = { 'chartId': '7038104f-8845-4a36-b274-ade706d627e3', 'name': 'Amazon Daily Folk', 'platform': 'amazon', 'target': 'track', 'country': 'GLOBAL', 'type': 'default', 'frequency': 'daily', 'genre': 'Folk', 'latestChartDate': '2021-01-19', 'createdAt': datetime.datetime(2021, 2, 11, 11, 19, 16), 'modifiedAt': datetime.datetime(2021, 2, 11, 17, 41, 55) } chart_expected = { 'chartId': '7038104f-8845-4a36-b274-ade706d627e3', 'country': 'GLOBAL', 'createdAt': 'Thu, 11 Feb 2021 11:19:16 GMT', 'frequency': 'daily', 'genre': 'Folk', 'latestChartDate': '2021-01-19', 'modifiedAt': 'Thu, 11 Feb 2021 17:41:55 GMT', 'name': 'Amazon Daily Folk', 'platform': 'amazon', 'target': 'track', 'type': 'default' } def test_get_charts(self, fixture_client): route = '/charts/' mock_return_value = [self.chart_from_model] with patch.object(handlers.chart, 'get_charts', return_value=mock_return_value): response = fixture_client.get(route) data = response.get_json() assert data == [self.chart_expected] def test_get_chart(self, fixture_client): route = '/charts/7038104f-8845-4a36-b274-ade706d627e3/' with patch.object(handlers.chart, 'get_chart', return_value=self.chart_from_model): response = fixture_client.get(route) data = response.get_json() assert data == self.chart_expected def test_get_chart_available_dates(self, fixture_client): route = '/charts/7038104f-8845-4a36-b274-ade706d627e3/dates/' mock_return_value = [ '2021-01-02', '2021-01-03', ] with patch.object(handlers.chart, 'get_chart_available_dates', return_value=mock_return_value): response = fixture_client.get(route) data = response.get_json() assert data == [ '2021-01-02', '2021-01-03', ] def test_get_chart_rankings(self, fixture_client): route = '/charts/7038104f-8845-4a36-b274-ade706d627e3/dates/2021-01-02' mock_return_value = [ {'chartDate': datetime.date(2021, 4, 23), 'isrc': 'GBQXY2060043', 'position': 1, 'positionChange': 0, 'publicSoundRecordingId': '1234-1234-1234-1234', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B08C74122X'}, {'chartDate': datetime.date(2021, 4, 23), 'isrc': 'DEA800026501', 'position': 2, 'positionChange': 0, 'publicSoundRecordingId': '1234-1234-1234-1111', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B00CWQBMP2'} ] with patch.object(handlers.chart, 'get_chart_rankings', return_value=mock_return_value): response = fixture_client.get(route) data = response.get_json() assert data == [ {'chartDate': 'Fri, 23 Apr 2021 00:00:00 GMT', 'isrc': 'GBQXY2060043', 'position': 1, 'positionChange': 0, 'publicSoundRecordingId': '1234-1234-1234-1234', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B08C74122X'}, {'chartDate': 'Fri, 23 Apr 2021 00:00:00 GMT', 'isrc': 'DEA800026501', 'position': 2, 'positionChange': 0, 'publicSoundRecordingId': '1234-1234-1234-1111', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B00CWQBMP2'} ] @pytest.mark.parametrize( 'limit_offset, expected_limit_offset', [ [(1, 2), (1, 2)], [(10, 0), (10, 0)], [(10, 11), (10, 11)], [(None, None), (1000, 0)], [(10, None), (10, 0)], [(None, 20), (1000, 20)], [(None, None), Exception], [(-1, 0), Exception], [(0, -1), Exception], ]) def test_get_chart_rankings_limit_offset(self, limit_offset, expected_limit_offset, fixture_client): limit, offset = limit_offset route = f'/charts/7038104f-8845-4a36-b274-ade706d627e3/dates/2021-01-02?limit={limit}&offset={offset}' with patch.object(handlers.chart, 'get_chart_rankings') as get_chart_rankings_mock: if expected_limit_offset == Exception: response = fixture_client.get(route) assert response.status_code == 500 else: fixture_client.get(route) assert get_chart_rankings_mock.called expected_limit, expected_offset = expected_limit_offset assert get_chart_rankings_mock.call_args[0] == ( '7038104f-8845-4a36-b274-ade706d627e3', '2021-01-02', expected_limit, expected_offset ) def test_get_chart_rankings_in_catalog(self, fixture_client): route = '/charts/7038104f-8845-4a36-b274-ade706d627e3/dates/2021-01-02/in_catalog' mock_return_value = [ {'chartDate': datetime.date(2021, 4, 23), 'isrc': 'GBQXY2060043', 'position': 1, 'positionChange': 0, 'publicSoundRecordingId': '1234-1234-1234-1234', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B08C74122X'}, {'chartDate': datetime.date(2021, 4, 23), 'isrc': 'DEA800026501', 'position': 2, 'positionChange': 0, 'publicSoundRecordingId': '1234-1234-1234-1111', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B00CWQBMP2'} ] with patch.object(handlers.chart, 'get_chart_rankings_in_catalog', return_value=mock_return_value): response = fixture_client.get(route) data = response.get_json() assert data == [ {'chartDate': 'Fri, 23 Apr 2021 00:00:00 GMT', 'isrc': 'GBQXY2060043', 'position': 1, 'positionChange': 0, 'publicSoundRecordingId': '1234-1234-1234-1234', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B08C74122X'}, {'chartDate': 'Fri, 23 Apr 2021 00:00:00 GMT', 'isrc': 'DEA800026501', 'position': 2, 'positionChange': 0, 'publicSoundRecordingId': '1234-1234-1234-1111', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B00CWQBMP2'} ] def test_get_chart_song_history(self, fixture_client): route = '/charts/7038104f-8845-4a36-b274-ade706d627e3/song-history/050236c6-062c-4728-8279-98ae7eb5dd19' mock_return_value = [ {'chartDate': datetime.date(2021, 2, 13), 'isrc': 'KRA402000131', 'position': 5, 'positionChange': None, 'publicSoundRecordingId': '050236c6-062c-4728-8279-98ae7eb5dd19', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B08GR81W92'}, {'chartDate': datetime.date(2021, 2, 14), 'isrc': 'KRA402000131', 'position': 6, 'positionChange': None, 'publicSoundRecordingId': '050236c6-062c-4728-8279-98ae7eb5dd19', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B08GR81W92'} ] with patch.object(handlers.chart, 'get_chart_song_history', return_value=mock_return_value): response = fixture_client.get(route) data = response.get_json() assert data == [ {'chartDate': 'Sat, 13 Feb 2021 00:00:00 GMT', 'isrc': 'KRA402000131', 'position': 5, 'positionChange': None, 'publicSoundRecordingId': '050236c6-062c-4728-8279-98ae7eb5dd19', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B08GR81W92'}, {'chartDate': 'Sun, 14 Feb 2021 00:00:00 GMT', 'isrc': 'KRA402000131', 'position': 6, 'positionChange': None, 'publicSoundRecordingId': '050236c6-062c-4728-8279-98ae7eb5dd19', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': 'B08GR81W92'} ] def test_get_chart_product_history(self, fixture_client): route = '/charts/0e80f8fe-38e1-444f-a38f-f4f015915170/product' \ '-history' \ '/06ca6732-e943-4eab-a06b-a2da8c897dfe' mock_return_value = [ {'chartDate': datetime.date(2021, 2, 13), 'isrc': None, 'position': 5, 'positionChange': None, 'publicProductId': '06ca6732-e943-4eab-a06b-a2da8c897dfe', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': None, 'upc': '094636797854'}, {'chartDate': datetime.date(2021, 2, 14), 'isrc': None, 'position': 6, 'positionChange': None, 'publicProductId': '06ca6732-e943-4eab-a06b-a2da8c897dfe', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': None, 'upc': '094636797854'} ] with patch.object(handlers.chart, 'get_chart_product_history', return_value=mock_return_value): response = fixture_client.get(route) data = response.get_json() assert data == [ {'chartDate': 'Sat, 13 Feb 2021 00:00:00 GMT', 'isrc': None, 'position': 5, 'positionChange': None, 'publicProductId': '06ca6732-e943-4eab-a06b-a2da8c897dfe', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': None, 'upc': '094636797854'}, {'chartDate': 'Sun, 14 Feb 2021 00:00:00 GMT', 'isrc': None, 'position': 6, 'positionChange': None, 'publicProductId': '06ca6732-e943-4eab-a06b-a2da8c897dfe', 'streams': None, 'totalShazams': None, 'totalStreams': None, 'trackId': None, 'upc': '094636797854'} ] @pytest.mark.parametrize( 'params,status,mocked_response,expected_response', [ [{}, 500, [], None], [{"isrc": "USSM12209777"}, 500, [], None], # missing required "platforms" param [{"platforms": ["spotify"]}, 500, [], None], # missing required "isrc" param [{"isrc": "USSM12209777", "platforms": ["spotify"]}, 200, [], []], [{"isrc": "USSM12209777", "platforms": ["spotify", "applemusic"]}, 200, [], []], [{"isrc": "USSM12209777", "platforms": ["spotify", "applemusic"]}, 200, [{"chart_name": "Apple Music Daily Top 100", "latest_chart_date": datetime.date.today(), "track_in_chart_most_recent_position": 62, "chart_most_recent_timestamp": datetime.date.today(), "track_in_chart_previous_position": 55, "chart_country_code": "SA", "track_first_added_date": datetime.date.today(), "track_last_added_date": datetime.date.today(), "platform": "APPLEMUSIC", "track_in_chart_streams": None, "definition_key_mapping": "applemusic_default_daily", "last_date_track_was_added_to_chart": datetime.date.today(), "countries": [ { "chart_name": "Apple Music Daily Top 100", "latest_chart_date": datetime.date.today(), "track_in_chart_most_recent_position": 62, "chart_most_recent_timestamp": datetime.date.today(), "track_in_chart_previous_position": 55, "chart_country_code": "SA", "track_first_added_date": datetime.date.today(), "track_last_added_date": datetime.date.today(), "chart_frequency": "daily", "platform": "APPLEMUSIC", "track_in_chart_streams": None, "days_between_records_update": 2, "definition_key_mapping": "applemusic_default_daily", "last_date_track_was_added_to_chart": datetime.date.today() }]}], [{"chartCount": 1, "chartDate": datetime.date.today().isoformat(), "chartName": "Daily Top 100", "countries": [ {"addedDate": datetime.date.today().isoformat(), "countryCode": 'SA', "currentPosition": 62, "newlyEntered": True, "positionChange": None, "streamsNumber": None }], "platform": "APPLEMUSIC"}]] ] ) def test_get_track_charts(self, params, status, mocked_response, client, expected_response): with patch.object(track, 'get_track_charts', return_value=mocked_response): response = client.get(url_for("get_track_charts", **params)) resp_status_code = response.status_code assert resp_status_code == status if resp_status_code == 200: resp_json = response.get_json() assert resp_json == expected_response @pytest.mark.parametrize( 'params,status,mocked_response,expected_response', [ [{}, 500, [], None], [{"platforms": ["spotify"]}, 200, [], []], [{"platforms": ["spotify", "applemusic"]}, 200, [], []], [{"platforms": ["spotify"]}, 200, [ { "chart_name": "The name does not matter because will be changed in a schema by mapper", "latest_chart_date": datetime.date.today(), "platform": "SPOTIFY", "definition_key_mapping": "spotify_viral_daily" }], [{"chartDate": datetime.date.today().isoformat(), "chartKey": "spotify_viral_daily", "chartName": "Daily Viral 100", "platform": "SPOTIFY" }] ], [{"platforms": ["applemusic"]}, 200, [ { "chart_name": "The name does not matter because will be changed in a schema by mapper", "latest_chart_date": datetime.date.today(), "platform": "APPLE", "definition_key_mapping": "applemusic_default_daily" }], [ { "chartDate": datetime.date.today().isoformat(), "chartKey": "applemusic_default_daily", "chartName": "Daily Top 100", "platform": "APPLE" }] ] ] ) def test_get_charts_by_platforms(self, params, status, mocked_response, client, expected_response): with patch.object(charts, "get_charts_by_platforms_with_latest_dates", return_value=mocked_response): response = client.get(url_for("get_charts_by_platforms", **params)) resp_status_code = response.status_code assert resp_status_code == status if resp_status_code == 200: resp_json = response.get_json() assert resp_json == expected_response def test_get_charts_by_definition(self, fixture_client): route = '/charts/by-definition/?platform=youtube&type=music_videos&frequency=weekly&target=video' mock_return_value = [ {'chartId': 'chart-id-youtube-1'}, {'chartId': 'chart-id-youtube-2'}, ] with patch.object(handlers.charts, 'get_charts_by_definition', return_value=mock_return_value): response = fixture_client.get(route) data = response.get_json() assert data == [ {'chartId': 'chart-id-youtube-1'}, {'chartId': 'chart-id-youtube-2'}, ] def test_get_chart_rankings_for_chart_ids_no_filter_no_cache(self, fixture_client): route = '/charts/rankings-for-chart-ids/' mock_return_value = [ { "data": { 'chartId': 'f4427653-e046-4cd1-813a-bf61806ccf77', 'chartDate': datetime.date(2024, 1, 1), 'uuids': ['75f276b0-21a9-4eeb-a771-0c7604ab5d2a', '2361242f-5436-431f-8c0e-15a8a8e0c9a5'] } }, { "data": None, }, ] with patch.object(handlers, 'get_chart_date_epochs') as mock_get_chart_date_epochs,\ patch.object(handlers, 'get_chart_date_placements_epochs') as mock_get_chart_date_placements_epochs_load_many,\ patch.object(handlers, 'get_ff_charts_cache', return_value=False),\ patch.object(placements_dataloader, '_get_chart_placements_for_chart_dates') as mock_chart_placements_for_chart_date_dataloader_load_many: input = [ { "chart_id": "f4427653-e046-4cd1-813a-bf61806ccf77", "chart_date": "2024-01-01", } ] mock_get_chart_date_epochs.return_value = [ { "chart_id": uuid.UUID("f4427653-e046-4cd1-813a-bf61806ccf77"), "chart_date": datetime.date(2024, 1, 1), "epoch": 0, } ] mock_get_chart_date_placements_epochs_load_many.return_value = [ { "chart_id": uuid.UUID("f4427653-e046-4cd1-813a-bf61806ccf77"), "chart_date": datetime.date(2024, 1, 1), "epoch": 0, } ] mock_chart_placements_for_chart_date_dataloader_load_many.return_value = mock_return_value response = fixture_client.post(route, json={"chart_ids_with_date": input}) data = response.get_json() assert data == [ { "data": { 'chartId': 'f4427653-e046-4cd1-813a-bf61806ccf77', 'chartDate': '2024-01-01', 'uuids': ['75f276b0-21a9-4eeb-a771-0c7604ab5d2a', '2361242f-5436-431f-8c0e-15a8a8e0c9a5'] } }, { "data": None, }, ] mock_chart_placements_for_chart_date_dataloader_load_many.assert_called_once_with( [ { "chart_id": uuid.UUID("f4427653-e046-4cd1-813a-bf61806ccf77"), "chart_date": datetime.date(2024, 1, 1), "epoch": 0, }, ], filter={}, order={ 'by': 'position', 'dir': 'ASC', }, show_sme_data=None, permissions=None, ) def test_get_chart_data_for_chart_ids(self, fixture_client): route = '/charts/data-for-chart-ids/' expected_data = [ { "data": { "chartId": "34f76bdb-4f5b-4917-a47e-02916f7291f5", "chartDate": "2025-04-01", "uuidsData": [ { "uuid": "a54812d9-d77b-43df-8490-6caedfdae081", "chartId": "34f76bdb-4f5b-4917-a47e-02916f7291f5", "chartDate": "2025-04-01", "publicSoundRecordingId": "879c8d5d-2bab-4157-a2bd-52d44dde4a02", "trackId": "7so0lgd0zP2Sbgs2d7a1SZ", "publicProductId": None, "peakTimestamp": "2025-03-07", "peakDate": "2025-03-07", "peakPosition": 1, "appearances": 32, "isrc": "USUM72409273", "firstDate": "2025-03-07", "firstPosition": 1, "mostRecentDate": "2025-04-07", "mostRecentPosition": 1, "previousDate": "2025-04-06", "previousPosition": 1, "position": 1, "positionChange": 0, "streams": 6253227, "totalStreams": None, "totalShazams": None, "views": None, "numTracks": None, "totalUnits": None, "upc": "602475450900", "videoId": None, "channelId": None, "channelName": None, "artistNames": "", "brand_ids": ['111', '222'], "isPartOfCatalog": True }, { "uuid": "c7d8f3b2-ed18-42f3-8103-38cc9dc5ea1a", "chartId": "34f76bdb-4f5b-4917-a47e-02916f7291f5", "chartDate": "2025-04-01", "publicSoundRecordingId": "21e96c6e-9106-424c-87a6-c976c7f21af8", "trackId": "6dOtVTDdiauQNBQEDOtlAB", "publicProductId": None, "peakTimestamp": "2025-07-08", "peakDate": "2025-07-08", "peakPosition": 1, "appearances": 326, "isrc": "USUM72401994", "firstDate": "2025-05-17", "firstPosition": 8, "mostRecentDate": "2025-04-07", "mostRecentPosition": 2, "previousDate": "2025-04-06", "previousPosition": 3, "position": 2, "positionChange": 1, "streams": 4906443, "totalStreams": None, "totalShazams": None, "views": None, "numTracks": None, "totalUnits": None, "upc": "602465630909", "videoId": None, "channelId": None, "channelName": None, "artistNames": "", "brand_ids": None, "isPartOfCatalog": False } ] } } ] with patch.object(handlers, 'get_chart_date_epochs') as mock_get_chart_date_epochs,\ patch.object(handlers, 'get_chart_date_placements_epochs') as mock_get_chart_date_placements_epochs_load_many,\ patch.object(handlers, 'get_ff_charts_cache', return_value=False),\ patch.object(snowflake, 'fetchall_nocache', return_value=False) as fetch: input = [ { "chart_id": "34f76bdb-4f5b-4917-a47e-02916f7291f5", "chart_date": "2025-01-01", } ] mock_get_chart_date_epochs.return_value = [ { "chart_id": uuid.UUID("34f76bdb-4f5b-4917-a47e-02916f7291f5"), "chart_date": datetime.date(2025, 4, 1), "epoch": 0, } ] mock_get_chart_date_placements_epochs_load_many.return_value = [ { "chart_id": uuid.UUID("34f76bdb-4f5b-4917-a47e-02916f7291f5"), "chart_date": datetime.date(2025, 4, 1), "epoch": 0, } ] fetch.return_value = [ ('a54812d9-d77b-43df-8490-6caedfdae081', '34f76bdb-4f5b-4917-a47e-02916f7291f5', datetime.date(2025, 4, 1), 1, 0, 6253227, None, None, None, None, None, '7so0lgd0zP2Sbgs2d7a1SZ', 'USUM72409273', '879c8d5d-2bab-4157-a2bd-52d44dde4a02', '602475450900', None, None, None, None, '', '111,222', '2025-03-07', datetime.date(2025, 3, 7), 1, 32, datetime.date(2025, 3, 7), 1, datetime.date(2025, 4, 7), 1, datetime.date(2025, 4, 6), 1, True), ('c7d8f3b2-ed18-42f3-8103-38cc9dc5ea1a', '34f76bdb-4f5b-4917-a47e-02916f7291f5', datetime.date(2025, 4, 1), 2, 1, 4906443, None, None, None, None, None, '6dOtVTDdiauQNBQEDOtlAB', 'USUM72401994', '21e96c6e-9106-424c-87a6-c976c7f21af8', '602465630909', None, None, None, None, '', None, '2025-07-08', datetime.date(2025, 7, 8), 1, 326, datetime.date(2025, 5, 17), 8, datetime.date(2025, 4, 7), 2, datetime.date(2025, 4, 6), 3, False) ] response = fixture_client.post(route, json={"chart_ids_with_date": input}) data = response.get_json() assert data == expected_data def test_get_chart_rankings_for_chart_ids_no_filter(self, fixture_client): route = '/charts/rankings-for-chart-ids/' mock_return_value = [ { "data": { 'chartId': 'f4427653-e046-4cd1-813a-bf61806ccf77', 'chartDate': datetime.date(2024, 1, 1), 'uuids': ['75f276b0-21a9-4eeb-a771-0c7604ab5d2a', '2361242f-5436-431f-8c0e-15a8a8e0c9a5'] } }, { "data": None, }, ] with patch.object(handlers, 'get_chart_date_epochs') as mock_get_chart_date_epochs,\ patch.object(handlers, 'get_chart_date_placements_epochs') as mock_get_chart_date_placements_epochs_load_many,\ patch.object(handlers, 'get_ff_charts_cache', return_value=True),\ patch.object(placements_dataloader.chart_placements_for_chart_date_dataloader, 'load_many') as mock_chart_placements_for_chart_date_dataloader_load_many: input = [ { "chart_id": "f4427653-e046-4cd1-813a-bf61806ccf77", "chart_date": "2024-01-01", } ] mock_get_chart_date_epochs.return_value = [ { "chart_id": uuid.UUID("f4427653-e046-4cd1-813a-bf61806ccf77"), "chart_date": datetime.date(2024, 1, 1), "epoch": 0, } ] mock_get_chart_date_placements_epochs_load_many.return_value = [ { "chart_id": uuid.UUID("f4427653-e046-4cd1-813a-bf61806ccf77"), "chart_date": datetime.date(2024, 1, 1), "epoch": 0, } ] mock_chart_placements_for_chart_date_dataloader_load_many.return_value = mock_return_value response = fixture_client.post(route, json={"chart_ids_with_date": input}) data = response.get_json() assert data == [ { "data": { 'chartId': 'f4427653-e046-4cd1-813a-bf61806ccf77', 'chartDate': '2024-01-01', 'uuids': ['75f276b0-21a9-4eeb-a771-0c7604ab5d2a', '2361242f-5436-431f-8c0e-15a8a8e0c9a5'] } }, { "data": None, }, ] mock_chart_placements_for_chart_date_dataloader_load_many.assert_called_once_with( [ { "chart_id": uuid.UUID("f4427653-e046-4cd1-813a-bf61806ccf77"), "chart_date": datetime.date(2024, 1, 1), "epoch": 0, }, ], filter={}, order={ 'by': 'position', 'dir': 'ASC', }, show_sme_data=None, permissions=None, ) def test_get_chart_rankings_for_chart_ids_requesting_private_data( self, fixture_client, mock_admin_permissions, ): route = '/charts/rankings-for-chart-ids/' mock_return_value = [ { "data": { 'chartId': 'f4427653-e046-4cd1-813a-bf61806ccf77', 'chartDate': datetime.date(2024, 1, 1), 'uuids': ['75f276b0-21a9-4eeb-a771-0c7604ab5d2a', '2361242f-5436-431f-8c0e-15a8a8e0c9a5'] } }, { "data": None, }, ] with patch.object(handlers, 'get_chart_date_epochs') as mock_get_chart_date_epochs,\ patch.object(handlers, 'get_show_sme_data_flag') as mock_get_show_sme_data_flag,\ patch.object(handlers, 'get_request_permissions') as mock_get_request_permissions,\ patch.object(handlers, 'get_ff_charts_cache', return_value=True),\ patch.object(placements_dataloader.chart_placements_for_chart_date_dataloader, 'load_many') as mock_chart_placements_for_chart_date_dataloader_load_many: mock_get_chart_date_epochs.return_value = [ { 'chart_id': uuid.UUID('f4427653-e046-4cd1-813a-bf61806ccf77'), 'chart_date': datetime.date(2024, 1, 1), 'epoch': 0, }, ] mock_get_show_sme_data_flag.return_value = False mock_get_request_permissions.return_value = mock_admin_permissions mock_chart_placements_for_chart_date_dataloader_load_many.return_value = mock_return_value response = fixture_client.post( route, json={ "chart_ids_with_date": [ { "chart_id": "f4427653-e046-4cd1-813a-bf61806ccf77", "chart_date": "2024-01-01", }, ], "filter": { "is_part_of_catalog": True, } }, ) data = response.get_json() assert data == [ { "data": { 'chartId': 'f4427653-e046-4cd1-813a-bf61806ccf77', 'chartDate': '2024-01-01', 'uuids': ['75f276b0-21a9-4eeb-a771-0c7604ab5d2a', '2361242f-5436-431f-8c0e-15a8a8e0c9a5'] } }, { "data": None, }, ] mock_chart_placements_for_chart_date_dataloader_load_many.assert_called_once_with( [ { "chart_id": uuid.UUID("f4427653-e046-4cd1-813a-bf61806ccf77"), "chart_date": datetime.date(2024, 1, 1), "epoch": 0, }, ], filter={ 'is_part_of_catalog': True, }, order={ 'by': 'position', 'dir': 'ASC', }, show_sme_data=False, permissions=mock_admin_permissions, ) def test_get_chart_rankings_for_chart_ids_incorrect_param(self, fixture_client): route = '/charts/rankings-for-chart-ids/' response = fixture_client.post(route, json={"chart": [{"chart_id": "id", "chart_date": "2024-01-01"}]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chart': ['Unknown field.']}"} def test_get_chart_rankings_dataloaded_no_cache(self, fixture_client): route = '/chart-rankings/dataloaded/' mock_return_value = [{ "data": { "chartId": "9745468d-9dbd-40a7-af10-3a0066fd808b", "chartDate": datetime.date(2024, 4, 18), "position": 4, "positionChange": 29, "streams": None, "totalStreams": None, "totalShazams": None, "views": 13835830, "numTracks": None, "totalUnits": 13835830, "trackId": "5GSt99nxiJQ", "isrc": None, "publicSoundRecordingId": "cd8aa990-7343-4631-b003-580d01875a5c", "upc": None, "publicProductId": None, "videoId": "5GSt99nxiJQ", "channelId": "UCq-Fj5jknLsUf-MWSy4_brA", "channelName": "T-Series", "artistNames": "" }, }] with patch.object(handlers, 'get_chart_date_placements_epochs', return_value=mock_return_value),\ patch.object(handlers, 'get_ff_charts_cache', return_value=False),\ patch.object(public_dataloader, '_chart_placement_dataloader', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_rankings": [{"chart_id": "794836b7-1569-48a2-8a50-e789008a657b", "chart_date": "2024-01-01", "uuid": "5edf9092-70b5-4718-a5df-c60de2a740ad"}]}) data = response.get_json() assert data == [{ "data": { "chartId": "9745468d-9dbd-40a7-af10-3a0066fd808b", "chartDate": "2024-04-18", "position": 4, "positionChange": 29, "streams": None, "totalStreams": None, "totalShazams": None, "views": 13835830, "numTracks": None, "totalUnits": 13835830, "trackId": "5GSt99nxiJQ", "isrc": None, "publicSoundRecordingId": "cd8aa990-7343-4631-b003-580d01875a5c", "upc": None, "publicProductId": None, "videoId": "5GSt99nxiJQ", "channelId": "UCq-Fj5jknLsUf-MWSy4_brA", "channelName": "T-Series", "artistNames": "" }, }] def test_get_chart_rankings_dataloaded(self, fixture_client): route = '/chart-rankings/dataloaded/' mock_return_value = [{ "data": { "chartId": "9745468d-9dbd-40a7-af10-3a0066fd808b", "chartDate": datetime.date(2024, 4, 18), "position": 4, "positionChange": 29, "streams": None, "totalStreams": None, "totalShazams": None, "views": 13835830, "numTracks": None, "totalUnits": 13835830, "trackId": "5GSt99nxiJQ", "isrc": None, "publicSoundRecordingId": "cd8aa990-7343-4631-b003-580d01875a5c", "upc": None, "publicProductId": None, "videoId": "5GSt99nxiJQ", "channelId": "UCq-Fj5jknLsUf-MWSy4_brA", "channelName": "T-Series", "artistNames": "" }, }] with patch.object(handlers, 'get_chart_date_placements_epochs', return_value=mock_return_value),\ patch.object(handlers, 'get_ff_charts_cache', return_value=True),\ patch.object(public_dataloader.chart_placement_public_data_dataloader, 'load_many', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_rankings": [{"chart_id": "794836b7-1569-48a2-8a50-e789008a657b", "chart_date": "2024-01-01", "uuid": "5edf9092-70b5-4718-a5df-c60de2a740ad"}]}) data = response.get_json() assert data == [{ "data": { "chartId": "9745468d-9dbd-40a7-af10-3a0066fd808b", "chartDate": "2024-04-18", "position": 4, "positionChange": 29, "streams": None, "totalStreams": None, "totalShazams": None, "views": 13835830, "numTracks": None, "totalUnits": 13835830, "trackId": "5GSt99nxiJQ", "isrc": None, "publicSoundRecordingId": "cd8aa990-7343-4631-b003-580d01875a5c", "upc": None, "publicProductId": None, "videoId": "5GSt99nxiJQ", "channelId": "UCq-Fj5jknLsUf-MWSy4_brA", "channelName": "T-Series", "artistNames": "" }, }] def test_get_chart_rankings_dataloaded_incorrect_param(self, fixture_client): route = '/chart-rankings/dataloaded/' with patch.object(public_dataloader.chart_placement_public_data_dataloader, 'load_many'): response = fixture_client.post(route, json={"chart": [{"chart_id": "id", "chart_date": "2024-01-01", "position": 3}]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chart': ['Unknown field.']}"} def test_get_chart_rankings_aggregated_values_dataloaded_no_cache(self, fixture_client): route = '/chart-rankings/aggregated-values-dataloaded/' mock_return_value = [{ "data": { "chartId": "9745468d-9dbd-40a7-af10-3a0066fd808b", "publicSoundRecordingId": "3d196a54-3125-4789-8bca-66bffdc40335", "trackId": None, "publicProductId": None, "peakTimestamp": "2024-01-01", "peakDate": datetime.date(2024, 1, 1), "peakPosition": 1, "appearances": 280, "isrc": "isrc", "firstDate": datetime.date(2022, 1, 1), "firstPosition": 2, "mostRecentDate": datetime.date(2024, 3, 1), "mostRecentPosition": 5, "previousDate": datetime.date(2023, 1, 1), "previousPosition": 3 } }] with patch.object(handlers, 'get_ff_charts_cache', return_value=False),\ patch.object(aggregated_values_dataloader, '_get_chart_rankings_aggregated_values_dataloaded', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_rankings_aggregated": [ {"chart_id": "9745468d-9dbd-40a7-af10-3a0066fd808b", "public_sound_recording_id": '3d196a54-3125-4789-8bca-66bffdc40335', "chartmetric_track_id": None, "public_product_id": None}]}) data = response.get_json() assert data == [{ "data" : { "chartId": "9745468d-9dbd-40a7-af10-3a0066fd808b", "publicSoundRecordingId": '3d196a54-3125-4789-8bca-66bffdc40335', "trackId": None, "publicProductId": None, "peakTimestamp": "2024-01-01", "peakDate": "2024-01-01", "peakPosition": 1, "appearances": 280, "isrc": "isrc", "firstDate": "2022-01-01", "firstPosition": 2, "mostRecentDate": "2024-03-01", "mostRecentPosition": 5, "previousDate": "2023-01-01", "previousPosition": 3 } }] def test_get_chart_rankings_aggregated_values_dataloaded(self, fixture_client): route = '/chart-rankings/aggregated-values-dataloaded/' mock_return_value = [{ "data": { "chartId": "9745468d-9dbd-40a7-af10-3a0066fd808b", "publicSoundRecordingId": "3d196a54-3125-4789-8bca-66bffdc40335", "trackId": None, "publicProductId": None, "peakTimestamp": "2024-01-01", "peakDate": datetime.date(2024, 1, 1), "peakPosition": 1, "appearances": 280, "isrc": "isrc", "firstDate": datetime.date(2022, 1, 1), "firstPosition": 2, "mostRecentDate": datetime.date(2024, 3, 1), "mostRecentPosition": 5, "previousDate": datetime.date(2023, 1, 1), "previousPosition": 3 } }] with patch.object(handlers, 'get_ff_charts_cache', return_value=True),\ patch.object(aggregated_values_dataloader, '_get_chart_rankings_aggregated_values_dataloaded', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_rankings_aggregated": [ {"chart_id": "9745468d-9dbd-40a7-af10-3a0066fd808b", "public_sound_recording_id": '3d196a54-3125-4789-8bca-66bffdc40335', "chartmetric_track_id": None, "public_product_id": None}]}) data = response.get_json() assert data == [{ "data" : { "chartId": "9745468d-9dbd-40a7-af10-3a0066fd808b", "publicSoundRecordingId": '3d196a54-3125-4789-8bca-66bffdc40335', "trackId": None, "publicProductId": None, "peakTimestamp": "2024-01-01", "peakDate": "2024-01-01", "peakPosition": 1, "appearances": 280, "isrc": "isrc", "firstDate": "2022-01-01", "firstPosition": 2, "mostRecentDate": "2024-03-01", "mostRecentPosition": 5, "previousDate": "2023-01-01", "previousPosition": 3 } }] def test_get_chart_rankings_aggregated_values_dataloaded_incorrect_param(self, fixture_client): route = '/chart-rankings/aggregated-values-dataloaded/' with patch.object(aggregated_values_dataloader.aggregated_values_dataloader, 'load_many'): response = fixture_client.post(route, json={"chart": [{"chart_id": "id", "public_sound_recording_id": None, "chartmetric_track_id": "id", "public_product_id": '1234'}]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chart': ['Unknown field.']}"} def test_get_chart_rankings_aggregated_values_on_date_dataloaded(self, fixture_client): route = '/chart-rankings/aggregated-values-on-date-dataloaded/' mock_return_value = [{ "data": { "id": "9745468d-9dbd-40a7-af10-3a0066fd808b", "chartDate": datetime.date(2022, 7, 1), "uuid": "3d196a54-3125-4789-8bca-66bffdc40335", } }] with patch.object(charts, 'get_chart_rankings_aggregated_values_on_date_dataloaded', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_rankings_aggregated_on_date": [ {"chart_id": "9745468d-9dbd-40a7-af10-3a0066fd808b", "chart_date": "2022-07-01", "public_sound_recording_id": '3d196a54-3125-4789-8bca-66bffdc40335', "chartmetric_track_id": None, "public_product_id": None}]}) data = response.get_json() assert data == [{ "data" : { "id": "9745468d-9dbd-40a7-af10-3a0066fd808b", "chartDate": "2022-07-01", "uuid": '3d196a54-3125-4789-8bca-66bffdc40335', } }] def test_get_chart_rankings_aggregated_values_on_date_dataloaded_incorrect_param(self, fixture_client): route = '/chart-rankings/aggregated-values-on-date-dataloaded/' with patch.object(charts, 'get_chart_rankings_aggregated_values_on_date_dataloaded'): response = fixture_client.post(route, json={"chart": [{"chart_id": "id", "public_sound_recording_id": None, "chartmetric_track_id": "id", "public_product_id": '1234'}]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chart': ['Unknown field.']}"} def test_chart_placement_private_dataloader(self, fixture_client): route = '/charts/placement-dataloader-private' permissions = { 'vendor_ids': ['*'], 'subaccount_ids': ['*'], 'label_participant_ids': ['*'], 'artist_id': ['*'] } mock_return_value = [ { 'data': { 'brand_ids': ['bad75dc4-8df3-45a5-baa5-ddb40dea3242', '151a4684-fb9b-4ae9-b938-6da0f2ea1f10'] } }, ] with patch.object(handlers, 'get_show_sme_data_flag') as mock_get_show_sme_data_flag,\ patch.object(handlers, 'get_request_permissions') as mock_get_request_permissions,\ patch.object(handlers, 'get_chart_date_placements_epochs') as mock_get_chart_date_placements_epochs,\ patch.object(chart_placement_private_data_dataloader, 'load_many') as mock_dataloader_private_load_many: mock_get_show_sme_data_flag.return_value = True mock_get_request_permissions.return_value = permissions mock_dataloader_private_load_many.return_value = mock_return_value input = [ { "chart_id": "5ba94e77-f855-401f-97e9-05e423622d70", "chart_date": "2020-01-01", "uuid": "940e00c2-e593-4001-b19b-505398e08bc2" }, ] mock_get_chart_date_placements_epochs.return_value = [ { "chart_id": uuid.UUID("5ba94e77-f855-401f-97e9-05e423622d70"), "chart_date": datetime.date(2020, 1, 1), "epoch": 0, "uuid": uuid.UUID("940e00c2-e593-4001-b19b-505398e08bc2"), }, ] response = fixture_client.post( route, json=input, ) data = response.get_json() assert data == [ { 'data': { 'brand_ids': ['bad75dc4-8df3-45a5-baa5-ddb40dea3242', '151a4684-fb9b-4ae9-b938-6da0f2ea1f10'] } }, ] mock_dataloader_private_load_many.assert_called_once_with( [ { "chart_id": uuid.UUID("5ba94e77-f855-401f-97e9-05e423622d70"), "chart_date": datetime.date(2020, 1, 1), "epoch": 0, "uuid": uuid.UUID("940e00c2-e593-4001-b19b-505398e08bc2"), }, ], show_sme_data=True, permissions=permissions, ) def test_chart_placement_private_dataloader_for_incorrect_param(self, fixture_client): route = '/charts/placement-dataloader-private' with patch.object(handlers, 'get_chart_date_epochs'),\ patch.object(chart_placement_private_data_dataloader, 'load_many'): response = fixture_client.post(route, json=[{"chart_id": "8d04c65d-ec5d-4b47-a0c4-77c428d0cfab", "chart_date": "2020-01-01"}]) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{0: {'uuid': ['Missing data for required field.']}}"} def test_get_chart_dates_for_chart_ids_incorrect_param(self, fixture_client): route = '/charts/dates-for-chart-ids/' with patch.object(chart_dates_dataloader, 'load_many'): response = fixture_client.post(route, json={"chartIds": [{"chart_id": "id"}]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chartIds': ['Unknown field.']}"} def test_get_chart_dates_for_chart_ids(self, fixture_client): route = '/charts/dates-for-chart-ids/' mock_return_value = [{ "data": { "chartId": "7085531c-a98f-45a2-927c-62ff369d3532", "chartDates": [datetime.date.fromisoformat("2024-01-01"), datetime.date.fromisoformat("2024-01-02")] } }] with patch.object(chart_dates_dataloader, 'load_many', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_ids": [{"chart_id": "7085531c-a98f-45a2-927c-62ff369d3532"}]}) data = response.get_json() assert data == [{ "data" : { "chartId": "7085531c-a98f-45a2-927c-62ff369d3532", "chartDates": ["2024-01-01", "2024-01-02"] } }] def test_get_metadata_for_chart_ids_incorrect_param(self, fixture_client): route = '/charts/metadata/' with patch.object(handlers, 'get_ff_charts_cache', return_value=True),\ patch.object(metadata_dataloader.chart_metadata_dataloader, 'load_many'): response = fixture_client.post(route, json={"chartIds": [{"chart_id": "id"}]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chartIds': ['Unknown field.']}"} def test_get_metadata_for_chart_ids_no_cache(self, fixture_client): route = '/charts/metadata/' mock_return_value = [{ "data": { "chartId": "id", "name": "Apple Music Daily Top 100", "platform": "appleMusic", "target": "track", "country": "MT", "type": "default", "frequency": "daily", "genre": "All Genres", "lastAvailableTimestamp": "2024-05-15", "createdAt": "2021-02-15 11:35:40", "modifiedAt": "2024-05-16 05:49:52" } }] with patch.object(handlers, 'get_ff_charts_cache', return_value=False),\ patch.object(metadata_dataloader, '_get_chart_metadata_for_chart_ids', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_ids": [{"chart_id": "07c8a0dc-032a-4626-8973-847d2b760288"}]}) data = response.get_json() assert data == [{ "data" : { "chartId": "id", "name": "Apple Music Daily Top 100", "platform": "appleMusic", "target": "track", "country": "MT", "type": "default", "frequency": "daily", "genre": "All Genres", "lastAvailableTimestamp": "2024-05-15", "createdAt": "2021-02-15 11:35:40", "modifiedAt": "2024-05-16 05:49:52" } }] def test_get_metadata_for_chart_ids_with_cache(self, fixture_client): route = '/charts/metadata/' mock_return_value = [{ "data": { "chartId": "id", "name": "Apple Music Daily Top 100", "platform": "appleMusic", "target": "track", "country": "MT", "type": "default", "frequency": "daily", "genre": "All Genres", "lastAvailableTimestamp": "2024-05-15", "createdAt": "2021-02-15 11:35:40", "modifiedAt": "2024-05-16 05:49:52" } }] with patch.object(handlers, 'get_ff_charts_cache', return_value=True),\ patch.object(metadata_dataloader.chart_metadata_dataloader, 'load_many', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_ids": [{"chart_id": "07c8a0dc-032a-4626-8973-847d2b760288"}]}) data = response.get_json() assert data == [{ "data" : { "chartId": "id", "name": "Apple Music Daily Top 100", "platform": "appleMusic", "target": "track", "country": "MT", "type": "default", "frequency": "daily", "genre": "All Genres", "lastAvailableTimestamp": "2024-05-15", "createdAt": "2021-02-15 11:35:40", "modifiedAt": "2024-05-16 05:49:52" } }] def get_global_sound_recordings_for_charts_date_incorrect_param(self, fixture_client): route = '/charts/gsrs-for-charts-date/' with patch.object(charts, 'get_global_sound_recordings_for_charts_date'): response = fixture_client.post(route, json={"chartIds": ["chart_id"]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chartIds': ['Unknown field.']}"} def test_get_global_sound_recordings_for_charts_date(self, fixture_client): route = '/charts/gsrs-for-charts-date/' mock_return_value = { "globalSoundRecordingIsrcs": [ "isrc1", "isrc2", "isrc3" ] } with patch.object(charts, 'get_global_sound_recordings_for_charts_date', return_value=mock_return_value): body = { "chart_ids": ["07c8a0dc-032a-4626-8973-847d2b760288"], "date": "2024-12-11" } response = fixture_client.post(route, json=body) data = response.get_json() assert data == { "globalSoundRecordingIsrcs" : [ "isrc1", "isrc2", "isrc3" ] } def test_get_chart_date_entry_for_isrcs_incorrect_param(self, fixture_client): route = '/charts/chart-date-entry/' with patch.object(chart_date_entry_dataloader, 'load_many'): response = fixture_client.post(route, json={"chart_entries": [{"chart_id": "id", "date": "2024-12-12"}]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chart_entries': {0: {'chart_id': ['Not a valid UUID.'], 'chart_date': ['Missing data for required field.'], 'isrc': ['Missing data for required field.'], 'date': ['Unknown field.']}}}"} def test_get_chart_date_entry_for_isrcs(self, fixture_client): route = '/charts/chart-date-entry/' mock_return_value = [ { "data": { "position": 1 } }, { "data": None }, { "data": { "position": None } }, ] with patch.object(chart_date_entry_dataloader, 'load_many', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_entries": [{"chart_id": "07c8a0dc-032a-4626-8973-847d2b760288", "chart_date": "2024-12-12", "isrc": "isrc1"}]}) data = response.get_json() assert data == [ { "data" : { "position": 1 }, }, { "data" : None, }, { "data" : None, }, ] def test_get_chart_date_entry_summary_for_isrcs_incorrect_param(self, fixture_client): route = '/charts/chart-date-entry-summary/' with patch.object(chart_date_entry_summary_dataloader, 'load_many'): response = fixture_client.post(route, json={"chart_entries": [{"isrc": "isrc", "date": "2024-12-12"}], "chart_ids": ["chartId"]}) data = response.get_json() assert data == {'code': 'internal_error', 'message': "{'chart_ids': {0: ['Not a valid UUID.']}, 'chart_entries': {0: {'chart_date': ['Missing data for required field.'], 'date': ['Unknown field.']}}}"} def test_get_chart_date_entry_summary_for_isrcs(self, fixture_client): route = '/charts/chart-date-entry-summary/' mock_return_value = [ { "data": { "feature": 10, "average_position": 6, "top_10_rank": 5, } }, { "data": None }, { "data": { "feature": 0, "average_position": None, "top_10_rank": 0, } }, ] with patch.object(chart_date_entry_summary_dataloader, 'load_many', return_value=mock_return_value): response = fixture_client.post(route, json={"chart_entries": [{"chart_date": "2024-12-12", "isrc": "isrc1"}], "chart_ids": ["07c8a0dc-032a-4626-8973-847d2b760288"]}) data = response.get_json() assert data == [ { "data" : { "feature": 10, "average_position": 6, "top_10_rank": 5, }, }, { "data" : None, }, { "data": { "feature": 0, "average_position": None, "top_10_rank": 0, } }, ] class TestChartDigest: # new version of test_get_chart_rankings. @pytest.mark.parametrize( 'params,status,mocked_response,expected_response', [ [{}, 500, [], None], [{"definition_key": "spotify_viral_daily", "chart_id": "123"}, 500, [], None], [{"definition_key": "spotify_viral_daily"}, 200, ([], []), []], ] ) def test_chart_digest_tracks(self, params, status, mocked_response, client, expected_response): with patch.object(digest, "get_chart_digest_tracks_with_entries", return_value=mocked_response): response = client.get(url_for("get_chart_digest_tracks", **params)) resp_status_code = response.status_code assert resp_status_code == status if resp_status_code == 200: resp_json = response.get_json() assert resp_json == expected_response @pytest.mark.parametrize( "params,status,expected_response", [ [ {"definition_key": "spotify_viral_weekly", "filter": "EXIT"}, 500, [] ], [ { "definition_key": "spotify_viral_weekly" }, 200, [ { "artistNames": "", "channelId": None, "channelName": None, "chartDate": "2024-04-03", "daysOnChart": 15, "isrc": "QZJ842400387", "newlyEntered": True, "numTracks": None, "peakPosition": 1, "peakTimestamp": "2024-04-02", "position": 1, "positionChange": 0, "publicProductId": None, "publicSoundRecordingId": "4636e2f8-04f8-4d6d-a92d-5de50f490c80", "streams": 8352353, "totalShazams": None, "totalStreams": None, "totalUnits": None, "trackId": "2GxrNKugF82CnoRFbQfzPf", "trend": None, "upc": "810129998306", "videoId": None, "views": None }, { "artistNames": "", "channelId": None, "channelName": None, "chartDate": "2024-04-03", "daysOnChart": 76, "isrc": "USWB12307016", "newlyEntered": False, "numTracks": None, "peakPosition": 1, "peakTimestamp": "2024-02-05", "position": 2, "positionChange": -20, "publicProductId": None, "publicSoundRecordingId": "edf7f20d-14e8-4af4-b175-1f0102480f5e", "streams": 8022981, "totalShazams": None, "totalStreams": None, "totalUnits": None, "trackId": "6tNQ70jh4OwmPGpYy6R2o9", "trend": -20, "upc": "054391342751", "videoId": None, "views": None }, { "artistNames": "", "channelId": None, "channelName": None, "chartDate": "2024-04-03", "daysOnChart": 47, "isrc": "GBKPL2205058", "newlyEntered": False, "numTracks": None, "peakPosition": 1, "peakTimestamp": "2024-03-24", "position": 3, "positionChange": 10, "publicProductId": None, "publicSoundRecordingId": "1b403bbe-8b7c-471e-a9d5-0e9cfc227360", "streams": 7403315, "totalShazams": None, "totalStreams": None, "totalUnits": None, "trackId": "3qhlB30KknSejmIvZZLjOD", "trend": 10, "upc": "5056494917336", "videoId": None, "views": None } ] ], [ { "definition_key": "spotify_viral_weekly", "filter": "ENTRY" }, 200, [ { "artistNames": "", "channelId": None, "channelName": None, "chartDate": "2024-04-03", "daysOnChart": 15, "isrc": "QZJ842400387", "newlyEntered": True, "numTracks": None, "peakPosition": 1, "peakTimestamp": "2024-04-02", "position": 1, "positionChange": 0, "publicProductId": None, "publicSoundRecordingId": "4636e2f8-04f8-4d6d-a92d-5de50f490c80", "streams": 8352353, "totalShazams": None, "totalStreams": None, "totalUnits": None, "trackId": "2GxrNKugF82CnoRFbQfzPf", "trend": None, "upc": "810129998306", "videoId": None, "views": None }, ] ], [ { "definition_key": "spotify_viral_weekly", "filter": "MAJOR_MOVE" }, 200, [ { "artistNames": "", "channelId": None, "channelName": None, "chartDate": "2024-04-03", "daysOnChart": 47, "isrc": "GBKPL2205058", "newlyEntered": False, "numTracks": None, "peakPosition": 1, "peakTimestamp": "2024-03-24", "position": 3, "positionChange": 10, "publicProductId": None, "publicSoundRecordingId": "1b403bbe-8b7c-471e-a9d5-0e9cfc227360", "streams": 7403315, "totalShazams": None, "totalStreams": None, "totalUnits": None, "trackId": "3qhlB30KknSejmIvZZLjOD", "trend": 10, "upc": "5056494917336", "videoId": None, "views": None }, { "artistNames": "", "channelId": None, "channelName": None, "chartDate": "2024-04-03", "daysOnChart": 76, "isrc": "USWB12307016", "newlyEntered": False, "numTracks": None, "peakPosition": 1, "peakTimestamp": "2024-02-05", "position": 2, "positionChange": -20, "publicProductId": None, "publicSoundRecordingId": "edf7f20d-14e8-4af4-b175-1f0102480f5e", "streams": 8022981, "totalShazams": None, "totalStreams": None, "totalUnits": None, "trackId": "6tNQ70jh4OwmPGpYy6R2o9", "trend": -20, "upc": "054391342751", "videoId": None, "views": None } ] ], ] ) def test_chart_digest_tracks_entries_and_major_moves(self, params, status, client, expected_response): mocked_response = [ { "position": 1, "positionChange": 0, "streams": 8352353, "totalStreams": None, "totalShazams": None, "views": None, "numTracks": None, "totalUnits": None, "trackId": "2GxrNKugF82CnoRFbQfzPf", "isrc": "QZJ842400387", "publicSoundRecordingId": "4636e2f8-04f8-4d6d-a92d-5de50f490c80", "upc": "810129998306", "publicProductId": None, "videoId": None, "channelId": None, "channelName": None, "chartDate": "2024-04-03", "peakTimestamp": "2024-04-02", "peakPosition": 1, "daysOnChart": 15, "artistNames": "" }, { "position": 2, "positionChange": -20, "streams": 8022981, "totalStreams": None, "totalShazams": None, "views": None, "numTracks": None, "totalUnits": None, "trackId": "6tNQ70jh4OwmPGpYy6R2o9", "isrc": "USWB12307016", "publicSoundRecordingId": "edf7f20d-14e8-4af4-b175-1f0102480f5e", "upc": "054391342751", "publicProductId": None, "videoId": None, "channelId": None, "channelName": None, "chartDate": "2024-04-03", "peakTimestamp": "2024-02-05", "peakPosition": 1, "daysOnChart": 76, "artistNames": "" }, { "position": 3, "positionChange": 10, "streams": 7403315, "totalStreams": None, "totalShazams": None, "views": None, "numTracks": None, "totalUnits": None, "trackId": "3qhlB30KknSejmIvZZLjOD", "isrc": "GBKPL2205058", "publicSoundRecordingId": "1b403bbe-8b7c-471e-a9d5-0e9cfc227360", "upc": "5056494917336", "publicProductId": None, "videoId": None, "channelId": None, "channelName": None, "chartDate": "2024-04-03", "peakTimestamp": "2024-03-24", "peakPosition": 1, "daysOnChart": 47, "artistNames": "" }, ], ["QZJ842400387"] with patch.object(digest, "get_chart_digest_tracks_with_entries", return_value=mocked_response): response = client.get(url_for("get_chart_digest_tracks", **params)) resp_status_code = response.status_code assert resp_status_code == status if resp_status_code == 200: resp_json = response.get_json() assert resp_json == expected_response class TestChartPrime: def test_missing_field(self, client): response = client.post(url_for("prime_charts_cache"), json={}) assert response.status_code == 500 def test_chart_prime(self, client): body_json = { 'chart_dates': [ { 'chart_id': 'df99e3f8-a62e-4acc-81dd-3028331c43f0', 'chart_date': '2024-01-01', } ] } mocked_response = { 'ok': True, } with patch.object(cache_prime, "prime_charts_cache", return_value=mocked_response): response = client.post(url_for("prime_charts_cache"), json=body_json) resp_status_code = response.status_code assert resp_status_code == 200 resp_json = response.get_json() assert resp_json == { 'ok': True } class TestChartGroups: def test_post_chart_groups_chart_ids_dataloader_bad_input(self, client): response = client.post(url_for('post_chart_groups_chart_ids_dataloader'), json={}) assert response.status_code == 500 def test_post_chart_groups_chart_ids_dataloader(self, client): body_json = { 'slugs': ['chart-slug-1', 'chart-slug-2'] } mocked_features = [ 'insights_chart_youtube_daily', ] mocked_response = [ { 'data': { 'slug': 'chart-slug-1', 'chart_ids': ['9745468d-9dbd-40a7-af10-3a0066fd808b', 'de95bb84-4616-4b4f-b0e5-bd5e20488232'], 'default_chart_id': 'de95bb84-4616-4b4f-b0e5-bd5e20488232', }, }, { 'data': None, }, ] with patch.object(handlers, 'get_controlled_chart_feature_flags', return_value=mocked_features), \ patch.object(chart_ids_dataloader.chart_groups_chart_ids_dataloader, 'load_many', return_value=mocked_response) as mock_dataloader: response = client.post(url_for('post_chart_groups_chart_ids_dataloader'), json=body_json) assert response.status_code == 200 resp_json = response.get_json() assert resp_json == [ { 'data': { 'slug': 'chart-slug-1', 'chart_ids': ['9745468d-9dbd-40a7-af10-3a0066fd808b', 'de95bb84-4616-4b4f-b0e5-bd5e20488232'], 'default_chart_id': 'de95bb84-4616-4b4f-b0e5-bd5e20488232', } }, { 'data': None, } ] mock_dataloader.assert_called_once_with( ['chart-slug-1', 'chart-slug-2'], controlled_charts_ffs=mocked_features, )