"""Tests for track-level asset operations.""" from typing import Any from unittest.mock import MagicMock import pytest from flexmock import flexmock from requests.exceptions import HTTPError from assets.constants import asset_upload_types, error from assets.exceptions import InvalidProductStatus from assets.logic import asset_copy, track from assets.models import ows_product, ows_track @pytest.fixture def correct_copy_track_data() -> dict[str, Any]: """Correct data for copy_track_asset call.""" return { "product_id": 777, "destination_product_id": 789, "filename": "000_000_002", "from_tuid": 54321, "to_tuid": 92345, "full_user_id": "alw:12345", "user_id": "alw:12345", "asset_concrete_type": "WAV", "source_upc": 54321, "destination_upc": 12345, } @pytest.fixture def copy_track_asset_mocks() -> dict[str, Any]: """Success mocks for copy_track_asset.""" return { "_prepare_source_track": { "source_upc": 54321, "source_filename": "54321_888_123.mp3", "track": { "upc": 54321, "volume_number": 888, "track_number": 123, }, "product": {"upc": 54321, "status": "in_content", "product_id": 777}, }, "_prepare_destination_track": { "destination_upc": 12345, "destination_filename": "54321_888_123.wav", "product": {"upc": 12345, "product_id": 789, "status": "in_progress"}, "track": { "upc": 12345, "volume_number": 888, "track_number": 123, }, }, "import_asset_items": {"import_asset_id": 1, "asset_type": "MP3"}, "direct_delivery_items": "ok", } @pytest.fixture def get_track_and_product_by_track_id_mocks() -> dict[str, Any]: """Success mocks for _get_track_and_product_by_track_id.""" return { "ows_product": {"status": "label_processing"}, "ows_track": { "product_id": 1, "track_number": 123, "volume_number": 888, "original_file_name": "name", }, } @pytest.fixture def generate_prepare_tracks_data_mocks( from_product_status: str = "in_content", from_original_name: str = "", to_product_status: str = "label_processing", ) -> dict[str, Any]: """Generate ows_track, ows_product responses mocks for copy_track_asset.""" return { "source_track": { "track": { "product_id": 1, "track_number": 123, "tuid": 555, "upc": 12312, "volume_number": 888, "original_file_name": from_original_name, }, "product": {"product_id": 444, "upc": 12312, "status": from_product_status}, }, "destination_track": { "track": { "product_id": 2, "tuid": 999, "track_number": 321, "upc": 76767, "volume_number": 111, "original_file_name": "name", }, "product": {"upc": 76767, "status": to_product_status}, }, } @pytest.fixture def tracks_id_for_copying() -> dict[str, int]: """Correct input data for preparing functions calls.""" return { "from_tuid": 54321, "to_tuid": 92345, } def test_post_asset_success_with_in_content_product( correct_copy_track_data: dict[str, Any], copy_track_asset_mocks: dict[str, Any] ) -> None: """Test for successful copy_track_asset call.""" copy_track_asset_mocks["_prepare_destination_track"] = { "destination_upc": 12345, "destination_filename": "54321_888_123.wav", "product": {"status": "in_content"}, } ( flexmock(track) .should_receive("_prepare_destination_track") .with_args(correct_copy_track_data["to_tuid"]) .and_return(copy_track_asset_mocks["_prepare_destination_track"]) ) ( flexmock(track) .should_receive("_prepare_source_track") .with_args(correct_copy_track_data["from_tuid"]) .and_return(copy_track_asset_mocks["_prepare_source_track"]) ) with pytest.raises(InvalidProductStatus) as exc: track.copy_track_asset( correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], correct_copy_track_data["user_id"], ) assert exc.value.description == error.ERROR_MESSAGE_PRODUCT_IN_CONTENT def test_post_asset_success( correct_copy_track_data: dict[str, Any], copy_track_asset_mocks: dict[str, Any] ) -> None: """Test for successful copy_track_asset call.""" ( flexmock(track) .should_receive("_prepare_source_track") .with_args(correct_copy_track_data["from_tuid"]) .and_return(copy_track_asset_mocks["_prepare_source_track"]) ) ( flexmock(track) .should_receive("_prepare_destination_track") .with_args(correct_copy_track_data["to_tuid"]) .and_return(copy_track_asset_mocks["_prepare_destination_track"]) ) ( flexmock(asset_copy) .should_receive("copy_v2_assets") .with_args( correct_copy_track_data["product_id"], correct_copy_track_data["destination_product_id"], correct_copy_track_data["destination_upc"], correct_copy_track_data["full_user_id"], correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], asset_upload_types.STEREO, False, ) .and_return(None) .once() .ordered() ) ( flexmock(asset_copy) .should_receive("copy_v2_assets") .with_args( correct_copy_track_data["product_id"], correct_copy_track_data["destination_product_id"], correct_copy_track_data["destination_upc"], correct_copy_track_data["full_user_id"], correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], asset_upload_types.ATMOS, True, ) .and_return(None) .once() .ordered() ) track.copy_track_asset( correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], correct_copy_track_data["user_id"], ) def test_post_asset_success_with_stereo_and_atmos_track( correct_copy_track_data: dict[str, Any], copy_track_asset_mocks: dict[str, Any] ) -> None: """Test successful copy_track_asset call when track has stereo and atmos.""" ( flexmock(track) .should_receive("_prepare_source_track") .with_args(correct_copy_track_data["from_tuid"]) .and_return(copy_track_asset_mocks["_prepare_source_track"]) ) ( flexmock(track) .should_receive("_prepare_destination_track") .with_args(correct_copy_track_data["to_tuid"]) .and_return(copy_track_asset_mocks["_prepare_destination_track"]) ) ( flexmock(asset_copy) .should_receive("copy_v2_assets") .with_args( correct_copy_track_data["product_id"], correct_copy_track_data["destination_product_id"], correct_copy_track_data["destination_upc"], correct_copy_track_data["full_user_id"], correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], asset_upload_types.STEREO, False, ) .and_return(None) .once() .ordered() ) ( flexmock(asset_copy) .should_receive("copy_v2_assets") .with_args( correct_copy_track_data["product_id"], correct_copy_track_data["destination_product_id"], correct_copy_track_data["destination_upc"], correct_copy_track_data["full_user_id"], correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], asset_upload_types.ATMOS, True, ) .and_return(None) .once() .ordered() ) track.copy_track_asset( correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], correct_copy_track_data["user_id"], ) def test_post_asset_success_with_atmos_track( correct_copy_track_data: dict[str, Any], copy_track_asset_mocks: dict[str, Any] ) -> None: """Test successful copy_track_asset call when track contains atmos asset type.""" copy_track_asset_mocks["_prepare_source_track"]["track"]["asset_type"] = "ATMOS" copy_track_asset_mocks["_prepare_destination_track"]["track"]["asset_type"] = ( "ATMOS" ) ( flexmock(track) .should_receive("_prepare_source_track") .with_args(correct_copy_track_data["from_tuid"]) .and_return(copy_track_asset_mocks["_prepare_source_track"]) ) ( flexmock(track) .should_receive("_prepare_destination_track") .with_args(correct_copy_track_data["to_tuid"]) .and_return(copy_track_asset_mocks["_prepare_destination_track"]) ) ( flexmock(asset_copy) .should_receive("copy_v2_assets") .with_args( correct_copy_track_data["product_id"], correct_copy_track_data["destination_product_id"], correct_copy_track_data["destination_upc"], correct_copy_track_data["full_user_id"], correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], asset_upload_types.STEREO, False, ) .and_return(None) .once() .ordered() ) ( flexmock(asset_copy) .should_receive("copy_v2_assets") .with_args( correct_copy_track_data["product_id"], correct_copy_track_data["destination_product_id"], correct_copy_track_data["destination_upc"], correct_copy_track_data["full_user_id"], correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], asset_upload_types.ATMOS, True, ) .and_return(None) .once() .ordered() ) track.copy_track_asset( correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], correct_copy_track_data["user_id"], ) def test_post_asset_prepare_source_track_failure( correct_copy_track_data: dict[str, Any], ) -> None: """Test for failure copy_track_asset call.""" ( flexmock(track) .should_receive("_prepare_source_track") .with_args(correct_copy_track_data["from_tuid"]) .and_raise(HTTPError(response=MagicMock(status_code=500))) ) (flexmock(track).should_receive("_prepare_destination_track").never()) (flexmock(asset_copy).should_receive("copy_v2_assets").never()) with pytest.raises(HTTPError) as exc: track.copy_track_asset( correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], correct_copy_track_data["user_id"], ) assert exc.value.response.status_code == 500 def test_post_asset_prepare_destination_track_failure( correct_copy_track_data: dict[str, Any], copy_track_asset_mocks: dict[str, Any] ) -> None: """Test for failure copy_track_asset call.""" ( flexmock(track) .should_receive("_prepare_source_track") .with_args(correct_copy_track_data["from_tuid"]) .and_return(copy_track_asset_mocks["_prepare_source_track"]) ) ( flexmock(track) .should_receive("_prepare_destination_track") .with_args(correct_copy_track_data["to_tuid"]) .and_raise(HTTPError(response=MagicMock(status_code=500))) ) (flexmock(asset_copy).should_receive("copy_v2_assets").never()) with pytest.raises(HTTPError) as exc: track.copy_track_asset( correct_copy_track_data["from_tuid"], correct_copy_track_data["to_tuid"], correct_copy_track_data["user_id"], ) assert str(exc.value) == "" def test_prepare_source_track_failure(tracks_id_for_copying: dict[str, int]) -> None: """Test for failure _prepare_source_track call.""" ( flexmock(track) .should_receive("_get_track_and_product_by_track_id") .with_args(tracks_id_for_copying["from_tuid"]) .and_raise(HTTPError(response=MagicMock(status_code=500))) ) with pytest.raises(HTTPError) as exc: track._prepare_source_track(tracks_id_for_copying["from_tuid"]) assert str(exc.value) == "" def test_prepare_source_track_default_flow_success( tracks_id_for_copying: dict[str, int], generate_prepare_tracks_data_mocks: dict[str, Any], ) -> None: """Test for successful _prepare_source_track call.""" ( flexmock(track) .should_receive("_get_track_and_product_by_track_id") .with_args(tracks_id_for_copying["from_tuid"]) .and_return(generate_prepare_tracks_data_mocks["source_track"]) .ordered() ) expected_result = generate_prepare_tracks_data_mocks["source_track"] expected_result["source_upc"] = 12312 assert ( track._prepare_source_track(tracks_id_for_copying["from_tuid"]) == expected_result ) def test_prepare_destination_track_success( tracks_id_for_copying: dict[str, int], generate_prepare_tracks_data_mocks: dict[str, Any], ) -> None: """Test for successful _prepare_destination_track call.""" ( flexmock(track) .should_receive("_get_track_and_product_by_track_id") .with_args(tracks_id_for_copying["to_tuid"]) .and_return(generate_prepare_tracks_data_mocks["destination_track"]) .ordered() ) result = track._prepare_destination_track(tracks_id_for_copying["to_tuid"]) assert result["destination_upc"] == 76767 def test_prepare_source_track_success( tracks_id_for_copying: dict[str, int], generate_prepare_tracks_data_mocks: dict[str, Any], ) -> None: """Test for successful _prepare_source_track call.""" ( flexmock(track) .should_receive("_get_track_and_product_by_track_id") .with_args(tracks_id_for_copying["from_tuid"]) .and_return(generate_prepare_tracks_data_mocks["source_track"]) .ordered() ) result = track._prepare_source_track(tracks_id_for_copying["from_tuid"]) assert result def test_prepare_destination_track_failure( tracks_id_for_copying: dict[str, int], ) -> None: """Test for failure _prepare_destination_track call.""" ( flexmock(track) .should_receive("_get_track_and_product_by_track_id") .with_args(tracks_id_for_copying["to_tuid"]) .and_raise(HTTPError(response=MagicMock(status_code=500))) ) with pytest.raises(HTTPError) as exc: track._prepare_destination_track(tracks_id_for_copying["to_tuid"]) assert str(exc.value) == "" def test_get_track_and_product_by_track_id_ows_track_failure( tracks_id_for_copying: dict[str, int], ) -> None: """Test for failure _get_track_and_product_by_track_id call.""" ( flexmock(ows_track) .should_receive("get_track_by_id") .with_args(tracks_id_for_copying["from_tuid"]) .and_raise(HTTPError(response=MagicMock(status_code=500))) ) with pytest.raises(HTTPError) as exc: track._get_track_and_product_by_track_id(tracks_id_for_copying["from_tuid"]) assert str(exc.value) == "" def test_get_track_and_product_by_track_id_ows_product_failure( tracks_id_for_copying: dict[str, int], get_track_and_product_by_track_id_mocks: dict[str, Any], ) -> None: """Test for failure _get_track_and_product_by_track_id call.""" ( flexmock(ows_track) .should_receive("get_track_by_id") .with_args(tracks_id_for_copying["from_tuid"]) .and_return(get_track_and_product_by_track_id_mocks["ows_track"]) ) ( flexmock(ows_product) .should_receive("get_product_by_id") .with_args(1) .and_raise(HTTPError(response=MagicMock(status_code=500))) ) with pytest.raises(HTTPError) as exc: track._get_track_and_product_by_track_id(tracks_id_for_copying["from_tuid"]) assert str(exc.value) == "" def test_get_track_and_product_by_track_id_success( tracks_id_for_copying: dict[str, int], get_track_and_product_by_track_id_mocks: dict[str, Any], ) -> None: """Test for successful _get_track_and_product_by_track_id call.""" ( flexmock(ows_track) .should_receive("get_track_by_id") .with_args(tracks_id_for_copying["from_tuid"]) .and_return(get_track_and_product_by_track_id_mocks["ows_track"]) ) ( flexmock(ows_product) .should_receive("get_product_by_id") .with_args(1) .and_return(get_track_and_product_by_track_id_mocks["ows_product"]) ) result = track._get_track_and_product_by_track_id( tracks_id_for_copying["from_tuid"] ) assert result