"""Tests for Bulk Product Update logic.""" from unittest.mock import MagicMock from unittest.mock import call from oto import response from pricing.constants import error from pricing.logic import bulk_product_update from pricing.logic import legacy_product_mapping from pricing.logic import product from pricing.logic import product_orchard_pricing_tier from pricing.logic import product_pricing_override import pytest @pytest.fixture def fixture_success(): """Fixture for a successfull response.""" return response.Response(status=200) @pytest.fixture def fixture_error(): """Fixture for an error response.""" return response.create_error_response( 500, error.ERROR_MESSAGE_DB_ISSUE) def fixture_empty_body_helper(): """Fixture for an empty body response.""" return response.create_error_response( 400, error.ERROR_MESSAGE_EMPTY_BODY) @pytest.fixture def fixture_empty_body(): """Fixture helper.""" return fixture_empty_body_helper() @pytest.fixture def fixture_product_orchard_pricing_tier(): """Fixture for single product orchard pricing tier.""" return response.Response( message={ 'product_orchard_pricing_tier_id': 1, 'orchard_pricing_tier_id': 2 }, status=200) @pytest.fixture def fixture_product_pricing_override(): """Fixture for single product pricing override.""" return response.Response( message={ 'product_id': 123, 'product_pricing_override_id': 1 }, status=200) @pytest.fixture def fixture_second_product_pricing_override(): """Fixture for single product pricing override.""" return response.Response( message={ 'product_id': 123, 'product_pricing_override_id': 2 }, status=200) @pytest.fixture def fixture_products(): """Fixture for products.""" return response.Response( message={ 'items': [ { 'product_id': 123, 'upc': 456, 'product_type': 'Music', 'product_name': 'Test', 'context_type': 'Test', 'vendor_id': 1, 'subaccount_id': 2, 'release_date': '01-01-2000' } ] }, status=200) @pytest.fixture def fixture_found_overrides(): """Fixture for found overrides.""" return response.Response( message={ 'items': [ { 'product_id': 123, 'product_pricing_override_id': 1, 'pricing_family_id': 1, 'sort_order': 2, 'price_code': '100', 'applies_worldwide': True, 'include_territory_list': False } ] }, status=200) @pytest.fixture def fixture_found_overrides_with_wrong_sort_order(): """Fixture for found overrides with wrong sort order value.""" return response.Response( message={ 'items': [ { 'product_id': 123, 'product_pricing_override_id': 1, 'pricing_family_id': 1, 'sort_order': 0, 'price_code': '100', 'applies_worldwide': True, 'include_territory_list': False } ] }, status=200) @pytest.fixture def fixture_found_overrides_with_mixed_sort_order(): """Fixture for found overrides with mixed sort order value.""" return response.Response( message={ 'items': [ { 'product_id': 123, 'product_pricing_override_id': 1, 'pricing_family_id': 1, 'sort_order': 0, 'price_code': '100', 'applies_worldwide': True, 'include_territory_list': False }, { 'product_id': 123, 'product_pricing_override_id': 2, 'pricing_family_id': 1, 'sort_order': 1, 'price_code': '100', 'applies_worldwide': True, 'include_territory_list': False } ] }, status=200) def test_bulk_update_products( monkeypatch, fixture_product_orchard_pricing_tier, fixture_product_pricing_override, fixture_success, fixture_products, fixture_found_overrides): """Test bulk updating pricing products.""" monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_product_orchard_pricing_tier)) 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_success)) monkeypatch.setattr( product, 'get_product_ids_from_upcs', MagicMock(return_value=fixture_products)) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=fixture_found_overrides)) monkeypatch.setattr( legacy_product_mapping, 'jit_music_migration', MagicMock(return_value=fixture_success)) data = { 'upcs': ['456'], 'payload': { 'product_pricing_overrides': [ { 'pricing_family_id': 1, 'sort_order': 2, 'price_code': '100', 'include_territory_list': False } ], 'default_pricing': { 'pricing_family_id': 1, 'orchard_pricing_tier_id': 2 } } } expected_result = { 'successes': [ { 'upc': 456, 'default_tier': { 'orchard_pricing_tier_id': 2, 'product_orchard_pricing_tier_id': 1 } }, { 'upc': 456, 'override': { 'product_id': 123, 'product_pricing_override_id': 1 } } ], 'failures': [] } result = bulk_product_update.bulk_update_products(data) assert result assert result.message == expected_result assert legacy_product_mapping.jit_music_migration.called def test_bulk_update_products_with_wrong_upcs( monkeypatch, fixture_product_orchard_pricing_tier, fixture_product_pricing_override, fixture_success, fixture_products, fixture_found_overrides): """Test bulk updating pricing products.""" monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_product_orchard_pricing_tier)) 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_success)) monkeypatch.setattr( product, 'get_product_ids_from_upcs', MagicMock(return_value=fixture_products)) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=fixture_found_overrides)) monkeypatch.setattr( legacy_product_mapping, 'jit_music_migration', MagicMock(return_value=fixture_success)) data = { 'upcs': ['123', '456'], 'payload': { 'product_pricing_overrides': [ { 'pricing_family_id': 1, 'sort_order': 2, 'price_code': '100', 'include_territory_list': False } ], 'default_pricing': { 'pricing_family_id': 1, 'orchard_pricing_tier_id': 2 } } } expected_result = { 'successes': [ { 'upc': 456, 'default_tier': { 'orchard_pricing_tier_id': 2, 'product_orchard_pricing_tier_id': 1 } }, { 'upc': 456, 'override': { 'product_id': 123, 'product_pricing_override_id': 1 } } ], 'failures': [ { 'upc': 123, 'default_tier': 'Invalid UPC' }, { 'upc': 123, 'override': 'Invalid UPC' } ] } result = bulk_product_update.bulk_update_products(data) assert result assert result.message == expected_result assert legacy_product_mapping.jit_music_migration.called def test_bulk_update_products_without_upcs( monkeypatch, fixture_product_orchard_pricing_tier, fixture_product_pricing_override, fixture_success): """Test bulk updating pricing products.""" monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_product_orchard_pricing_tier)) monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) data = { 'payload': { 'product_pricing_overrides': [ { 'pricing_family_id': 1, 'sort_order': 2, 'price_code': '100', 'applies_worldwide': True, 'include_territory_list': False } ], 'default_pricing': { 'pricing_family_id': 1, 'orchard_pricing_tier_id': 2 } } } expected_result = fixture_empty_body_helper() result = bulk_product_update.bulk_update_products(data) assert result.status == expected_result.status assert result.message == expected_result.message def test_bulk_update_products_with_multiple_overrides( monkeypatch, fixture_product_orchard_pricing_tier, fixture_product_pricing_override, fixture_second_product_pricing_override, fixture_success, fixture_products, fixture_found_overrides): """Test bulk updating pricing products.""" def create_override_side_effect(product_id, data): if data['sort_order'] == 1: return fixture_product_pricing_override return fixture_second_product_pricing_override monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_product_orchard_pricing_tier)) monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(side_effect=create_override_side_effect)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=fixture_found_overrides)) monkeypatch.setattr( product_pricing_override, 'update_product_pricing_override', MagicMock(return_value=fixture_success)) monkeypatch.setattr( legacy_product_mapping, 'jit_music_migration', MagicMock(return_value=fixture_success)) monkeypatch.setattr( product, 'get_product_ids_from_upcs', MagicMock(return_value=fixture_products)) data = { 'upcs': ['456'], 'payload': { 'product_pricing_overrides': [ { 'pricing_family_id': 1, 'sort_order': 1, 'price_code': '100', 'applies_worldwide': True, 'include_territory_list': False }, { 'pricing_family_id': 1, 'sort_order': 2, 'price_code': '200', 'applies_worldwide': True, 'include_territory_list': False } ] } } expected_result = { 'successes': [ { 'upc': 456, 'override': { 'product_id': 123, 'product_pricing_override_id': 1 } }, { 'upc': 456, 'override': { 'product_id': 123, 'product_pricing_override_id': 2 } } ], 'failures': [] } result = bulk_product_update.bulk_update_products(data) assert result.status == 200 assert result.message == expected_result assert legacy_product_mapping.jit_music_migration.called def test_bulk_update_products_without_payload( monkeypatch, fixture_product_orchard_pricing_tier, fixture_product_pricing_override): """Test bulk updating pricing products.""" monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_product_orchard_pricing_tier)) monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) data = { 'upcs': ['456'] } expected_result = fixture_empty_body_helper() result = bulk_product_update.bulk_update_products(data) assert result.status == expected_result.status assert result.message == expected_result.message def test_bulk_update_products_without_default_tier_and_overrides( monkeypatch, fixture_product_orchard_pricing_tier, fixture_product_pricing_override): """Test bulk updating pricing products.""" monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_product_orchard_pricing_tier)) monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_product_pricing_override)) monkeypatch.setattr( product_pricing_override, 'has_duplicate', MagicMock(return_value=False)) data = { 'upcs': ['456'], 'payload': { } } expected_result = fixture_empty_body_helper() result = bulk_product_update.bulk_update_products(data) assert result.status == expected_result.status assert result.message == expected_result.message def test_bulk_update_products_with_failures( monkeypatch, fixture_error, fixture_success, fixture_products, fixture_found_overrides): """Test bulk updating pricing products.""" monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_error)) monkeypatch.setattr( product_pricing_override, 'create_product_pricing_override', MagicMock(return_value=fixture_error)) monkeypatch.setattr( product_pricing_override, 'update_product_pricing_override', MagicMock(return_value=fixture_success)) monkeypatch.setattr( product, 'get_product_ids_from_upcs', MagicMock(return_value=fixture_products)) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=fixture_found_overrides)) monkeypatch.setattr( legacy_product_mapping, 'jit_music_migration', MagicMock(return_value=fixture_success)) data = { 'upcs': ['456'], 'payload': { 'product_pricing_overrides': [ { 'pricing_family_id': 1, 'sort_order': 2, 'price_code': '100' } ], 'default_pricing': { 'pricing_family_id': 1, 'orchard_pricing_tier_id': 2 } } } expected_result = { 'successes': [], 'failures': [ { 'upc': 456, 'default_tier': {'code': 500, 'message': 'DB Error'} }, { 'upc': 456, 'override': {'code': 500, 'message': 'DB Error'} } ] } result = bulk_product_update.bulk_update_products(data) assert result assert result.message == expected_result assert legacy_product_mapping.jit_music_migration.called def test_bulk_update_products_with_wrong_sort_order( monkeypatch, fixture_product_orchard_pricing_tier, fixture_product_pricing_override, fixture_success, fixture_products, fixture_found_overrides_with_wrong_sort_order): """Test bulk updating pricing products with wrong sort_order value.""" monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_product_orchard_pricing_tier)) 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_success)) monkeypatch.setattr( product, 'get_product_ids_from_upcs', MagicMock(return_value=fixture_products)) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=fixture_found_overrides_with_wrong_sort_order)) monkeypatch.setattr( legacy_product_mapping, 'jit_music_migration', MagicMock(return_value=fixture_success)) data = { 'upcs': ['456'], 'payload': { 'product_pricing_overrides': [ { 'pricing_family_id': 1, 'sort_order': 1, 'price_code': '100', 'include_territory_list': False } ] } } bulk_product_update.bulk_update_products(data) calls = product_pricing_override.\ update_product_pricing_override.call_args_list expected_calls = [call(123, 1, {'sort_order': 2})] assert len(calls) == 1 assert calls == expected_calls assert legacy_product_mapping.jit_music_migration.called def test_bulk_update_products_with_mixed_sort_order( monkeypatch, fixture_product_orchard_pricing_tier, fixture_product_pricing_override, fixture_success, fixture_products, fixture_found_overrides_with_mixed_sort_order): """Test bulk updating pricing products with mixed sort_order value.""" monkeypatch.setattr( product_orchard_pricing_tier, 'update_product_with_orchard_pricing_tier', MagicMock(return_value=fixture_product_orchard_pricing_tier)) 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_success)) monkeypatch.setattr( product, 'get_product_ids_from_upcs', MagicMock(return_value=fixture_products)) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=fixture_found_overrides_with_mixed_sort_order)) monkeypatch.setattr( legacy_product_mapping, 'jit_music_migration', MagicMock(return_value=fixture_success)) data = { 'upcs': ['456'], 'payload': { 'product_pricing_overrides': [ { 'pricing_family_id': 1, 'sort_order': 1, 'price_code': '100', 'include_territory_list': False } ] } } bulk_product_update.bulk_update_products(data) calls = product_pricing_override.\ update_product_pricing_override.call_args_list expected_data = { 'sort_order': 2, 'pricing_family_id': 1 } expected_calls = [call(123, 2, expected_data), call( 123, 1, {'sort_order': 3})] assert len(calls) == 2 assert calls == expected_calls assert legacy_product_mapping.jit_music_migration.called