"""Unit tests for sound-recording streams_by_product model layer.""" import datetime from unittest.mock import patch import pytest from sound_recordings.models import streams_by_product as streams_by_product from tests.unit.models.conftest import snowflake_fetch_assert # This mock SQL is to test that filtering is correct MOCK_SQL = "{filter_clause}" @pytest.fixture def mock_load_query(): """Mock load query.""" with patch("sound_recordings.models.streams_by_product.SQLLoader") as sql_loader: load_query = sql_loader.load_query load_query.return_value = MOCK_SQL yield load_query @pytest.fixture def mock_store_availability(): """Mock store_availability.""" with patch( "sound_recordings.models.streams_by_product.store_availability" ) as store_availability: store_availability.get_store_ids.return_value = [1, 286] yield store_availability @pytest.fixture def db_result(): """Mock db result.""" return [ ("123", datetime.date(2018, 7, 4), 40000, 1000, 300, 600), ("321", datetime.date(2018, 7, 4), 2000, 1000, 400, 800), ("456", datetime.date(2018, 7, 5), 126, 0, None, None), ("123", datetime.date(2018, 7, 6), 3126, 0, None, None), ("321", datetime.date(2018, 7, 5), 1126, 800, 400, 100), ] @pytest.fixture def expected_response(): """Expect formatted response.""" return [ { "product_id": "123", "date": datetime.date(2018, 7, 4), "streams": 40000, "streams_with_skips": 1000, "skips": 300, "saves": 600, }, { "product_id": "321", "date": datetime.date(2018, 7, 4), "streams": 2000, "streams_with_skips": 1000, "skips": 400, "saves": 800, }, { "product_id": "456", "date": datetime.date(2018, 7, 5), "streams": 126, "streams_with_skips": 0, "skips": None, "saves": None, }, { "product_id": "123", "date": datetime.date(2018, 7, 6), "streams": 3126, "streams_with_skips": 0, "skips": None, "saves": None, }, { "product_id": "321", "date": datetime.date(2018, 7, 5), "streams": 1126, "streams_with_skips": 800, "skips": 400, "saves": 100, }, ] class TestGetStreamsByProductWithLabel: """Test get_streams_by_product with Label.""" permissions_filter = { "label_ids": [7123], "artist_ids": None, "subaccount_ids": None, "feed_ids": [1, 2], } args = { "isrc": "isrc", "start_date": "2018-07-04", "end_date": "2018-07-06", "distributors": ["theorchard"], } expected_sql = ( "product_id IN (SELECT product_id FROM dim_release WHERE " "labelid IN (:label_ids)) " "AND (download_activity_date " "BETWEEN :start_date AND :end_date) AND feed_id " "IN (:feed_ids) " ) @pytest.fixture def mock_snowflake_fetchall(self, db_result): """Mock Snowflake fetchall.""" with patch( "sound_recordings.models.streams_by_product.snowflake.fetchall" ) as fetchall: fetchall.return_value = db_result yield fetchall @pytest.fixture(autouse=True) def no_cache(self): """Mock out caching of response.""" with patch("sound_recordings.connectors.redis.client.get") as get: get.return_value = None yield get @pytest.fixture def response( self, mock_snowflake_fetchall, mock_load_query, mock_store_availability, expected_response, ): """Return track streams.""" return streams_by_product.get_streams_by_product( self.permissions_filter, **self.args ) def test_succeeds(self, response, expected_response): """Test successful response.""" assert response == expected_response def test_query_is_loaded(self, response, mock_load_query): """Test correct query is loaded.""" mock_load_query.assert_called_once_with("streams_by_product") def test_loaded_query_is_run(self, response, mock_snowflake_fetchall): """Test loaded query is run.""" expected_args = self.args expected_args["store_ids"] = [1, 286] snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **expected_args}, ) class TestGetStreamsByProductWithSubaccountWithCountryFilter: """Test get_streams_by_product with Subaccount & country filter.""" permissions_filter = { "label_ids": None, "artist_ids": None, "subaccount_ids": [345], "feed_ids": [1, 2], } args = { "isrc": "isrc", "countries": ["US"], "start_date": "2018-07-04", "end_date": "2018-07-06", "distributors": ["theorchard"], } expected_sql = ( "product_id IN (SELECT product_id FROM dim_release WHERE " "subaccountid IN (:subaccount_ids)) " "AND (download_activity_date " "BETWEEN :start_date AND :end_date) AND feed_id " "IN (:feed_ids) " ) @pytest.fixture def mock_snowflake_fetchall(self, db_result): """Mock Snowflake fetchall.""" with patch( "sound_recordings.models.streams_by_product.snowflake.fetchall" ) as fetchall: fetchall.return_value = db_result yield fetchall @pytest.fixture(autouse=True) def no_cache(self): """Mock out caching of response.""" with patch("sound_recordings.connectors.redis.client.get") as get: get.return_value = None yield get @pytest.fixture def response( self, mock_snowflake_fetchall, mock_load_query, mock_store_availability, expected_response, ): """Return track streams.""" return streams_by_product.get_streams_by_product( self.permissions_filter, **self.args ) def test_succeeds(self, response, expected_response): """Test successful response.""" assert response == expected_response def test_query_is_loaded(self, response, mock_load_query): """Test correct query is loaded.""" mock_load_query.assert_called_once_with("streams_by_product_by_country") def test_loaded_query_is_run(self, response, mock_snowflake_fetchall): """Test loaded query is run.""" expected_args = self.args del expected_args["countries"] expected_args["country_codes"] = ["US"] expected_args["store_ids"] = [1, 286] snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **expected_args}, )