"""Unit tests for streams logic layer.""" from flexmock import flexmock from oto import response as oto_response import pytest from analytics.logic import streams from analytics.models import ows_account from analytics.models import streams as streams_model def test__calculate_percentage(): """Test for _find_by_date method.""" chart = { 'items': [], 'overall_number_of_streams': 10, 'overall_number_of_spotify_streams': 10, 'streams_from_passive_discovery': 1, 'streams_from_active_discovery': 3, 'streams_from_collection': 6, 'skips': 6, 'saves': 3 } streams._calculate_percentage(chart) assert chart['streams_from_passive_discovery_pct'] == 10 assert chart['streams_from_active_discovery_pct'] == 30 assert chart['streams_from_collection_pct'] == 60 assert chart['saves_pct'] == 30 assert chart['skips_pct'] == 60 def test__calculate_percentage__0(): """Test for _find_by_date method.""" chart = { 'items': [], 'overall_number_of_streams': 0, 'overall_number_of_spotify_streams': 0, 'streams_from_passive_discovery': 0, 'streams_from_active_discovery': 0, 'streams_from_collection': 0, 'skips': 0, 'saves': 0 } streams._calculate_percentage(chart) assert chart['streams_from_passive_discovery_pct'] == 0 assert chart['streams_from_active_discovery_pct'] == 0 assert chart['streams_from_collection_pct'] == 0 assert chart['saves_pct'] == 0 assert chart['skips_pct'] == 0 def test__calculate_overall_metrics(): """Test for _find_by_date method.""" chart = { 'items': [ { 'date': '2017-01-01', 'overall_number_of_streams': 3, 'overall_number_of_spotify_streams': 3, 'streams_from_passive_discovery': 1, 'streams_from_active_discovery': 1, 'streams_from_collection': 1, 'skips': 1, 'saves': 1}, { 'date': '2017-01-02', 'overall_number_of_streams': 7, 'overall_number_of_spotify_streams': 7, 'streams_from_passive_discovery': 3, 'streams_from_active_discovery': 2, 'streams_from_collection': 2, 'skips': 3, 'saves': 2}]} streams._calculate_overall_metrics(chart) assert chart['overall_number_of_streams'] == 10 assert chart['streams_from_passive_discovery'] == 4 assert chart['streams_from_active_discovery'] == 3 assert chart['streams_from_collection'] == 3 assert chart['skips'] == 4 assert chart['saves'] == 3 def test_get_streams_successful_result_no_subaccount( streams_params, get_streams_model_response, streams_db_formatted_result, streams_logic_result): """Test get streams when successful call made to datastore.""" streams_params.update({'subaccountid': None}) del streams_params['query'] (flexmock(streams_model).should_receive('get_streams').with_args( **streams_params).and_return( get_streams_model_response).once()) result = streams.get_streams( streams_params['start_date'], streams_params['end_date'], 'vendor', streams_params['labelid'], streams_params['storeids'], streams_params['feed_ids'], streams_params['isrcs'], streams_params['artistids'], streams_params['distributors']) assert result.status == 200 assert result.message == streams_logic_result def test_get_streams_successful_result_with_subaccount( streams_params, get_streams_model_response, streams_db_formatted_result, streams_logic_result): """Test get_streams returns success when called with subaccount. Logic function will make call to ows_account to retrieve vendor_id when subaccount user makes request. """ ows_account_response = oto_response.Response(streams_params['labelid']) del streams_params['query'] (flexmock(ows_account).should_receive( 'get_vendor_id_by_subaccount_id').with_args( streams_params['subaccountid']).and_return( ows_account_response).once()) (flexmock(streams_model).should_receive('get_streams').with_args( **streams_params).and_return( get_streams_model_response).once()) result = streams.get_streams( streams_params['start_date'], streams_params['end_date'], 'subaccount', streams_params['subaccountid'], streams_params['storeids'], streams_params['feed_ids'], streams_params['isrcs'], streams_params['artistids'], streams_params['distributors']) assert result.status == 200 assert result.message == streams_logic_result def test_get_streams_when_error_from_ows_account( streams_params, get_streams_model_response, streams_db_formatted_result): """Test get streams returns error from ows_account when error occurs.""" error_message = 'An error occurred in 2049.' error_code = 'blade_runner' error_status = 418 ows_account_response = oto_response.create_error_response( status=error_status, code=error_code, message=error_message) (flexmock(ows_account).should_receive( 'get_vendor_id_by_subaccount_id').with_args( streams_params['subaccountid']).and_return( ows_account_response).once()) result = streams.get_streams( streams_params['start_date'], streams_params['end_date'], 'subaccount', streams_params['subaccountid'], streams_params['storeids'], streams_params['feed_ids'], streams_params['isrcs'], streams_params['artistids'], streams_params['distributors']) assert result.status == error_status assert result.errors.get('message') == error_message assert result.errors.get('code') == error_code def test_get_streams_failed_result_from_database( streams_params, get_streams_model_response, streams_db_formatted_result): """Test get streams returns fatal response when error from database.""" db_error_message = 'More human than humans.' del streams_params['query'] streams_params.update({'subaccountid': None}) params = streams_params (flexmock(streams_model).should_receive('get_streams').with_args( **streams_params).and_return( oto_response.create_fatal_response(db_error_message)).once()) result = streams.get_streams( params['start_date'], params['end_date'], 'vendor', params['labelid'], params['storeids'], streams_params['feed_ids'], params['isrcs'], params['artistids'], streams_params['distributors']) assert result.status == 500 assert result.errors.get('message') == db_error_message assert result.errors.get('code') == 'internal_error' class TestGetPlacementsWhenEmpty(object): """Test get placements when no placements.""" @pytest.fixture def mock_get_placements(self, placement_params_vendor): """Mock get_placements model call.""" response = oto_response.Response([]) test_params = placement_params_vendor del test_params['query'] return flexmock(streams_model).should_receive( 'get_placements').with_args(**test_params).and_return( response).once() @pytest.fixture def mock_get_placement_totals(self, placement_total_params_vendor): """Mock get_placement_totals model call.""" test_params = placement_total_params_vendor del test_params['query'] return flexmock(streams_model).should_receive( 'get_placement_totals').with_args( **test_params).and_return( oto_response.Response(0)).once() @pytest.fixture def get_placements( self, mock_get_placements, mock_get_placement_totals, placement_params_vendor): """Call logic layer get_placements.""" return streams.get_placements( placement_params_vendor['start_date'], placement_params_vendor['end_date'], 'vendor', placement_params_vendor['labelid'], placement_params_vendor['storeids'], placement_params_vendor['feed_ids'], placement_params_vendor['isrcs'], placement_params_vendor['artistids'], placement_params_vendor['distributors'], placement_params_vendor['limit']) def test_returns_200(self, get_placements): """Return a 200.""" assert get_placements.status == 200 def test_returns_no_total(self, get_placements): """Return total of 2.""" assert get_placements.message.get('total') == 0 def test_returns_empty_list(self, get_placements): """Return an empty list.""" assert get_placements.message.get('items') == [] @pytest.fixture def mock_get_placement_totals(placement_total_params_vendor): """Mock get_placement_totals model call.""" test_params = placement_total_params_vendor del test_params['query'] return flexmock(streams_model).should_receive( 'get_placement_totals').with_args( **test_params).and_return( oto_response.Response(2)).once() @pytest.fixture def get_placements_message(): """Return a fake message for getting placements.""" return [{'thing': 'place'}, {'person': 'house'}] @pytest.fixture def mock_get_placements(placement_params_vendor, get_placements_message): """Mock get_placements model call.""" response = oto_response.Response(get_placements_message) test_params = placement_params_vendor del test_params['query'] return flexmock(streams_model).should_receive( 'get_placements').with_args(**test_params).and_return( response).once() class TestGetPlacements(object): """Test get_placments with placements.""" @pytest.fixture def get_placements( self, mock_get_placements, mock_get_placement_totals, placement_params_vendor): """Call logic layer get_placements.""" return streams.get_placements( placement_params_vendor['start_date'], placement_params_vendor['end_date'], 'vendor', placement_params_vendor['labelid'], placement_params_vendor['storeids'], placement_params_vendor['feed_ids'], placement_params_vendor['isrcs'], placement_params_vendor['artistids'], placement_params_vendor['distributors'], placement_params_vendor['limit']) def test_returns_200(self, get_placements): """Return a 200.""" assert get_placements.status == 200 def test_returns_total(self, get_placements): """Return the total.""" assert get_placements.message.get('total') == 2 def test_returns_items_from_get_placements( self, get_placements, get_placements_message): """Return items from model.""" assert get_placements.message.get('items') == \ get_placements_message class TestGetPlacementsWhenGetPlacementsError(object): """Test get_placments get_placements model error.""" @pytest.fixture def mock_get_placements_with_error(self, placement_params_vendor): """Mock get_placements model call.""" test_params = placement_params_vendor del test_params['query'] return flexmock(streams_model).should_receive( 'get_placements').with_args(**test_params).and_return( oto_response.create_fatal_response()).once() @pytest.fixture def get_placements( self, mock_get_placements_with_error, mock_get_placement_totals, placement_params_vendor): """Call logic layer get_placements.""" return streams.get_placements( placement_params_vendor['start_date'], placement_params_vendor['end_date'], 'vendor', placement_params_vendor['labelid'], placement_params_vendor['storeids'], placement_params_vendor['feed_ids'], placement_params_vendor['isrcs'], placement_params_vendor['artistids'], placement_params_vendor['distributors'], placement_params_vendor['limit']) def test_returns_500(self, get_placements): """Return a 500.""" assert get_placements.status == 500 class TestGetPlacementsWhenGetPlacementTotalsError(object): """Test get_placments with placements.""" @pytest.fixture def mock_get_placement_totals_with_error(self, streams_params): """Mock get_placement_totals model call.""" return flexmock(streams_model).should_receive( 'get_placement_totals').and_return( oto_response.create_fatal_response()).once() @pytest.fixture def get_placements( self, mock_get_placements, mock_get_placement_totals_with_error, placement_params_vendor): """Call logic layer get_placements.""" return streams.get_placements( placement_params_vendor['start_date'], placement_params_vendor['end_date'], 'vendor', placement_params_vendor['labelid'], placement_params_vendor['storeids'], placement_params_vendor['feed_ids'], placement_params_vendor['isrcs'], placement_params_vendor['artistids'], placement_params_vendor['distributors'], placement_params_vendor['limit']) def test_returns_500(self, get_placements): """Return a 500.""" assert get_placements.status == 500