from unittest.mock import MagicMock from pricing.constants.warning import WARNING_ALBUM_PREORDER_PRICE_SUM_OF_IGS, WARNING_ALBUM_PREORDER_PRICE_SUM_OF_TRACKS from pricing.logic.product_pricing_validator import _validate_album_price_is_less_than_sum_of_track_prices from pricing.logic.product_pricing_validator import _validate_album_price_is_greater_than_sum_of_ig_tracks from pricing.logic.product_pricing_validator import _get_album_override_prices from pricing.logic.product_pricing_validator import _get_highest_album_price from pricing.logic.product_pricing_validator import _get_track_override_prices from pricing.logic.product_pricing_validator import _get_ig_track_prices from pricing.logic.product_pricing_validator import validate_product_by_id from pricing.models import orchard_pricing_tier_value as orchard_pricing_tier_value_model, ows_track, product_pricing_override from pricing.logic import track_pricing_override import pytest @pytest.fixture def fixture_pricing_tier_value(): """Fixture for pricing tier value.""" return 99 @pytest.fixture def fixture_product_override_pricing_tier_value(): """Fixture for pricing tier value.""" return 1599 @pytest.fixture def fixture_track_override_pricing_tier_value(): """Fixture for pricing tier value.""" return 49 def test_validate_album_price_is_less_than_sum_of_track_prices(): """Test that the album price is strictly lower than the sum of the individual prices of all tracks.""" assert _validate_album_price_is_less_than_sum_of_track_prices(1399, 99, 15, []) is True assert _validate_album_price_is_less_than_sum_of_track_prices(1399, 99, 15, [10]) is False assert _validate_album_price_is_less_than_sum_of_track_prices(1399, 99, 15, [199]) is True assert _validate_album_price_is_less_than_sum_of_track_prices(1399, 99, 15, [199, 10, 10]) is True assert _validate_album_price_is_less_than_sum_of_track_prices(1399, 99, 15, [199, 10, 10, 10]) is False def test_validate_album_price_is_greater_than_sum_of_ig_tracks(monkeypatch, fixture_pricing_tier_value): """Test that the album price is greater than the sum of the instant grat track prices plus one mid-tier track.""" monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_value_by_tier_id', MagicMock(return_value=fixture_pricing_tier_value)) assert _validate_album_price_is_greater_than_sum_of_ig_tracks(1399, [99, 99]) is True assert _validate_album_price_is_greater_than_sum_of_ig_tracks(399, [99, 99, 99, 99]) is False assert _validate_album_price_is_greater_than_sum_of_ig_tracks(495, [99, 99, 99, 99]) is True assert _validate_album_price_is_greater_than_sum_of_ig_tracks(496, [99, 99, 99, 99]) is True def test_get_album_override_prices(monkeypatch, fixture_product_override_pricing_tier_value): """Test getting the prices for any album overrides""" mock_overrides = [ { "product_pricing_override_id": 1, "orchard_pricing_tier_id": 15, }, { "product_pricing_override_id": 2, "orchard_pricing_tier_id": 15, } ] monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_values_by_tier_id', MagicMock(return_value=[fixture_product_override_pricing_tier_value, fixture_product_override_pricing_tier_value])) assert _get_album_override_prices(mock_overrides) == [1599, 1599] assert _get_album_override_prices([]) == [] def test_get_highest_album_price(): """Test getting the highest album price""" assert _get_highest_album_price(1399, [1499, 1599]) == 1599 assert _get_highest_album_price(1699, [1499, 1599]) == 1699 def test_get_track_override_prices(monkeypatch, fixture_track_override_pricing_tier_value): """Test getting the prices for any track overrides""" mock_overrides = [ { "product_pricing_override_id": 1, "orchard_pricing_tier_id": 15, "track_id": 1, }, { "product_pricing_override_id": 2, "orchard_pricing_tier_id": 15, "track_id": 2, } ] monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_value_by_tier_id', MagicMock(return_value=fixture_track_override_pricing_tier_value)) assert _get_track_override_prices(mock_overrides) == {1: 49, 2: 49} assert _get_track_override_prices([]) == {} def test_get_ig_track_prices(): mock_ig_tracks = [{'tuid': 1}, {'tuid': 2}] mock_track_override_prices = {2: 49} assert _get_ig_track_prices(mock_ig_tracks, 99, mock_track_override_prices) == [99, 49] def test_validate_product_by_id_valid(monkeypatch, fixture_product_override_pricing_tier_value, fixture_track_override_pricing_tier_value): """Test validating a product by id""" mock_product_id = 123 mock_default_album_price_cents = 1199 mock_default_track_price_cents = 99 mock_number_of_tracks = 15 mock_album_overrides = [] mock_track_overrides = [ { "product_pricing_override_id": 1, "orchard_pricing_tier_id": 15, "track_id": 1, }, { "product_pricing_override_id": 2, "orchard_pricing_tier_id": 15, "track_id": 2, } ] monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_album_price_cents_by_product_id', MagicMock(return_value=mock_default_album_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_track_price_cents_by_product_id', MagicMock(return_value=mock_default_track_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_value_by_tier_id', MagicMock(side_effect=[fixture_product_override_pricing_tier_value, fixture_product_override_pricing_tier_value, fixture_track_override_pricing_tier_value, fixture_track_override_pricing_tier_value])) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=MagicMock(message={'items': mock_album_overrides}))) monkeypatch.setattr( track_pricing_override, 'get_track_pricing_overrides_for_product', MagicMock(return_value=MagicMock(message={ 'items': mock_track_overrides, 'total_track_count': mock_number_of_tracks}))) monkeypatch.setattr( ows_track, 'get_ig_tracks_by_product_id', MagicMock(return_value=MagicMock(message={"code": "not_found_error"}))) result = validate_product_by_id(mock_product_id) assert result.message['valid'] is True assert result.message['warnings'] == [] def test_validate_product_by_id_valid_with_no_pricing_data(monkeypatch, fixture_product_override_pricing_tier_value, fixture_track_override_pricing_tier_value): """Test validating a product by id""" mock_product_id = 123 mock_default_album_price_cents = None mock_default_track_price_cents = None mock_number_of_tracks = 15 mock_album_overrides = [] mock_track_overrides = [ { "product_pricing_override_id": 1, "orchard_pricing_tier_id": 15, "track_id": 1, }, { "product_pricing_override_id": 2, "orchard_pricing_tier_id": 15, "track_id": 2, } ] monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_album_price_cents_by_product_id', MagicMock(return_value=mock_default_album_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_track_price_cents_by_product_id', MagicMock(return_value=mock_default_track_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_value_by_tier_id', MagicMock(side_effect=[fixture_product_override_pricing_tier_value, fixture_product_override_pricing_tier_value, fixture_track_override_pricing_tier_value, fixture_track_override_pricing_tier_value])) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=MagicMock(message={'items': mock_album_overrides}))) monkeypatch.setattr( track_pricing_override, 'get_track_pricing_overrides_for_product', MagicMock(return_value=MagicMock(message={ 'items': mock_track_overrides, 'total_track_count': mock_number_of_tracks}))) monkeypatch.setattr( ows_track, 'get_ig_tracks_by_product_id', MagicMock(return_value=MagicMock(message={"code": "not_found_error"}))) result = validate_product_by_id(mock_product_id) assert result.message['valid'] is True assert result.message['warnings'] == [] def test_validate_product_by_id_invalid(monkeypatch, fixture_product_override_pricing_tier_value, fixture_track_override_pricing_tier_value): """Test validating a product by id""" mock_product_id = 123 mock_default_album_price_cents = 1199 mock_default_track_price_cents = 99 mock_number_of_tracks = 15 mock_album_overrides = [ { "product_pricing_override_id": 1, "orchard_pricing_tier_id": 15, "pricing_family_id": 2, }, { "product_pricing_override_id": 2, "orchard_pricing_tier_id": 15, "pricing_family_id": 2, } ] mock_track_overrides = [ { "product_pricing_override_id": 1, "orchard_pricing_tier_id": 15, "track_id": 1, }, { "product_pricing_override_id": 2, "orchard_pricing_tier_id": 15, "track_id": 2, } ] monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_album_price_cents_by_product_id', MagicMock(return_value=mock_default_album_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_track_price_cents_by_product_id', MagicMock(return_value=mock_default_track_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_value_by_tier_id', MagicMock(side_effect=[fixture_track_override_pricing_tier_value, fixture_track_override_pricing_tier_value])) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_values_by_tier_id', MagicMock(return_value=[fixture_product_override_pricing_tier_value, fixture_product_override_pricing_tier_value])) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=MagicMock(message={'items': mock_album_overrides}))) monkeypatch.setattr( track_pricing_override, 'get_track_pricing_overrides_for_product', MagicMock(return_value=MagicMock(message={ 'items': mock_track_overrides, 'total_track_count': mock_number_of_tracks}))) monkeypatch.setattr( ows_track, 'get_ig_tracks_by_product_id', MagicMock(return_value=MagicMock(message={"code": "not_found_error"}))) result = validate_product_by_id(mock_product_id) assert result.message['valid'] is False assert result.message['warnings'][0]['warning_code'] == WARNING_ALBUM_PREORDER_PRICE_SUM_OF_TRACKS def test_validate_product_by_id_ig_valid(monkeypatch, fixture_pricing_tier_value): """Test validating a product by id""" mock_product_id = 123 mock_default_album_price_cents = 1199 mock_default_track_price_cents = 99 mock_number_of_tracks = 15 mock_album_overrides = [] mock_track_overrides = [] mock_ig_tracks = [{'tuid': 1}, {'tuid': 2}] monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_album_price_cents_by_product_id', MagicMock(return_value=mock_default_album_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_track_price_cents_by_product_id', MagicMock(return_value=mock_default_track_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_value_by_tier_id', MagicMock(side_effect=[fixture_pricing_tier_value])) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=MagicMock(message={'items': mock_album_overrides}))) monkeypatch.setattr( track_pricing_override, 'get_track_pricing_overrides_for_product', MagicMock(return_value=MagicMock(message={ 'items': mock_track_overrides, 'total_track_count': mock_number_of_tracks}))) monkeypatch.setattr( ows_track, 'get_ig_tracks_by_product_id', MagicMock(return_value=MagicMock(message={'items': mock_ig_tracks}))) result = validate_product_by_id(mock_product_id) assert result.message['valid'] is True assert result.message['warnings'] == [] def test_validate_product_by_id_ig_invalid(monkeypatch, fixture_product_override_pricing_tier_value, fixture_pricing_tier_value): """Test validating a product by id""" mock_product_id = 123 mock_default_album_price_cents = 1199 mock_default_track_price_cents = 99 mock_number_of_tracks = 15 mock_album_overrides = [] mock_track_overrides = [ { "product_pricing_override_id": 1, "orchard_pricing_tier_id": 15, "track_id": 1, }, { "product_pricing_override_id": 2, "orchard_pricing_tier_id": 15, "track_id": 2, } ] mock_ig_tracks = [{'tuid': 1}, {'tuid': 2}] monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_album_price_cents_by_product_id', MagicMock(return_value=mock_default_album_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_track_price_cents_by_product_id', MagicMock(return_value=mock_default_track_price_cents)) monkeypatch.setattr( orchard_pricing_tier_value_model, 'get_price_value_by_tier_id', MagicMock(side_effect=[fixture_product_override_pricing_tier_value, fixture_product_override_pricing_tier_value, fixture_pricing_tier_value])) monkeypatch.setattr( product_pricing_override, 'get_by_product_id', MagicMock(return_value=MagicMock(message={'items': mock_album_overrides}))) monkeypatch.setattr( track_pricing_override, 'get_track_pricing_overrides_for_product', MagicMock(return_value=MagicMock(message={ 'items': mock_track_overrides, 'total_track_count': mock_number_of_tracks}))) monkeypatch.setattr( ows_track, 'get_ig_tracks_by_product_id', MagicMock(return_value=MagicMock(message={'items': mock_ig_tracks}, status=200))) result = validate_product_by_id(mock_product_id) assert result.message['valid'] is False assert result.message['warnings'][0]['warning_code'] == WARNING_ALBUM_PREORDER_PRICE_SUM_OF_IGS