"""Unit tests for track downloads model layer.""" import datetime from unittest.mock import patch import pytest from sound_recordings.models import downloads as downloads 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.downloads.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.downloads.store_availability" ) as store_availability: store_availability.get_download_store_ids.return_value = [1, 496] yield store_availability @pytest.fixture def db_result(): """Mock db result.""" return [ (1, datetime.date(2018, 7, 5), 1), (1, datetime.date(2018, 7, 6), 2), (496, datetime.date(2018, 7, 5), 3), (496, datetime.date(2018, 7, 6), 4), ] @pytest.fixture def expected_response(): """Expect formatted response.""" return [ {"store_id": 1, "date": datetime.date(2018, 7, 5), "downloads": 1}, {"store_id": 1, "date": datetime.date(2018, 7, 6), "downloads": 2}, {"store_id": 496, "date": datetime.date(2018, 7, 5), "downloads": 3}, {"store_id": 496, "date": datetime.date(2018, 7, 6), "downloads": 4}, ] @pytest.fixture def db_result_by_country(): """Mock db result by country.""" return [ ("GB", datetime.date(2018, 7, 5), 1), ("GB", datetime.date(2018, 7, 6), 2), ("US", datetime.date(2018, 7, 5), 3), ("US", datetime.date(2018, 7, 6), 4), ] @pytest.fixture def expected_response_by_country(): """Expect formated response by country.""" return [ {"country_code": "GB", "date": datetime.date(2018, 7, 5), "downloads": 1}, {"country_code": "GB", "date": datetime.date(2018, 7, 6), "downloads": 2}, {"country_code": "US", "date": datetime.date(2018, 7, 5), "downloads": 3}, {"country_code": "US", "date": datetime.date(2018, 7, 6), "downloads": 4}, ] class TestGetDownloadsForPeriodWithLabel: """Test get_downloads_for_period with label.""" permissions_filter = { "label_ids": [7123], "artist_ids": None, "subaccount_ids": None, "feed_ids": [1, 2], } args = { "isrc": "isrc", "countries": ["DE"], "start_date": "2019-12-01", "end_date": "2019-12-01", "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.downloads.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 downloads.""" return downloads.get_downloads(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("downloads_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"] = ["DE"] expected_args["store_ids"] = [1, 496] snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **expected_args}, ) class TestGetDownloadsForPeriodWithSubaccount: """Test get_downloads_for_period with subaccount.""" permissions_filter = { "label_ids": None, "artist_ids": None, "subaccount_ids": [345], "feed_ids": [1, 2], } args = { "isrc": "isrc", "store_ids": [1, 496], "start_date": "2019-12-01", "end_date": "2019-12-01", "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.downloads.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 ): """Return track downloads.""" return downloads.get_downloads(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("downloads") def test_loaded_query_is_run(self, response, mock_snowflake_fetchall): """Test loaded query is run.""" snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **self.args, "store_ids": [1, 496]}, ) class TestGetDownloadsByCountryWithLabel: """Test get_downloads_by_country with label.""" permissions_filter = { "label_ids": [7123], "artist_ids": None, "subaccount_ids": None, "feed_ids": [1, 2], } args = { "isrc": "isrc", "countries": [], "start_date": "2019-12-01", "end_date": "2019-12-01", "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_by_country): """Mock Snowflake fetchall.""" with patch("sound_recordings.models.downloads.snowflake.fetchall") as fetchall: fetchall.return_value = db_result_by_country 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_by_country, ): """Return track downloads by country.""" return downloads.get_downloads_by_country(self.permissions_filter, **self.args) def test_succeeds(self, response, expected_response_by_country): """Test successful response.""" assert response == expected_response_by_country def test_query_is_loaded(self, response, mock_load_query): """Test correct query is loaded.""" mock_load_query.assert_called_once_with("downloads_group_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["store_ids"] = [1, 496] snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **expected_args}, ) class TestGetDownloadsByCountryWithLabelFilteredByCountry: """Test get_downloads_by_country with label.""" permissions_filter = { "label_ids": [7123], "artist_ids": None, "subaccount_ids": None, "feed_ids": [1, 2], } args = { "isrc": "isrc", "countries": ["GB"], "start_date": "2019-12-01", "end_date": "2019-12-01", "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_by_country): """Mock Snowflake fetchall.""" with patch("sound_recordings.models.downloads.snowflake.fetchall") as fetchall: fetchall.return_value = db_result_by_country 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_by_country, ): """Return track downloads by country.""" return downloads.get_downloads_by_country(self.permissions_filter, **self.args) def test_succeeds(self, response, expected_response_by_country): """Test successful response.""" assert response == expected_response_by_country def test_query_is_loaded(self, response, mock_load_query): """Test correct query is loaded.""" mock_load_query.assert_called_once_with( "downloads_group_by_country_for_country" ) def test_loaded_query_is_run(self, response, mock_snowflake_fetchall): """Test loaded query is run.""" expected_args = self.args expected_args["country_codes"] = ["GB"] del expected_args["countries"] expected_args["store_ids"] = [1, 496] snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **expected_args}, ) class TestGetDownloadsByCountryWithSubaccount: """Test get_downloads_by_country with subaccount.""" permissions_filter = { "label_ids": None, "artist_ids": None, "subaccount_ids": [345], "feed_ids": [1, 2], } args = { "isrc": "isrc", "store_ids": [1, 496], "start_date": "2019-12-01", "end_date": "2019-12-01", "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_by_country): """Mock Snowflake fetchall.""" with patch("sound_recordings.models.downloads.snowflake.fetchall") as fetchall: fetchall.return_value = db_result_by_country 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 ): """Return track downloads.""" return downloads.get_downloads_by_country(self.permissions_filter, **self.args) def test_succeeds(self, response, expected_response_by_country): """Test successful response.""" assert response == expected_response_by_country def test_query_is_loaded(self, response, mock_load_query): """Test correct query is loaded.""" mock_load_query.assert_called_once_with("downloads_group_by_country") def test_loaded_query_is_run(self, response, mock_snowflake_fetchall): """Test loaded query is run.""" snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **self.args, "store_ids": [1, 496]}, ) @pytest.fixture def db_result_by_product(): """Mock db result by product.""" return [ (123, datetime.date(2018, 7, 5), 1), (123, datetime.date(2018, 7, 6), 2), (321, datetime.date(2018, 7, 5), 3), (321, datetime.date(2018, 7, 6), 4), ] @pytest.fixture def expected_response_by_product(): """Expect formated response by product.""" return [ {"product_id": 123, "date": datetime.date(2018, 7, 5), "downloads": 1}, {"product_id": 123, "date": datetime.date(2018, 7, 6), "downloads": 2}, {"product_id": 321, "date": datetime.date(2018, 7, 5), "downloads": 3}, {"product_id": 321, "date": datetime.date(2018, 7, 6), "downloads": 4}, ] class TestGetDownloadsByProductWithLabel: """Test get_downloads_by_product with label.""" permissions_filter = { "label_ids": [7123], "artist_ids": None, "subaccount_ids": None, "feed_ids": [1, 2], } args = { "isrc": "isrc", "countries": [], "start_date": "2019-12-01", "end_date": "2019-12-01", "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_by_product): """Mock Snowflake fetchall.""" with patch("sound_recordings.models.downloads.snowflake.fetchall") as fetchall: fetchall.return_value = db_result_by_product 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_by_product, ): """Return track downloads by country.""" return downloads.get_downloads_by_product(self.permissions_filter, **self.args) def test_succeeds(self, response, expected_response_by_product): """Test successful response.""" assert response == expected_response_by_product def test_query_is_loaded(self, response, mock_load_query): """Test correct query is loaded.""" mock_load_query.assert_called_once_with("downloads_by_product") 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["store_ids"] = [1, 496] snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **expected_args}, ) class TestGetDownloadsByProductWithLabelFilteredByCountry: """Test get_downloads_by_product with label.""" permissions_filter = { "label_ids": [7123], "artist_ids": None, "subaccount_ids": None, "feed_ids": [1, 2], } args = { "isrc": "isrc", "countries": ["GB"], "start_date": "2019-12-01", "end_date": "2019-12-01", "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_by_product): """Mock Snowflake fetchall.""" with patch("sound_recordings.models.downloads.snowflake.fetchall") as fetchall: fetchall.return_value = db_result_by_product 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_by_product, ): """Return track downloads by product.""" return downloads.get_downloads_by_product(self.permissions_filter, **self.args) def test_succeeds(self, response, expected_response_by_product): """Test successful response.""" assert response == expected_response_by_product def test_query_is_loaded(self, response, mock_load_query): """Test correct query is loaded.""" mock_load_query.assert_called_once_with("downloads_by_product_by_country") def test_loaded_query_is_run(self, response, mock_snowflake_fetchall): """Test loaded query is run.""" expected_args = self.args expected_args["country_codes"] = ["GB"] del expected_args["countries"] expected_args["store_ids"] = [1, 496] snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **expected_args}, ) class TestGetDownloadsByProductWithSubaccount: """Test get_downloads_by_product with subaccount.""" permissions_filter = { "label_ids": None, "artist_ids": None, "subaccount_ids": [345], "feed_ids": [1, 2], } args = { "isrc": "isrc", "store_ids": [1, 496], "start_date": "2019-12-01", "end_date": "2019-12-01", "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_by_product): """Mock Snowflake fetchall.""" with patch("sound_recordings.models.downloads.snowflake.fetchall") as fetchall: fetchall.return_value = db_result_by_product 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 ): """Return track downloads by product.""" return downloads.get_downloads_by_product(self.permissions_filter, **self.args) def test_succeeds(self, response, expected_response_by_product): """Test successful response.""" assert response == expected_response_by_product def test_query_is_loaded(self, response, mock_load_query): """Test correct query is loaded.""" mock_load_query.assert_called_once_with("downloads_by_product") def test_loaded_query_is_run(self, response, mock_snowflake_fetchall): """Test loaded query is run.""" snowflake_fetch_assert( mock_snowflake_fetchall, self.expected_sql, {**self.permissions_filter, **self.args, "store_ids": [1, 496]}, )