"""Tests for Product Pricing Override Tier logic.""" from unittest.mock import MagicMock from oto import response from pricing.constants import error from pricing.logic import change_detection from pricing.logic import product_pricing_override from pricing.models import product_pricing_override \ as product_pricing_override_model from pricing.models import product_pricing_override_store as \ product_pricing_override_store_model from pricing.models import product_pricing_override_territory \ as product_pricing_override_territory_model import pytest @pytest.fixture def fixture_product_pricing_override(): """Fixture for single product pricing override.""" return response.Response( message={ 'product_id': 1, 'product_pricing_override_id': 1, 'pricing_family_id': 1, 'applies_worldwide': True, 'store_id': 1, 'orchard_pricing_tier_id': 3 }, status=200) @pytest.fixture def fixture_product_pricing_override_no_id(): """Fixture for single product pricing override without ID.""" return response.Response( message={ 'product_id': 1, 'pricing_family_id': 1, 'applies_worldwide': True, 'store_id': 1, 'orchard_pricing_tier_id': 3 }, status=200) @pytest.fixture def fixture_product_pricing_overrides(): """Fixture for single product pricing override.""" return response.Response( message={ 'items': [{ 'product_id': 1, 'pricing_family_id': 1, 'product_pricing_override_id': 1, 'applies_worldwide': True, 'store_id': 1, 'orchard_pricing_tier_id': 3}] }, status=200) @pytest.fixture def fixture_product_pricing_overrides_empty_response(): """Fixture for single product pricing override.""" return response.Response( message={ 'items': [] }, status=200) @pytest.fixture def fixture_product_pricing_override_stores(): """Fixture for a product pricing override stores update response.""" return response.Response({ 'created': [ { 'store_id': 1 } ], 'deleted': [] }) @pytest.fixture def fixture_product_pricing_override_territories(): """Fixture for a product pricing override territories update response.""" return response.Response({ 'created': [ { 'territory_code': 'US' } ], 'deleted': [] }) @pytest.fixture def fixture_error(): """Fixture for an error response.""" return response.Response(status=500) @pytest.fixture def fixture_find_duplicate_true(): """Fixture for a positive find_duplicate response.""" return response.Response({ 'found': True, 'item': { 'product_pricing_override_id': 1 } }) @pytest.fixture def fixture_find_duplicate_false(): """Fixture for a negative find_duplicate response.""" return response.Response({'found': False}) @pytest.fixture def fixture_get_territories(): """Fixture for a get territories response.""" return response.Response({ 'items': [ { 'territory_code': 'US' }, { 'territory_code': 'CA' } ] }) @pytest.fixture def fixture_get_stores(): """Fixture for a get stores response.""" return response.Response({ 'items': [ { 'store_id': 1 }, { 'store_id': 2 } ] }) def test_get_by_product_id(monkeypatch, fixture_product_pricing_override): """Test getting product pricing overrides with product id.""" monkeypatch.setattr( product_pricing_override_model, 'get_by_product_id', MagicMock(return_value=fixture_product_pricing_override)) result = product_pricing_override.get_by_product_id(1) product_pricing_override_model.get_by_product_id.assert_called_with(1) assert result assert result.message == fixture_product_pricing_override.message def test_create_product_pricing_override( monkeypatch, fixture_product_pricing_override, fixture_find_duplicate_false): """Test creating a product pricing override.""" monkeypatch.setattr( product_pricing_override_model, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_model, 'find_duplicate', MagicMock(return_value=fixture_find_duplicate_false)) data = fixture_product_pricing_override.message result = product_pricing_override.create_product_pricing_override(1, data) product_pricing_override_model.create_product_pricing_override\ .assert_called_with(1, data) assert result assert result.message == fixture_product_pricing_override.message def test_create_product_pricing_override_with_error( monkeypatch, fixture_error): """Test error response when creating a product pricing override.""" monkeypatch.setattr( product_pricing_override_model, 'create_product_pricing_override', MagicMock(return_value=fixture_error)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) product_id = 1 data = {} result = product_pricing_override.create_product_pricing_override( product_id, data) assert result == fixture_error def test_create_product_pricing_override_with_territories( monkeypatch, fixture_product_pricing_override, fixture_product_pricing_override_territories): """Test creating a product pricing override with some territories.""" monkeypatch.setattr( product_pricing_override_model, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_territory_model, 'update_territories', MagicMock(return_value=fixture_product_pricing_override_territories)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) product_id = 1 create_data = { 'applies_worldwide': True, 'pricing_family_id': 1, 'store_id': 1, 'orchard_pricing_tier_id': 3 } territories = ['US'] data = dict(create_data) data['territories'] = territories expected_result = fixture_product_pricing_override.message expected_result['territories'] = ['US'] result = product_pricing_override.create_product_pricing_override( product_id, data) assert result product_pricing_override_id = result.message['product_pricing_override_id'] product_pricing_override_model.create_product_pricing_override.\ assert_called_with(product_id, create_data) product_pricing_override_territory_model.update_territories.\ assert_called_with(product_pricing_override_id, territories) assert result.message == expected_result def test_create_with_territories_and_error( monkeypatch, fixture_product_pricing_override, fixture_error): """Test error response during territories update.""" monkeypatch.setattr( product_pricing_override_model, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_territory_model, 'update_territories', MagicMock(return_value=fixture_error)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) product_id = 1 data = {'territories': ['US']} result = product_pricing_override.create_product_pricing_override( product_id, data) assert result == fixture_error def test_create_product_pricing_override_with_stores( monkeypatch, fixture_product_pricing_override, fixture_product_pricing_override_stores): """Test creating a product pricing override with some stores.""" monkeypatch.setattr( product_pricing_override_model, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_store_model, 'update_stores', MagicMock(return_value=fixture_product_pricing_override_stores)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) product_id = 1 create_data = { 'applies_worldwide': True, 'pricing_family_id': 1, 'store_id': 1, 'orchard_pricing_tier_id': 3 } stores = [1] data = dict(create_data) data['stores'] = stores expected_result = fixture_product_pricing_override.message expected_result['stores'] = [1] result = product_pricing_override.create_product_pricing_override( product_id, data) assert result product_pricing_override_id = result.message['product_pricing_override_id'] product_pricing_override_model.create_product_pricing_override.\ assert_called_with(product_id, create_data) product_pricing_override_store_model.update_stores.\ assert_called_with(product_pricing_override_id, stores) assert result.message == expected_result def test_create_product_pricing_override_with_change_detection_error( monkeypatch, fixture_error): """Test change detection is not called if there is an error.""" monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_error)) monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) product_id = 1 pricing_family_id = 4 data = { 'stores': [1], 'pricing_family_id': pricing_family_id } result = product_pricing_override.\ create_product_pricing_override_with_change_detection( product_id, data) assert result == fixture_error assert change_detection.write_pricing_changes.call_count == 0 def test_create_product_pricing_override_with_change_detection_no_error( monkeypatch, fixture_product_pricing_override): """Test change detection is not called if there is an error.""" monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) product_id = 1 pricing_family_id = 2 data = {'stores': [1], 'pricing_family_id': pricing_family_id} result = product_pricing_override.\ create_product_pricing_override_with_change_detection( product_id, data) assert result == fixture_product_pricing_override change_detection.write_pricing_changes.\ assert_called_with(product_id, pricing_family_id) def test_create_with_stores_and_error( monkeypatch, fixture_product_pricing_override, fixture_error): """Test error response during stores update.""" monkeypatch.setattr( product_pricing_override_model, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_store_model, 'update_stores', MagicMock(return_value=fixture_error)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) product_id = 1 data = {'stores': [1]} result = product_pricing_override.create_product_pricing_override( product_id, data) assert result == fixture_error def test_create_duplicate(monkeypatch): """Test duplicate response when creating a product pricing override.""" monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=True)) product_id = 1 data = {} result = product_pricing_override.create_product_pricing_override( product_id, data) assert result.status == 400 assert result.errors['message'] == error.ERROR_MESSAGE_DUPLICATE def test_bulk_create_product_pricing_override( monkeypatch, fixture_product_pricing_override): """Test creating product pricing overrides.""" monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) data = { 'items': [ fixture_product_pricing_override.message, fixture_product_pricing_override.message ] } product_id = 1 result = product_pricing_override.bulk_create_product_pricing_override( product_id, data) assert product_pricing_override.\ create_product_pricing_override.call_count == 2 change_detection.write_pricing_changes.call_count == 1 change_detection.write_pricing_changes.\ assert_called_with(product_id, 1) assert result assert result.message['items'] == data['items'] def test_bulk_create_product_pricing_override_bad_data(monkeypatch): """Test bad data response when creating product pricing overrides.""" data = {} product_id = 1 monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) result = product_pricing_override.bulk_create_product_pricing_override( product_id, data) assert result.status == 400 change_detection.write_pricing_changes.call_count == 0 def test_bulk_create_product_pricing_override_error( monkeypatch, fixture_error): """Test error response when creating product pricing overrides.""" monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_error)) monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) data = { 'items': [{'pricing_family_id': 1}] } product_id = 1 result = product_pricing_override.bulk_create_product_pricing_override( product_id, data) assert result.status == 500 change_detection.write_pricing_changes.call_count == 0 def test_bulk_update_create_product_pricing_override( monkeypatch, fixture_product_pricing_override, fixture_product_pricing_override_no_id): """Test bulk updating and creating product pricing overrides.""" monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override, 'update_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) data = { 'items': [ fixture_product_pricing_override.message, fixture_product_pricing_override_no_id.message ] } product_id = 1 result = product_pricing_override.\ bulk_update_create_product_pricing_override(product_id, data) assert product_pricing_override.\ create_product_pricing_override.call_count == 1 assert product_pricing_override.\ update_product_pricing_override.call_count == 1 assert result assert result.message == { 'items': [ fixture_product_pricing_override.message, fixture_product_pricing_override.message ] } change_detection.write_pricing_changes.call_count == 1 change_detection.write_pricing_changes.\ assert_called_with(product_id, 1) def test_bulk_update_create_product_pricing_override_bad_data(monkeypatch): """Test bad data response when updating product pricing overrides.""" monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) data = {} product_id = 1 result = product_pricing_override.\ bulk_update_create_product_pricing_override(product_id, data) assert result.status == 400 change_detection.write_pricing_changes.call_count == 0 def test_bulk_update_create_product_pricing_override_create_error( monkeypatch, fixture_error, fixture_product_pricing_override_no_id): """Test error response when updating product pricing override.""" monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_error)) monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) data = { 'items': [ fixture_product_pricing_override_no_id.message ] } product_id = 1 result = product_pricing_override.\ bulk_update_create_product_pricing_override(product_id, data) assert result.status == 500 change_detection.write_pricing_changes.call_count == 0 def test_bulk_update_create_product_pricing_override_update_error( monkeypatch, fixture_error, fixture_product_pricing_override): """Test error response when creating product pricing override.""" monkeypatch.setattr( product_pricing_override, 'update_product_pricing_override', MagicMock(return_value=fixture_error)) monkeypatch.setattr( change_detection, 'write_pricing_changes', MagicMock()) data = { 'items': [ fixture_product_pricing_override.message ] } product_id = 1 result = product_pricing_override.\ bulk_update_create_product_pricing_override(product_id, data) assert result.status == 500 change_detection.write_pricing_changes.call_count == 0 def test_update_product_pricing_override( monkeypatch, fixture_product_pricing_override, fixture_product_pricing_override_territories): """Test updating a product pricing override.""" monkeypatch.setattr( product_pricing_override_model, 'update_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_territory_model, 'update_territories', MagicMock(return_value=fixture_product_pricing_override_territories)) data = fixture_product_pricing_override.message result = product_pricing_override.update_product_pricing_override( 1, 1, data) product_pricing_override_model.update_product_pricing_override.\ assert_called_with(1, 1, data) assert result assert result.message == fixture_product_pricing_override.message def test_update_product_pricing_override_with_error( monkeypatch, fixture_error): """Test error response when update a product_pricing_override.""" monkeypatch.setattr( product_pricing_override_model, 'update_product_pricing_override', MagicMock(return_value=fixture_error)) product_id = 10 product_pricing_override_id = 1 data = {} result = product_pricing_override.update_product_pricing_override( product_id, product_pricing_override_id, data) assert result == fixture_error def test_update_product_pricing_override_with_territories( monkeypatch, fixture_product_pricing_override, fixture_product_pricing_override_territories): """Test updating a store pricing tier code with some territories.""" monkeypatch.setattr( product_pricing_override_model, 'update_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_territory_model, 'update_territories', MagicMock(return_value=fixture_product_pricing_override_territories)) product_pricing_override_id = 1 product_id = 1 update_data = { 'applies_worldwide': True, 'pricing_family_id': 1, 'store_id': 1, 'orchard_pricing_tier_id': 3, 'territory_list_include': True } territories = ['US'] data = dict(update_data) data['territories'] = territories expected_result = fixture_product_pricing_override.message expected_result['territories'] = \ fixture_product_pricing_override_territories.message result = product_pricing_override.update_product_pricing_override( product_id, product_pricing_override_id, data) assert result product_pricing_override_model.update_product_pricing_override.\ assert_called_with(product_id, product_pricing_override_id, update_data) product_pricing_override_territory_model.update_territories.\ assert_called_with(product_pricing_override_id, territories) assert result.message == expected_result def test_update_product_pricing_override_with_territories_and_error( monkeypatch, fixture_product_pricing_override, fixture_error): """Test error response during territories update.""" monkeypatch.setattr( product_pricing_override_model, 'update_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_territory_model, 'update_territories', MagicMock(return_value=fixture_error)) product_pricing_override_id = 1 product_id = 1 data = {'territories': ['US']} result = product_pricing_override.update_product_pricing_override( product_id, product_pricing_override_id, data) assert result == fixture_error def test_update_product_pricing_override_with_stores( monkeypatch, fixture_product_pricing_override, fixture_product_pricing_override_stores): """Test updating a store pricing tier code with some stores.""" monkeypatch.setattr( product_pricing_override_model, 'update_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_store_model, 'update_stores', MagicMock(return_value=fixture_product_pricing_override_stores)) product_pricing_override_id = 1 product_id = 1 update_data = { 'applies_worldwide': True, 'pricing_family_id': 1, 'store_id': 1, 'orchard_pricing_tier_id': 3, 'territory_list_include': True } stores = [1] data = dict(update_data) data['stores'] = stores expected_result = fixture_product_pricing_override.message expected_result['stores'] = [1] result = product_pricing_override.update_product_pricing_override( product_id, product_pricing_override_id, data) assert result product_pricing_override_model.update_product_pricing_override.\ assert_called_with(product_id, product_pricing_override_id, update_data) product_pricing_override_store_model.update_stores.\ assert_called_with(product_pricing_override_id, stores) assert result.message == expected_result def test_update_product_pricing_override_with_stores_and_error( monkeypatch, fixture_product_pricing_override, fixture_error): """Test error response during stores update.""" monkeypatch.setattr( product_pricing_override_model, 'update_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override_store_model, 'update_stores', MagicMock(return_value=fixture_error)) product_pricing_override_id = 1 product_id = 1 data = {'stores': [1]} result = product_pricing_override.update_product_pricing_override( product_id, product_pricing_override_id, data) assert result == fixture_error def test_find_duplicate_true( monkeypatch, fixture_find_duplicate_true, fixture_get_territories, fixture_get_stores): """Test finding an existing duplicate product pricing override.""" monkeypatch.setattr( product_pricing_override_model, 'find_duplicate', MagicMock(return_value=fixture_find_duplicate_true)) monkeypatch.setattr( product_pricing_override_territory_model, 'get_by_product_pricing_override_id', MagicMock(return_value=fixture_get_territories)) monkeypatch.setattr( product_pricing_override_store_model, 'get_by_product_pricing_override_id', MagicMock(return_value=fixture_get_stores)) product_id = 1 data = { 'applies_worldwide': True, 'store_id': 1, 'orchard_pricing_tier_id': 3, 'territory_list_include': True } territories = ['US', 'CA'] stores = [1, 2] result = product_pricing_override.has_duplicate( product_id, data, territories, stores) assert result is True def test_find_duplicate_false( monkeypatch, fixture_find_duplicate_false): """Test finding a non-existing duplicate product pricing override.""" monkeypatch.setattr( product_pricing_override_model, 'find_duplicate', MagicMock(return_value=fixture_find_duplicate_false)) product_id = 10 data = { 'applies_worldwide': True, 'store_id': 1, 'orchard_pricing_tier_id': 3 } territories = [] stores = [] result = product_pricing_override.has_duplicate( product_id, data, territories, stores) assert result is False def test_find_duplicate_with_territories_false( monkeypatch, fixture_find_duplicate_true, fixture_get_territories, fixture_get_stores): """Test finding a non-existing duplicate PPO with territories.""" monkeypatch.setattr( product_pricing_override_model, 'find_duplicate', MagicMock(return_value=fixture_find_duplicate_true)) monkeypatch.setattr( product_pricing_override_territory_model, 'get_by_product_pricing_override_id', MagicMock(return_value=fixture_get_territories)) monkeypatch.setattr( product_pricing_override_store_model, 'get_by_product_pricing_override_id', MagicMock(return_value=fixture_get_stores)) product_id = 1 data = { 'applies_worldwide': True, 'store_id': 1, 'orchard_pricing_tier_id': 3, 'territory_list_include': True } territories = ['US', 'CA', 'FR'] stores = [1, 2] result = product_pricing_override.has_duplicate( product_id, data, territories, stores) assert result is False def test_find_duplicate_with_stores_false( monkeypatch, fixture_find_duplicate_true, fixture_get_territories, fixture_get_stores): """Test finding a non-existing duplicate TPO with stores.""" monkeypatch.setattr( product_pricing_override_model, 'find_duplicate', MagicMock(return_value=fixture_find_duplicate_true)) monkeypatch.setattr( product_pricing_override_territory_model, 'get_by_product_pricing_override_id', MagicMock(return_value=fixture_get_territories)) monkeypatch.setattr( product_pricing_override_store_model, 'get_by_product_pricing_override_id', MagicMock(return_value=fixture_get_stores)) product_id = 1 data = { 'applies_worldwide': True, 'store_id': 1, 'orchard_pricing_tier_id': 3, 'territory_list_include': True } territories = ['US', 'CA'] stores = [1, 2, 3] result = product_pricing_override.has_duplicate( product_id, data, territories, stores) assert result is False def test_find_duplicate_error(monkeypatch, fixture_error): """Test that an exception is raised if an error occurred.""" monkeypatch.setattr( product_pricing_override_model, 'find_duplicate', MagicMock(return_value=fixture_error)) product_id = 1 data = { 'price_code': '100', 'resolution': '4K', 'applies_worldwide': False, 'territory_list_include': True } territories = [] stores = [] try: product_pricing_override.has_duplicate( product_id, data, territories, stores) except Exception as err: assert err def test_find_duplicate_with_territories_error( monkeypatch, fixture_find_duplicate_true, fixture_error): """Test that an exception is raised if an error occurred.""" monkeypatch.setattr( product_pricing_override_model, 'find_duplicate', MagicMock(return_value=fixture_find_duplicate_true)) monkeypatch.setattr( product_pricing_override_territory_model, 'get_by_product_pricing_override_id', MagicMock(return_value=fixture_error)) product_id = 1 data = { 'price_code': '100', 'resolution': '4K', 'applies_worldwide': False, 'territory_list_include': True } territories = ['US', 'CA'] stores = [1, 2] try: product_pricing_override.has_duplicate( product_id, data, territories, stores) except Exception as err: assert err def test_find_duplicate_with_stores_error( monkeypatch, fixture_find_duplicate_true, fixture_error): """Test that an exception is raised if an error occurred.""" monkeypatch.setattr( product_pricing_override_model, 'find_duplicate', MagicMock(return_value=fixture_find_duplicate_true)) monkeypatch.setattr( product_pricing_override_store_model, 'get_by_product_pricing_override_id', MagicMock(return_value=fixture_error)) product_id = 1 data = { 'price_code': '100', 'resolution': '4K', 'applies_worldwide': False, 'territory_list_include': True } territories = ['US', 'CA'] stores = [1, 2] try: product_pricing_override.has_duplicate( product_id, data, territories, stores) except Exception as err: assert err