"""Tests for demographics endpoint.""" import json from unittest.mock import MagicMock import flexmock from oto import response as oto_response from owsrequest import constants as context import pytest from analytics.consts import error from analytics.logic import demographics from analytics.models import ows_account from tests.unit.fixtures import fixture_api VENDOR_ID = 1000 @pytest.fixture def mock_call_to_ows_account(): """Mock call to ows_account model for fetching vendor_id.""" (flexmock(ows_account).should_receive( 'get_vendor_id_by_subaccount_id').and_return( oto_response.Response(message=VENDOR_ID))) @pytest.fixture() def mock_snowflake(monkeypatch, mock_config): """Mock for Snowflake database client.""" snowflake_mock = MagicMock() monkeypatch.setattr( 'analytics.models.demographics.snowflake_conn', snowflake_mock) return snowflake_mock @pytest.mark.parametrize( 'url, error_message', [ # too long date range ( '/demographic_insights/?from_date=2015-01-01&to_date=2017-01-03', error.INVALID_DATE_RANGE_VALUES_MESSAGE), # bad store ids ( '/demographic_insights/?from_date=2017-01-01&to_date=2017-01-03' '&stores=a,b,c', error.INVALID_STORE_IDS_FORMAT_MESSAGE), # unexpected store ids ( '/demographic_insights/?from_date=2017-01-01&to_date=2017-01-03' '&stores=1,2,3', error.INVALID_STORE_IDS_VALUES_MESSAGE) ]) def test_demographic_insights_unprocessable_entity( url, error_message, headers): """Test get_demographic_insights for 422 response.""" response = fixture_api.CLIENT.get(url, headers=headers) assert json.loads(response.data.decode())['message'] == error_message class TestGetDemographicInsights(object): """Test get_demographic_insights handler.""" url = ('/demographic_insights/?from_date=2017-01-01&to_date=2017-01-03' '&stores=286') headers = { context.GRASS_ACCOUNT_TYPE: 'subaccount', context.GRASS_ACCOUNT_ID: 1111} @pytest.fixture def mock_logic_get_demo_ok(self, monkeypatch): """Mock get_demographic_insights logic call.""" mock_get_demographic_insights = MagicMock( return_value=oto_response.Response()) monkeypatch.setattr( demographics, 'get_demographic_insights', mock_get_demographic_insights) return mock_get_demographic_insights @pytest.fixture def mock_track_custom_params(self, monkeypatch): """Mock track_custom_parameters.""" mock_track = MagicMock() monkeypatch.setattr( 'analytics.handlers.track_custom_parameters', mock_track) return mock_track @pytest.fixture def request_demographic_insights_isrcs( self, mock_logic_get_demo_ok, mock_track_custom_params): """Request demographic insights.""" isrcs_param = '&isrcs=ISRC123,ISRC5678' return fixture_api.CLIENT.get( self.url + isrcs_param, headers=self.headers) @pytest.fixture def request_demographic_insights_artist_ids( self, mock_logic_get_demo_ok, mock_track_custom_params): """Request demographic insights.""" artist_ids_param = '&artist_ids=123,5678' return fixture_api.CLIENT.get( self.url + artist_ids_param, headers=self.headers) @pytest.fixture def request_demographic_insights_territory_code( self, mock_logic_get_demo_ok, mock_track_custom_params): """Request demographic insights.""" territory_code_param = '&territory_code=US' return fixture_api.CLIENT.get( self.url + territory_code_param, headers=self.headers) @pytest.fixture def request_demographic_insights_region_code( self, mock_logic_get_demo_ok, mock_track_custom_params): """Request demographic insights.""" region_code_param = '®ion_code=101' return fixture_api.CLIENT.get( self.url + region_code_param, headers=self.headers) def test_returns_success_when_called_with_isrcs( self, request_demographic_insights_isrcs): """Test returns success with isrcs.""" assert request_demographic_insights_isrcs.status_code == 200 def test_returns_success_when_called_with_artist_ids( self, request_demographic_insights_artist_ids): """Test returns success with isrcs.""" assert request_demographic_insights_artist_ids.status_code == 200 def test_calls_logic_layer_with_isrcs( self, request_demographic_insights_isrcs, mock_logic_get_demo_ok): """Test calls logic layer with isrcs.""" mock_logic_get_demo_ok.assert_called_once_with( account_type='subaccount', account_id='1111', end_date='2017-01-03', start_date='2017-01-01', artist_ids=None, isrcs=['ISRC123', 'ISRC5678'], store_ids=['286'], territory_code=None, region_code=None) def test_calls_track_custom_parameters_with_isrcs( self, request_demographic_insights_isrcs, mock_track_custom_params): """Test calls new relic with isrcs.""" mock_track_custom_params.assert_called_once_with( account_id='1111', end_date='2017-01-03', start_date='2017-01-01', date_period=None, artist_ids=None, isrcs=['ISRC123', 'ISRC5678'], store_ids=['286'], territory_code=None, region_code=None) def test_calls_logic_layer_with_artist_ids( self, request_demographic_insights_artist_ids, mock_logic_get_demo_ok): """Test calls logic layer with isrcs.""" mock_logic_get_demo_ok.assert_called_once_with( account_type='subaccount', account_id='1111', end_date='2017-01-03', start_date='2017-01-01', artist_ids=['123', '5678'], isrcs=None, store_ids=['286'], territory_code=None, region_code=None) def test_calls_track_custom_parameters_with_artist_ids( self, request_demographic_insights_artist_ids, mock_track_custom_params): """Test calls new relic with artist_ids.""" mock_track_custom_params.assert_called_once_with( account_id='1111', end_date='2017-01-03', start_date='2017-01-01', date_period=None, artist_ids=['123', '5678'], isrcs=None, store_ids=['286'], territory_code=None, region_code=None) def test_calls_logic_layer_with_territory_code( self, request_demographic_insights_territory_code, mock_logic_get_demo_ok): """Test calls logic layer with territory_code.""" mock_logic_get_demo_ok.assert_called_once_with( account_type='subaccount', account_id='1111', end_date='2017-01-03', start_date='2017-01-01', artist_ids=None, isrcs=None, store_ids=['286'], territory_code='US', region_code=None) def test_calls_track_custom_parameters_with_territory_code( self, request_demographic_insights_territory_code, mock_track_custom_params): """Test calls new relic with territory code.""" mock_track_custom_params.assert_called_once_with( account_id='1111', end_date='2017-01-03', start_date='2017-01-01', date_period=None, artist_ids=None, isrcs=None, store_ids=['286'], territory_code='US', region_code=None) def test_calls_logic_layer_with_region_code( self, request_demographic_insights_region_code, mock_logic_get_demo_ok): """Test calls logic layer with region.""" mock_logic_get_demo_ok.assert_called_once_with( account_type='subaccount', account_id='1111', end_date='2017-01-03', start_date='2017-01-01', artist_ids=None, isrcs=None, store_ids=['286'], territory_code=None, region_code='101') def test_calls_track_custom_parameters_with_region_code( self, request_demographic_insights_region_code, mock_track_custom_params): """Test calls new relic with region code.""" mock_track_custom_params.assert_called_once_with( account_id='1111', end_date='2017-01-03', start_date='2017-01-01', date_period=None, artist_ids=None, isrcs=None, store_ids=['286'], territory_code=None, region_code='101') def test_empty_demographics_insights( headers, mock_snowflake, mock_call_to_ows_account): """Test demographic_insights endpoint returns 204 when data absent.""" mock_snowflake.fetchall.return_value = [] url = ( '/demographic_insights/?from_date=2017-05-01&' 'to_date=2017-05-02&stores=286') response = fixture_api.CLIENT.get(url, headers=headers) assert response.data.decode('utf8') == '' assert response.status_code == 204 def test_nonempty_demographics_insights( headers, mock_snowflake, demographics_db_result, mock_call_to_ows_account): """Test demographic_insights endpoint returns data in valid format.""" mock_snowflake.fetchall.return_value = demographics_db_result url = ( '/demographic_insights/?from_date=2017-05-01&' 'to_date=2017-05-02&stores=286') response = fixture_api.CLIENT.get(url, headers=headers) assert response.status_code == 200 data = json.loads(response.data.decode('utf8')) assert data