"""Unit tests for the top sound recordings logic layer.""" from decimal import Decimal from unittest.mock import patch import pytest from analytics.api import app from analytics.logic import top_sound_recordings @pytest.fixture(autouse=True) def mock_request_context(): """Run in Flask request context.""" with app.test_request_context(): yield @pytest.fixture(autouse=True) def no_cache(): """Bypass redis cache lookups.""" with patch("analytics.connectors.redis.client.get") as get: get.return_value = None yield get @pytest.fixture(autouse=True) def mock_store_ids(mocker): mocker.patch( "analytics.logic.top_sound_recordings.store_availability.get_store_ids", return_value=[1, 286], ) @pytest.fixture def permissions(): return { "permission_label_ids": [7123], "permission_artist_ids": None, "permission_subaccount_ids": None, "permission_label_participant_ids": None, "permission_feed_ids": [1, 2], } @pytest.fixture def query_params(): return { "country_ids": [], "distributors": ["theorchard", "sme", "awal"], "order_by": "streams_7_days", "limit": 10, "offset": 0, } @pytest.fixture def query_rows(): return [ { "isrc": "USA561066580", "streams": 500000, "growth_percentage": Decimal("16"), }, { "isrc": "USJMZ1800003", "streams": 400000, "growth_percentage": Decimal("16.25"), }, ] @pytest.fixture def expected_items(): return [ {"isrc": "USA561066580", "streams": 500000, "growth_percentage": 16}, {"isrc": "USJMZ1800003", "streams": 400000, "growth_percentage": 16.25}, ] class TestGetTopSoundRecordings: def test_succeeds( self, mocker, permissions, query_params, query_rows, expected_items ): mocker.patch( "analytics.logic.top_sound_recordings.TopSoundRecordings.execute", return_value=query_rows, ) response = top_sound_recordings.get_top_sound_recordings( query_params, permissions ) assert response.status == 200 assert response.message == {"items": expected_items} def test_country_ids_passed_through( self, mocker, permissions, query_params, query_rows ): MockQuery = mocker.patch( "analytics.logic.top_sound_recordings.TopSoundRecordings" ) MockQuery.return_value.execute.return_value = query_rows params = {**query_params, "country_ids": ["US", "GB"]} top_sound_recordings.get_top_sound_recordings(params, permissions) query_input = MockQuery.call_args[0][0] assert query_input["country_ids"] == ["US", "GB"] def test_all_time_toggle_passed( self, mocker, permissions, query_params, query_rows ): MockQuery = mocker.patch( "analytics.logic.top_sound_recordings.TopSoundRecordings" ) MockQuery.return_value.execute.return_value = query_rows params = {**query_params, "order_by": "streams_all_time"} top_sound_recordings.get_top_sound_recordings(params, permissions) query_input = MockQuery.call_args[0][0] assert query_input["all_time"] is True assert query_input["order_by"] == "streams_all_time" def test_rollup_grain_threaded(self, mocker, permissions, query_params, query_rows): MockQuery = mocker.patch( "analytics.logic.top_sound_recordings.TopSoundRecordings" ) MockQuery.return_value.execute.return_value = query_rows top_sound_recordings.get_top_sound_recordings(query_params, permissions) query_input = MockQuery.call_args[0][0] assert query_input["rollup_grain"] is True def test_invalid_order_by_raises(self, permissions, query_params): params = {**query_params, "order_by": "bogus"} with pytest.raises(Exception): top_sound_recordings.get_top_sound_recordings(params, permissions) def test_empty_query_returns_empty_items(self, mocker, permissions, query_params): mocker.patch( "analytics.logic.top_sound_recordings.TopSoundRecordings.execute", return_value=[], ) response = top_sound_recordings.get_top_sound_recordings( query_params, permissions ) assert response.status == 200 assert response.message == {"items": []}