"""Unit tests for sound recording streams_by_store logic layer.""" import datetime from unittest.mock import patch import pytest from sound_recordings.api import app from sound_recordings.logic import streams_by_store as streams_by_store @pytest.fixture def mock_get_streams_by_store_model_payload(): """Mock payload for sound recording streams_by_store model.""" return [ { "store_id": 1, "date": datetime.date(2018, 6, 28), "streams": 500, "streams_with_skips": 0, "skips": None, "saves": None, }, { "store_id": 1, "date": datetime.date(2018, 6, 29), "streams": 3000, "streams_with_skips": 2000, "skips": 300, "saves": 600, }, { "store_id": 286, "date": datetime.date(2018, 6, 28), "streams": 3000, "streams_with_skips": 2000, "skips": 300, "saves": 600, }, { "store_id": 286, "date": datetime.date(2018, 6, 29), "streams": 2000, "streams_with_skips": 1000, "skips": 200, "saves": 400, }, { "store_id": 1, "date": datetime.date(2018, 6, 30), "streams": 1000, "streams_with_skips": 0, "skips": None, "saves": None, }, ] @pytest.fixture def expected_payload(): """Return expected payload from streams_by_store logic.""" return { "isrc": "isrc", "stores": [ { "id": 1, "name": "Apple Music", "items": [ { "streams": 500, "saves": None, "skip_rate": None, "date": "2018-06-28T00:00:00Z", }, { "streams": 3000, "saves": 600, "skip_rate": 0.13043478260869565, "date": "2018-06-29T00:00:00Z", }, { "streams": 1000, "saves": None, "skip_rate": None, "date": "2018-06-30T00:00:00Z", }, ], }, { "id": 286, "name": "Spotify", "items": [ { "streams": 3000, "saves": 600, "skip_rate": 0.13043478260869565, "date": "2018-06-28T00:00:00Z", }, { "streams": 2000, "saves": 400, "skip_rate": None, "date": "2018-06-29T00:00:00Z", }, ], }, ], } @pytest.fixture def mock_get_streams_by_store_model_success(mock_get_streams_by_store_model_payload): """Mock successful get_streams_by_store model response.""" with patch( "sound_recordings.models.streams_by_store.get_streams_by_store" ) as get_streams_by_store: get_streams_by_store.return_value = mock_get_streams_by_store_model_payload yield get_streams_by_store @pytest.fixture def mock_get_streams_by_store_model_failure(): """Mock failure get_streams_by_store model response.""" with patch( "sound_recordings.models.streams_by_store.get_streams_by_store" ) as get_streams_by_store: get_streams_by_store.return_value = [] yield get_streams_by_store class TestGetStreamsByStoreWithLabel: """Test get_streams_by_store with label.""" isrc = "isrc" start_date = datetime.date(2018, 6, 28) end_date = datetime.date(2018, 6, 29) @pytest.fixture def response( self, mock_get_streams_by_store_model_success, request_context_for_label, mock_permissions_for_label, ): """Run get_streams_by_store.""" return streams_by_store.get_streams_by_store( request_context_for_label, self.isrc, ["theorchard"], [], [], self.start_date, self.end_date, ) def test_succeeds(self, response, expected_payload): """Test successful response.""" assert response.status == 200 # Sorted the response and expected_payload as set() changes the order # of the `all_store_ids` list every time assert sorted(response.message) == sorted(expected_payload) def test_get_streams_by_store_model_is_called( self, response, mock_get_streams_by_store_model_success, permissions_for_label ): """Test streams_by_store model is called.""" mock_get_streams_by_store_model_success.assert_called_once_with( permissions_for_label, self.isrc, ["theorchard"], [], [], self.start_date, self.end_date, ) def test_fails_when_streams_by_store_model_fails( self, mock_get_streams_by_store_model_failure, mock_permissions_for_label, request_context_for_label, ): """Test failure response when streams_by_store model fails.""" response = streams_by_store.get_streams_by_store( request_context_for_label, self.isrc, ["theorchard"], [], [], self.start_date, self.end_date, ) assert response.status == 200 assert response.message == {"isrc": self.isrc, "stores": []} class TestGetStreamsByStoreWithSubaccount: """Test get_streams_by_store with subaccount.""" isrc = "isrc" start_date = datetime.date(2018, 6, 28) end_date = datetime.date(2018, 6, 29) @pytest.fixture def response( self, mock_get_streams_by_store_model_success, mock_permissions_for_subaccount, request_context_for_subaccount, ): """Run get_streams_by_store.""" with app.test_request_context(): return streams_by_store.get_streams_by_store( request_context_for_subaccount, self.isrc, ["theorchard"], [], [], self.start_date, self.end_date, ) def test_succeeds(self, response, expected_payload): """Test successful response.""" assert response.status == 200 assert sorted(response.message) == sorted(expected_payload) def test_get_streams_by_store_model_is_called( self, response, mock_get_streams_by_store_model_success, permissions_for_subaccount, ): """Test streams_by_store model is called.""" mock_get_streams_by_store_model_success.assert_called_once_with( permissions_for_subaccount, self.isrc, ["theorchard"], [], [], self.start_date, self.end_date, ) def test_fails_when_streams_by_store_model_fails( self, mock_get_streams_by_store_model_failure, mock_permissions_for_subaccount, request_context_for_subaccount, ): """Test failure response when streams_by_store model fails.""" response = streams_by_store.get_streams_by_store( request_context_for_subaccount, self.isrc, ["theorchard"] ) assert response.status == 200 assert response.message == {"isrc": self.isrc, "stores": []}