"""Test single product overview logic layer.""" from multiprocessing import pool from unittest.mock import MagicMock import pytest from oto import response from reporting.logic import single_product_overview as spo from reporting.models import ows_permissions, persister from reporting.utils import single_product_overview as utils @pytest.mark.parametrize('territory, expected', [('CA', 200), ('AUS', 404)]) def test_get_product_overview(mocker, territory, expected, local_product_cd): """Test get_sales_rtd logic.""" mocker.spy(utils, 'territory_to_supply_chain') mocker.spy(persister, 'get_product_overview') mocker.patch.object( persister, 'get_product_overview', return_value=response.Response(status=200), ) snowflake_response = spo.get_product_overview(local_product_cd, territory) utils.territory_to_supply_chain.assert_called_once_with(territory) if expected != 200: assert not persister.get_product_overview.called else: persister.get_product_overview.assert_called_once_with( local_product_cd, utils.territory_to_supply_chain(territory) ) assert snowflake_response.status == expected @pytest.mark.parametrize('territory, expected', [('CA', 200), ('AUS', 404)]) def test_get_monthly_trend(mocker, territory, expected, local_product_cd): """Test get_sales_rtd logic.""" mocker.spy(utils, 'territory_to_supply_chain') mocker.spy(persister, 'get_physical_product_monthly_trend') mocker.patch.object( persister, 'get_physical_product_monthly_trend', return_value=response.Response(status=200), ) snowflake_response = spo.get_monthly_trend(local_product_cd, territory) utils.territory_to_supply_chain.assert_called_once_with(territory) if expected != 200: assert not persister.get_physical_product_monthly_trend.called else: persister.get_physical_product_monthly_trend.assert_called_once_with( local_product_cd, utils.territory_to_supply_chain(territory) ) assert snowflake_response.status == expected @pytest.mark.parametrize('territory, expected', [('CA', 200)]) def test_get_overview(mocker, local_product_cd, territory, expected): """Test get overview logic.""" mocker.spy(spo, '_make_request') mocker.spy(spo, 'get_product_overview') mocker.spy(spo, 'get_monthly_trend') mocker.patch.object( persister, 'get_physical_product_monthly_trend', return_value=response.Response(status=200, message={'foo': 'bar'}), ) mocker.patch.object( persister, 'get_product_overview', return_value=response.Response(status=200, message={'baz': 'qux'}), ) mocker.patch.object( pool, 'ThreadPool', return_value=MagicMock(map=lambda x, y: x(y)) ) snowflake_response = spo.get_overview(local_product_cd, territory) assert spo._make_request.called spo.get_product_overview.assert_called_once_with( local_product_cd, territory ) spo.get_monthly_trend.assert_called_once_with(local_product_cd, territory) assert snowflake_response.status == expected assert snowflake_response.message == {'foo': 'bar', 'baz': 'qux'} def _mock_account_by_product(mocker, vendor_id, subaccount_id): """Mock persister.get_account_by_product for a given owner.""" mocker.patch.object( persister, 'get_account_by_product', return_value=response.Response( message={'vendor_id': vendor_id, 'subaccount_id': subaccount_id} ), ) @pytest.mark.parametrize( ('account_type', 'account_id', 'expected_status'), [ ('vendor', '100', 200), ('vendor', '999', 403), ('subaccount', '200', 200), ('subaccount', '999', 403), ], ) def test_product_belongs_to_account( mocker, local_product_cd, account_type, account_id, expected_status ): """Test product_belongs_to_account authorizes exact grass owner only.""" _mock_account_by_product(mocker, vendor_id=100, subaccount_id=200) result = spo.product_belongs_to_account( local_product_cd, 'CA', account_type, account_id ) assert result.status == expected_status def test_product_belongs_to_account_not_found(mocker, local_product_cd): """Test product_belongs_to_account for an unknown territory.""" result = spo.product_belongs_to_account( local_product_cd, 'AUS', 'vendor', '100' ) assert result.status == 404 @pytest.mark.parametrize( ('permissions_message', 'expected_status'), [ ( {'full_access': False, 'vendor_ids': [100], 'subaccount_ids': []}, 200, ), ( { 'full_access': False, 'vendor_ids': [], 'subaccount_ids': [200], }, 200, ), ( { 'full_access': False, 'vendor_ids': [999], 'subaccount_ids': [999], }, 403, ), ( {'full_access': True, 'vendor_ids': [], 'subaccount_ids': []}, 200, ), ], ) def test_product_belongs_to_profile( mocker, local_product_cd, permissions_message, expected_status ): """Test product_belongs_to_profile authorizes profile's granted scopes.""" _mock_account_by_product(mocker, vendor_id=100, subaccount_id=200) mocker.patch.object( ows_permissions, 'get_label_resources', return_value=response.Response(message=permissions_message), ) result = spo.product_belongs_to_profile( local_product_cd, 'CA', 'Label', '456' ) assert result.status == expected_status def test_product_belongs_to_profile_not_found(mocker, local_product_cd): """Test product_belongs_to_profile for an unknown territory.""" result = spo.product_belongs_to_profile( local_product_cd, 'AUS', 'Label', '456' ) assert result.status == 404 def test_product_belongs_to_profile_permissions_service_error( mocker, local_product_cd ): """Test product_belongs_to_profile bubbles up ows-permissions errors.""" _mock_account_by_product(mocker, vendor_id=100, subaccount_id=200) mocker.patch.object( ows_permissions, 'get_label_resources', return_value=response.create_error_response( status=500, code='internal_error', message='boom' ), ) result = spo.product_belongs_to_profile( local_product_cd, 'CA', 'Label', '456' ) assert result.status == 500