from datetime import datetime from typing import Any import pytest from syrupy.assertion import SnapshotAssertion from delivery_metadata.constants import ( DownloadStreamRights, StoreIds, TrackTypes, ) from delivery_metadata.models.delivery_rights import ( DeliveryRights, InstantGratRights, TerritoryPricing, TerritoryRights, _denormalize_end_date_inclusive, _denormalize_territory_rights_and_sort, _fabricate_instant_grat_end_dates_normalized, _format_and_normalize_instant_grat_data, _format_and_normalize_territory_pricing, _format_instant_grat_data, _format_territories_data, _generate_release_preorder_term_rights, _generate_sale_start_term_rights, _get_active_preorder_rights_with_instant_grats, _get_all_active_rights_with_pricing_intervals, _get_and_normalize_preorder_end_date, _get_splice_points, _merge_adjacent_rights, _merge_equal_rights, _normalize_end_date_exclusive, _normalize_start_date, _split_preorder_by_instant_grat_rights, _split_rights_terms_by_price, get_delivery_rights, get_product_delivery_rights, get_track_delivery_rights, ) from delivery_metadata.models.schemas import ( CustomPricing, DeliveryMetadata, ReleasePricing, Store, TerritoryCodeA2, TerritoryDates, ) from tests.unit.conftest import ( get_audio_track_mock_no_pricing_by_track_id, get_delivery_metadata_mock_by_store, get_store_mock, get_track_mock_no_pricing_by_track_id, update_mock_object, ) def test_get_delivery_rights_no_pricing( audio_delivery_rights_mock_no_pricing: DeliveryRights, ) -> None: store = get_store_mock( StoreIds.NO_STORE, [TrackTypes.MUSIC], {StoreIds.NO_STORE: {"is_preorder_supported": True}}, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_delivery_rights(delivery_metadata_mock) assert result == audio_delivery_rights_mock_no_pricing def test_get_delivery_rights_no_pricing_no_preorder( audio_delivery_rights_mock_no_pricing_no_preorder: DeliveryRights, ) -> None: store = get_store_mock( StoreIds.NO_STORE, [TrackTypes.MUSIC], ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_delivery_rights(delivery_metadata_mock) assert result == audio_delivery_rights_mock_no_pricing_no_preorder def test_get_delivery_rights_pricing( audio_delivery_rights_mock_with_pricing: DeliveryRights, ) -> None: store = get_store_mock( StoreIds.NO_STORE, [TrackTypes.MUSIC], { StoreIds.NO_STORE: { "is_pricing_supported": True, "is_preorder_supported": True, } }, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_delivery_rights(delivery_metadata_mock) assert result == audio_delivery_rights_mock_with_pricing def test_get_delivery_rights_pricing_no_preorder( audio_delivery_rights_mock_with_pricing_no_preorder: DeliveryRights, ) -> None: store = get_store_mock( StoreIds.NO_STORE, [TrackTypes.MUSIC], { StoreIds.NO_STORE: { "is_pricing_supported": True, } }, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_delivery_rights(delivery_metadata_mock) assert result == audio_delivery_rights_mock_with_pricing_no_preorder def test_get_delivery_rights_with_instant_grats_no_pricing( product_delivery_rights_mock_with_instant_grats_no_pricing: list[TerritoryRights], audio_tracks_delivery_rights_mock_with_instant_grats_no_pricing: dict[ int, list[TerritoryRights] ], ) -> None: store = update_mock_object( get_store_mock(StoreIds.NO_STORE, [TrackTypes.MUSIC]), Store, { "is_instant_gratification_supported": True, "is_preorder_supported": True, }, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_delivery_rights(delivery_metadata_mock) expected_result = DeliveryRights( product_rights=product_delivery_rights_mock_with_instant_grats_no_pricing, track_rights=audio_tracks_delivery_rights_mock_with_instant_grats_no_pricing, ) assert result == expected_result def test_get_product_delivery_rights_no_pricing( product_delivery_rights_mock_no_pricing: list[TerritoryRights], ) -> None: store = get_store_mock( StoreIds.NO_STORE, [TrackTypes.MUSIC], { StoreIds.NO_STORE: { "is_preorder_supported": True, } }, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_product_delivery_rights(delivery_metadata_mock) assert result == product_delivery_rights_mock_no_pricing def test_get_product_delivery_rights_with_pricing( product_delivery_rights_mock_with_pricing: list[TerritoryRights], ) -> None: store = get_store_mock( StoreIds.NO_STORE, [TrackTypes.MUSIC], { StoreIds.NO_STORE: { "is_pricing_supported": True, "is_preorder_supported": True, } }, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_product_delivery_rights(delivery_metadata_mock) assert result == product_delivery_rights_mock_with_pricing def test_get_product_delivery_rights_with_instant_grats_no_pricing( product_delivery_rights_mock_with_instant_grats_no_pricing: list[TerritoryRights], ) -> None: store = update_mock_object( get_store_mock(StoreIds.NO_STORE, [TrackTypes.MUSIC]), Store, { "is_instant_gratification_supported": True, "is_preorder_supported": True, }, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_product_delivery_rights(delivery_metadata_mock) assert result == product_delivery_rights_mock_with_instant_grats_no_pricing def test_get_track_delivery_rights_no_pricing( delivery_metadata_mock: DeliveryMetadata, audio_tracks_delivery_rights_mock_no_pricing: dict[int, list[TerritoryRights]], ) -> None: result = get_track_delivery_rights(delivery_metadata_mock) assert result == audio_tracks_delivery_rights_mock_no_pricing def test_get_track_delivery_rights_with_pricing( audio_tracks_delivery_rights_mock_with_pricing: dict[int, list[TerritoryRights]], ) -> None: store = get_store_mock( StoreIds.NO_STORE, [TrackTypes.MUSIC], {StoreIds.NO_STORE: {"is_pricing_supported": True}}, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_track_delivery_rights(delivery_metadata_mock) assert result == audio_tracks_delivery_rights_mock_with_pricing def test_get_track_delivery_rights_with_instant_grats_no_pricing( audio_tracks_delivery_rights_mock_with_instant_grats_no_pricing: dict[ int, list[TerritoryRights] ], ) -> None: store = update_mock_object( get_store_mock(StoreIds.NO_STORE, [TrackTypes.MUSIC]), Store, { "is_instant_gratification_supported": True, "is_preorder_supported": True, }, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) result = get_track_delivery_rights(delivery_metadata_mock) assert result == audio_tracks_delivery_rights_mock_with_instant_grats_no_pricing @pytest.mark.parametrize( "expected_preorder_term_rights, delivery_metadata_mock_updates", [ ( # Exclude territory date with start date == preorder_date (US is excluded) [ TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], {}, ), ( # Territory date with start date before sale_start_date and after preorder_date [ TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 11), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], { "product.territory_dates": [ TerritoryDates( country_code="US", country_release_date="2024-08-11", country_sale_start_date="2024-08-11", country_preorder_date="2024-08-08", ), ] }, ), ( # Territory date with start date after sale_start_date [ TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 19), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], { "product.territory_dates": [ TerritoryDates( country_code="US", country_release_date="2024-08-11", country_sale_start_date="2024-08-19", country_preorder_date="2024-08-08", ), ] }, ), ( # Exclude territory date with start date < preorder_date (US is excluded) [ TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], { "product.territory_dates": [ TerritoryDates( country_code="US", country_release_date="2024-08-11", country_sale_start_date="2024-08-08", country_preorder_date="2024-08-08", ), ] }, ), ], ) def test__generate_release_preorder_term_rights( expected_preorder_term_rights: list[TerritoryRights], delivery_metadata_mock_updates: dict[str, Any], delivery_metadata_mock: DeliveryMetadata, ) -> None: updated_delivery_metadata_mock = update_mock_object( delivery_metadata_mock, DeliveryMetadata, delivery_metadata_mock_updates ) result = _generate_release_preorder_term_rights(updated_delivery_metadata_mock) assert result == expected_preorder_term_rights @pytest.mark.parametrize( "territory_mock, expected_result", [ ("AT", datetime(2024, 8, 12)), ("FR", datetime(2024, 8, 12)), ], ) def test__get_and_normalize_preorder_end_date( territory_mock: str, expected_result: datetime, delivery_metadata_mock: DeliveryMetadata, ) -> None: result = _get_and_normalize_preorder_end_date( delivery_metadata_mock, territory_mock ) assert result == expected_result @pytest.mark.parametrize( "mock_root_preorder_list, mock_instant_grats", [ pytest.param( [ # No instant grat rights TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], [], id="no_instant_grat_rights", ), pytest.param( [ # Simple preorder list TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), ), InstantGratRights( tuids={12345, 12347}, start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), ), InstantGratRights( tuids={12345, 12347, 12348}, start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 12), ), ], id="simple_preorder_list", ), pytest.param( [ # Complex preorder list TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 19), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 11), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), ), InstantGratRights( tuids={12345, 12347}, start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), ), InstantGratRights( tuids={12345, 12347, 12348}, start_date=datetime(2024, 8, 10), end_date=datetime.max, ), ], id="complex_preorder_list", ), pytest.param( [ # Preorder US end date on grat start date TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 19), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 10), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), ), InstantGratRights( tuids={12345, 12347}, start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), ), InstantGratRights( tuids={12345, 12347, 12348}, start_date=datetime(2024, 8, 10), end_date=datetime.max, ), ], id="preorder_us_end_date_on_grat_start_date", ), pytest.param( [ # Preorder ending for US before grat start date TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 19), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 3), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), ), InstantGratRights( tuids={12345, 12347}, start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), ), InstantGratRights( tuids={12345, 12347, 12348}, start_date=datetime(2024, 8, 10), end_date=datetime.max, ), ], id="preorder_ending_for_us_before_grat_start_date", ), ], ) def test__split_preorder_by_instant_grat_rights( mock_root_preorder_list: list[TerritoryRights], mock_instant_grats: list[InstantGratRights], snapshot: SnapshotAssertion, ) -> None: result = _split_preorder_by_instant_grat_rights( mock_root_preorder_list, mock_instant_grats ) assert result == snapshot @pytest.mark.parametrize( "store_id_mock, track_types_mock", [ pytest.param( StoreIds.AMAZON, [TrackTypes.MUSIC], id="amazon_music", ), ], ) def test__format_and_normalize_instant_grat_data( store_id_mock: int, track_types_mock: list[TrackTypes], snapshot: SnapshotAssertion, ) -> None: mock_store = get_store_mock(store_id_mock, track_types_mock) delivery_metadata_mock = get_delivery_metadata_mock_by_store( mock_store, track_types_mock ) result = _format_and_normalize_instant_grat_data(delivery_metadata_mock) assert result == snapshot @pytest.mark.parametrize( "root_preorder_list_mock, instant_grats_mock, expected_rights", [ ( [ # Simple preorder list TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), ), InstantGratRights( tuids={12345, 12347}, start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), ), InstantGratRights( tuids={12345, 12347, 12348}, start_date=datetime(2024, 8, 10), end_date=datetime.max, ), ], [ TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 4), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks=None, ), TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345}, ), TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347}, ), TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347, 12348}, ), ], ), ( [ # Complex preorder list TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 19), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 11), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), ), InstantGratRights( tuids={12345, 12347}, start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), ), InstantGratRights( tuids={12345, 12347, 12348}, start_date=datetime(2024, 8, 10), end_date=datetime.max, ), ], [ TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 4), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks=None, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 4), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks=None, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 1), end_date=datetime(2024, 8, 4), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks=None, ), TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345}, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345}, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 4), end_date=datetime(2024, 8, 7), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345}, ), TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347}, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347}, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 7), end_date=datetime(2024, 8, 10), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347}, ), TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 11), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347, 12348}, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 11), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347, 12348}, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 11), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347, 12348}, ), TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 11), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347, 12348}, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 11), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347, 12348}, ), TerritoryRights( territories=["CA", "FR"], start_date=datetime(2024, 8, 12), end_date=datetime(2024, 8, 19), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, instant_gratification_tracks={12345, 12347, 12348}, ), ], ), ], ) def test__get_active_preorder_rights_with_instant_grats( root_preorder_list_mock: list[TerritoryRights], instant_grats_mock: list[InstantGratRights], expected_rights: list[TerritoryRights], ) -> None: result = _get_active_preorder_rights_with_instant_grats( root_preorder_list_mock, instant_grats_mock ) assert result == expected_rights @pytest.mark.parametrize( "expected_instant_grat_rights", [ ( [ { "tuids": {12345}, "start_date": datetime(2024, 8, 10), }, { "tuids": {12349}, "start_date": datetime(2024, 8, 11), }, ] ), ], ) def test__format_instant_grat_data( expected_instant_grat_rights: list[dict[str, Any]], ) -> None: store_mock = get_store_mock(StoreIds.AMAZON, [TrackTypes.MUSIC]) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store_mock, [TrackTypes.MUSIC] ) result = _format_instant_grat_data(delivery_metadata_mock) assert result == expected_instant_grat_rights @pytest.mark.parametrize( "instant_grats_mock, expected_instant_grat_rights", [ ( [ { "tuids": {12345}, "start_date": datetime(2024, 8, 10), }, { "tuids": {12349}, "start_date": datetime(2024, 8, 11), }, ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 11), ), InstantGratRights( tuids={12345, 12349}, start_date=datetime(2024, 8, 11), end_date=datetime.max, ), ], ), ( [ { "tuids": {12345}, "start_date": datetime(2024, 8, 10), }, ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 10), end_date=datetime.max, ), ], ), ( [ { "tuids": {12345}, "start_date": datetime(2024, 8, 10), }, { "tuids": {12349}, "start_date": datetime(2024, 8, 11), }, { "tuids": {123410}, "start_date": datetime(2024, 8, 13), }, ], [ InstantGratRights( tuids={12345}, start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 11), ), InstantGratRights( tuids={12345, 12349}, start_date=datetime(2024, 8, 11), end_date=datetime(2024, 8, 13), ), InstantGratRights( tuids={12345, 12349, 123410}, start_date=datetime(2024, 8, 13), end_date=datetime.max, ), ], ), ], ) def test__fabricate_instant_grat_end_dates_normalized( instant_grats_mock: list[dict[str, Any]], expected_instant_grat_rights: list[InstantGratRights], ) -> None: result = _fabricate_instant_grat_end_dates_normalized( instant_grats_mock, ) assert result == expected_instant_grat_rights @pytest.mark.parametrize( "delivery_metadata_mock_updates", [ pytest.param({}, id="start_date_eq_preorder_date"), pytest.param( { "product.territory_dates": [ TerritoryDates( country_code="US", country_release_date="2024-08-11", country_sale_start_date="2024-08-08", country_preorder_date="2024-08-08", ), ] }, id="start_date_lt_preorder_date", ), pytest.param( { "product.territory_dates": [ TerritoryDates( country_code="US", country_release_date="2024-08-11", country_sale_start_date="2024-08-19", country_preorder_date="2024-08-08", ), ] }, id="start_date_gt_sale_start_date", ), ], ) def test__generate_sale_start_term_rights_product_level( delivery_metadata_mock_updates: dict[str, Any], delivery_metadata_mock: DeliveryMetadata, snapshot: SnapshotAssertion, ) -> None: updated_delivery_metadata_mock = update_mock_object( delivery_metadata_mock, DeliveryMetadata, delivery_metadata_mock_updates ) result = _generate_sale_start_term_rights(updated_delivery_metadata_mock) assert result == snapshot @pytest.mark.parametrize( ("delivery_metadata_mock_updates", "mock_track_id", "store_id"), [ pytest.param({}, 12349, StoreIds.NO_STORE, id="start_date_eq_preorder_date"), pytest.param( { "product.territory_dates": [ TerritoryDates( country_code="US", country_release_date="2024-08-11", country_sale_start_date="2024-08-08", country_preorder_date="2024-08-08", ), ] }, 12349, StoreIds.NO_STORE, id="start_date_lt_preorder_date", ), pytest.param( { "product.territory_dates": [ TerritoryDates( country_code="US", country_release_date="2024-08-11", country_sale_start_date="2024-08-19", country_preorder_date="2024-08-08", ), ], }, 12349, StoreIds.NO_STORE, id="start_date_gt_sale_start_date", ), pytest.param( {}, 12349, StoreIds.AMAZON, id="instant_grat_track_affecting_sale_start_amazon", ), ], ) def test__generate_sale_start_term_rights_track_level( delivery_metadata_mock_updates: dict[str, Any], mock_track_id: int, store_id: int, snapshot: SnapshotAssertion, ) -> None: store = get_store_mock( store_id, [TrackTypes.MUSIC], {store_id: {"is_preorder_supported": True}}, ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC] ) updated_delivery_metadata_mock = update_mock_object( delivery_metadata_mock, DeliveryMetadata, delivery_metadata_mock_updates ) mock_track = get_audio_track_mock_no_pricing_by_track_id(mock_track_id, store) result = _generate_sale_start_term_rights( updated_delivery_metadata_mock, mock_track ) assert result == snapshot @pytest.mark.parametrize( "normalized_territory_rights_mock", [ pytest.param( [ TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 12), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["AT", "BE", "CA", "FR"], start_date=datetime(2024, 8, 10), end_date=datetime(2024, 8, 12), price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=True, ), TerritoryRights( territories=["US"], start_date=datetime(2024, 8, 10), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], id="preorder_and_release_no_pricing", ), pytest.param( [ TerritoryRights( territories=["AT", "BE"], start_date=datetime(2024, 8, 12), end_date=datetime.max, price_code="3", custom_price=CustomPricing( custom_price="1.99", custom_currency_code="EUR", ), distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["AT", "BE"], start_date=datetime(2023, 1, 1), end_date=datetime(2024, 8, 12), price_code="3", custom_price=CustomPricing( custom_price="1.29", custom_currency_code="EUR", ), distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["AT", "BE"], start_date=datetime(1999, 1, 1), end_date=datetime(2023, 1, 1), price_code="3", custom_price=CustomPricing( custom_price="0.99", custom_currency_code="EUR", ), distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], id="multiple_price_windows", ), ], ) def test__denormalize_territory_rights_and_sort( normalized_territory_rights_mock: list[TerritoryRights], snapshot: SnapshotAssertion, ) -> None: result = _denormalize_territory_rights_and_sort(normalized_territory_rights_mock) assert result == snapshot @pytest.mark.parametrize( "mock_territory_rights_list, mock_pricing", [ pytest.param( [ TerritoryRights( territories=["MX", "CA"], start_date=datetime(2026, 2, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["PE"], start_date=datetime(2026, 4, 22), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date="2026-05-31", ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-06-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date="2026-02-01", end_date="2026-04-21", ), ReleasePricing( price_code="1", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date="2026-04-22", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date="2026-02-01", end_date=None, ), ReleasePricing( price_code="1", country_code=TerritoryCodeA2( country_code="PE", ), custom_pricing=None, start_date="2026-04-22", end_date=None, ), }, id="mix_price_codes_dates", ), pytest.param( [ TerritoryRights( territories=["US", "MX", "CA", "FR"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="FR", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), }, id="same_price_no_end_date", ), pytest.param( [ TerritoryRights( territories=["CA", "FR", "MX", "US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["SP", "IT"], start_date=datetime(2026, 2, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="1", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="FR", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="SP", ), custom_pricing=None, start_date="2026-02-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="IT", ), custom_pricing=None, start_date="2026-02-01", end_date=None, ), }, id="two_starts_diff_prices", ), pytest.param( [ TerritoryRights( territories=["US", "CA"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2027-01-01", end_date=None, ), ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), }, id="fabricate_end_dates", ), pytest.param( [ TerritoryRights( territories=["CA", "FR", "MX", "US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="FR", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date=None, end_date=None, ), }, id="mixed_pricing_dates", ), pytest.param( [ TerritoryRights( territories=["CA", "FR", "MX", "US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["BR"], start_date=datetime(2026, 2, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="FR", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="BR", ), custom_pricing=None, start_date=None, end_date=None, ), }, id="no_pricing_dates", ), pytest.param( [ TerritoryRights( territories=["CA", "FR", "MX", "US", "BR", "IT", "SP"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="BR", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="FR", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="IT", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="SP", ), custom_pricing=None, start_date=None, end_date=None, ), }, id="single_price_all_territories", ), pytest.param( [ TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date="2026-12-31", ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2027-01-01", end_date=None, ), }, id="one_territory_multi_prices", ), pytest.param( [ TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), }, id="single_territory_single_price", ), ], ) def test__split_rights_terms_by_price( mock_territory_rights_list: list[TerritoryRights], mock_pricing: set[ReleasePricing], snapshot: SnapshotAssertion, ) -> None: result = _split_rights_terms_by_price(mock_territory_rights_list, mock_pricing) assert result == snapshot @pytest.mark.parametrize( "mock_territory_rights_list, mock_pricing, expected_intervals", [ ( # Normal mix of different price codes, start/end dates [ TerritoryRights( territories=["CA", "FR", "MX", "US"], start_date=datetime(2026, 1, 1), end_date=None, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["BR"], start_date=datetime(2026, 2, 1), end_date=None, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="4L", country_code=TerritoryCodeA2( country_code="BR", ), custom_pricing=None, start_date="2026-02-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date="2026-01-01", end_date="2026-03-16", ), ReleasePricing( price_code="1", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date="2026-03-17", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="FR", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), }, [ TerritoryRights( territories=["CA"], start_date=datetime(2026, 1, 1), end_date=datetime(2026, 2, 1), price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["FR", "MX", "US"], start_date=datetime(2026, 1, 1), end_date=datetime(2026, 2, 1), price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["CA"], start_date=datetime(2026, 2, 1), end_date=datetime(2026, 3, 17), price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["FR", "MX", "US"], start_date=datetime(2026, 2, 1), end_date=datetime(2026, 3, 17), price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["BR"], start_date=datetime(2026, 2, 1), end_date=datetime(2026, 3, 17), price_code="4L", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["FR", "MX", "US"], start_date=datetime(2026, 3, 17), end_date=datetime.max, price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["CA"], start_date=datetime(2026, 3, 17), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["BR"], start_date=datetime(2026, 3, 17), end_date=datetime.max, price_code="4L", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], ), ( # One territory, different pricing [ TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=None, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date="2026-12-31", ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2027-01-01", end_date="2027-12-31", ), ReleasePricing( price_code="1", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2028-01-01", end_date=None, ), }, [ TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=datetime(2027, 1, 1), price_code="3", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["US"], start_date=datetime(2027, 1, 1), end_date=datetime(2028, 1, 1), price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["US"], start_date=datetime(2028, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], ), ( # One territory, one price (no splits needed) [ TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=None, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2026-01-01", end_date=None, ), }, [ TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code="3", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], ), ], ) def test__get_all_active_rights_with_pricing_intervals( mock_territory_rights_list: list[TerritoryRights], mock_pricing: set[ReleasePricing], expected_intervals: list[TerritoryRights], ) -> None: result = _get_all_active_rights_with_pricing_intervals( mock_territory_rights_list, mock_pricing ) assert result == expected_intervals @pytest.mark.parametrize( "mock_territory_rights_list, mock_pricing, mock_instant_grats", [ pytest.param( [ TerritoryRights( territories=["CA", "FR", "US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], [ TerritoryPricing( territories={"FR", "US"}, start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code="2", custom_price=None, ), TerritoryPricing( territories={"CA"}, start_date=datetime(2026, 1, 1), end_date=datetime(2026, 3, 17), price_code="2", custom_price=None, ), TerritoryPricing( territories={"CA"}, start_date=datetime(2026, 3, 17), end_date=None, price_code="2", custom_price=None, ), ], None, id="normal_mix_of_different_price_codes_startend_dates", ), pytest.param( [ TerritoryRights( territories=["CA", "FR", "US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code=None, custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], [ TerritoryPricing( territories={"FR", "US", "CA"}, start_date=datetime.min, end_date=datetime.max, price_code="2", custom_price=None, ), ], None, id="single_territory_pricing_no_instant_grats", ), ], ) def test__get_splice_points( mock_territory_rights_list: list[TerritoryRights], mock_pricing: list[TerritoryPricing] | None, mock_instant_grats: list[InstantGratRights] | None, snapshot: SnapshotAssertion, ) -> None: result = _get_splice_points( mock_territory_rights_list, pricing=mock_pricing, instant_grats=mock_instant_grats, ) assert result == snapshot @pytest.mark.parametrize( "mock_active_rights_list, expected_merged_rights", [ ( [ TerritoryRights( territories=["US", "CA"], start_date=datetime(2026, 1, 1), end_date=datetime(2027, 1, 1), price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["US", "CA"], start_date=datetime(2027, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], [ TerritoryRights( territories=["US", "CA"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], ), ( [ TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=datetime(2027, 1, 1), price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["CA"], start_date=datetime(2026, 1, 1), end_date=datetime(2027, 1, 1), price_code="3", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["US"], start_date=datetime(2027, 1, 1), end_date=datetime(2028, 1, 1), price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["CA"], start_date=datetime(2027, 1, 1), end_date=datetime(2028, 1, 1), price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["US"], start_date=datetime(2028, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["CA"], start_date=datetime(2028, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], [ TerritoryRights( territories=["US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["CA"], start_date=datetime(2026, 1, 1), end_date=datetime(2027, 1, 1), price_code="3", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["CA"], start_date=datetime(2027, 1, 1), end_date=datetime(2028, 1, 1), price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["CA"], start_date=datetime(2028, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], ), ], ) def test__merge_adjacent_rights( mock_active_rights_list: list[TerritoryRights], expected_merged_rights: list[TerritoryRights], ) -> None: result = _merge_adjacent_rights(mock_active_rights_list) assert result == expected_merged_rights @pytest.mark.parametrize( "mock_contiguous_merged_rights_list, expected_merged_rights", [ ( [ TerritoryRights( territories=["US", "CA"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["MX"], start_date=datetime(2026, 3, 1), end_date=datetime.max, price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), TerritoryRights( territories=["PE"], start_date=datetime(2026, 3, 1), end_date=datetime.max, price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, ), ], [ TerritoryRights( territories=["CA", "US"], start_date=datetime(2026, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=False, instant_gratification_tracks=None, ), TerritoryRights( territories=["MX", "PE"], start_date=datetime(2026, 3, 1), end_date=datetime.max, price_code="2", custom_price=None, distribution_rights={ DownloadStreamRights.DOWNLOAD, DownloadStreamRights.STREAM, }, is_preorder=False, instant_gratification_tracks=None, ), ], ), ], ) def test__merge_equal_rights( mock_contiguous_merged_rights_list: list[TerritoryRights], expected_merged_rights: list[TerritoryRights], ) -> None: result = _merge_equal_rights(mock_contiguous_merged_rights_list) assert result == expected_merged_rights @pytest.mark.parametrize( "expected_territories_data", [ ( { datetime(2024, 8, 10): ["US"], datetime(2024, 8, 12): ["AT", "BE", "CA", "FR"], } ), ], ) def test__format_territories_data( delivery_metadata_mock: DeliveryMetadata, expected_territories_data: dict[str, list[str]], ) -> None: result = _format_territories_data(delivery_metadata_mock) assert result == expected_territories_data @pytest.mark.parametrize( "mock_store, mock_track_id", [ pytest.param(StoreIds.NO_STORE, 12345, id="no_instant_grats_track_12345"), pytest.param(StoreIds.AMAZON, 12345, id="instant_grats_track_12345"), pytest.param(StoreIds.AMAZON, 12349, id="instant_grats_track_12349"), ], ) def test__format_territories_data_track_level( delivery_metadata_mock: DeliveryMetadata, mock_store: int, mock_track_id: int, snapshot: SnapshotAssertion, ) -> None: store = get_store_mock( mock_store, [TrackTypes.MUSIC], {mock_store: {"is_preorder_supported": True}} ) track = get_track_mock_no_pricing_by_track_id( [TrackTypes.MUSIC], store, mock_track_id ) delivery_metadata_mock = get_delivery_metadata_mock_by_store( store, [TrackTypes.MUSIC], ) result = _format_territories_data(delivery_metadata_mock, track) assert result == snapshot @pytest.mark.parametrize( "mock_pricing, expected_pricing", [ ( # One price for all territories/no dates { ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="FR", ), custom_pricing=None, start_date=None, end_date=None, ), }, [ TerritoryPricing( territories={"CA", "FR", "US"}, start_date=datetime.min, end_date=datetime.max, price_code="2", custom_price=None, ), ], ), ( # Different prices for different territories, no dates { ReleasePricing( price_code="1", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date=None, end_date=None, ), ReleasePricing( price_code="4L", country_code=TerritoryCodeA2( country_code="FR", ), custom_pricing=None, start_date=None, end_date=None, ), }, [ TerritoryPricing( territories={"US"}, start_date=datetime.min, end_date=datetime.max, price_code="1", custom_price=None, ), TerritoryPricing( territories={"CA"}, start_date=datetime.min, end_date=datetime.max, price_code="2", custom_price=None, ), TerritoryPricing( territories={"FR"}, start_date=datetime.min, end_date=datetime.max, price_code="4L", custom_price=None, ), ], ), ( # Different prices for different territories, with dates { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2024-08-10", end_date="2026-12-31", ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2027-01-01", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date="2024-08-10", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="MX", ), custom_pricing=None, start_date="2024-08-10", end_date=None, ), }, [ TerritoryPricing( territories={"US"}, start_date=datetime(2024, 8, 10), end_date=datetime(2027, 1, 1), price_code="3", custom_price=None, ), TerritoryPricing( territories={"CA", "MX"}, start_date=datetime(2024, 8, 10), end_date=datetime.max, price_code="2", custom_price=None, ), TerritoryPricing( territories={"US"}, start_date=datetime(2027, 1, 1), end_date=datetime.max, price_code="2", custom_price=None, ), ], ), ( # Fabricate end dates from start dates { ReleasePricing( price_code="3", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2024-08-10", end_date=None, ), ReleasePricing( price_code="2", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2027-01-01", end_date=None, ), ReleasePricing( price_code="1", country_code=TerritoryCodeA2( country_code="US", ), custom_pricing=None, start_date="2029-01-01", end_date=None, ), ReleasePricing( price_code="4L", country_code=TerritoryCodeA2( country_code="CA", ), custom_pricing=None, start_date=None, end_date=None, ), }, [ TerritoryPricing( territories={"CA"}, start_date=datetime.min, end_date=datetime.max, price_code="4L", custom_price=None, ), TerritoryPricing( territories={"US"}, start_date=datetime(2024, 8, 10), end_date=datetime(2027, 1, 1), price_code="3", custom_price=None, ), TerritoryPricing( territories={"US"}, start_date=datetime(2027, 1, 1), end_date=datetime(2029, 1, 1), price_code="2", custom_price=None, ), TerritoryPricing( territories={"US"}, start_date=datetime(2029, 1, 1), end_date=datetime.max, price_code="1", custom_price=None, ), ], ), ], ) def test__format_and_normalize_territory_pricing( mock_pricing: set[ReleasePricing], expected_pricing: list[TerritoryPricing], ) -> None: result = _format_and_normalize_territory_pricing(mock_pricing) assert result == expected_pricing @pytest.mark.parametrize( "mock_start_date, expected_normalized_start_date", [ (datetime(2024, 8, 10), datetime(2024, 8, 10)), (None, datetime.min), ], ) def test__normalize_start_date( mock_start_date: datetime | None, expected_normalized_start_date: datetime, ) -> None: result = _normalize_start_date(mock_start_date) assert result == expected_normalized_start_date @pytest.mark.parametrize( "mock_end_date, expected_denormalized_end_date", [ (None, None), (datetime(2027, 1, 1), datetime(2027, 1, 1, 0, 0)), (datetime.max, None), ], ) def test__denormalize_end_date_inclusive( mock_end_date: datetime | None, expected_denormalized_end_date: datetime, ) -> None: result = _denormalize_end_date_inclusive(mock_end_date) assert result == expected_denormalized_end_date @pytest.mark.parametrize( "mock_date, expected_normalized_date", [ (None, datetime.max), (datetime(2026, 12, 31), datetime(2027, 1, 1)), ], ) def test__normalize_end_date_exclusive( mock_date: datetime | None, expected_normalized_date: datetime, ) -> None: result = _normalize_end_date_exclusive(mock_date) assert result == expected_normalized_date