import pytest from flexmock import flexmock from assets.constants import asset_types, asset_upload_types, error from assets.exceptions import AssetFinalNotFound, AssetUploadNotFound from assets.logic import asset_upload as asset_upload_logic, stereo_reference from assets.models import ( asset_final, asset_upload as asset_upload_model, asset_upload_type, ) _STEREO_TYPE_ID = 1 _PRODUCT_ID = 4242 _TRACK_UNIQUE_ID = 7788 _INPUT_UPLOAD_ID = 1001 _STEREO_UPLOAD_ID = 1002 _STEREO_BUCKET = "prod-encoded-assets" _STEREO_FILENAME = "stereo.flac" def _expect_resolve_stereo_type_id() -> None: ( flexmock(asset_upload_type) .should_receive("resolve_asset_upload_type_id") .with_args(asset_upload_types.STEREO) .and_return(_STEREO_TYPE_ID) ) def _expect_input_asset_lookup( filename: str, *, product_id: int = _PRODUCT_ID, track_unique_id: int = _TRACK_UNIQUE_ID, asset_upload_type_id: int = 3, ) -> None: ( flexmock(asset_upload_logic) .should_receive("get_asset_upload_by_filename") .with_args(filename) .and_return( { "id": _INPUT_UPLOAD_ID, "product_id": product_id, "track_unique_id": track_unique_id, "asset_upload_type_id": asset_upload_type_id, } ) .once() ) def test_returns_latest_stereo_for_track() -> None: _expect_input_asset_lookup("atmos.wav") _expect_resolve_stereo_type_id() ( flexmock(asset_upload_model) .should_receive("get_latest_asset_upload") .with_args( product_id=_PRODUCT_ID, track_id=_TRACK_UNIQUE_ID, asset_upload_type_id=_STEREO_TYPE_ID, is_correction_mode=True, limit=1, ) .and_return([{"id": _STEREO_UPLOAD_ID}]) .once() ) ( flexmock(asset_final) .should_receive("get_asset_final_by_asset_upload_id_and_type") .with_args(_STEREO_UPLOAD_ID, asset_types.TYPE_FILE_FLAC) .and_return({"bucket": _STEREO_BUCKET, "filename": _STEREO_FILENAME}) .once() ) assert stereo_reference.get_stereo_for_asset("atmos.wav") == { "bucket": _STEREO_BUCKET, "key": _STEREO_FILENAME, } def test_lookup_is_scoped_to_product_when_track_unique_id_is_placeholder_zero() -> None: # Image assets use track_unique_id=0 as a placeholder. Without product_id in the # filter, the lookup would match stereos across every product that has a row with # track_unique_id=0. Scoping by (product_id, track_id) prevents that bleed. _expect_input_asset_lookup("artwork.jpg", track_unique_id=0) _expect_resolve_stereo_type_id() ( flexmock(asset_upload_model) .should_receive("get_latest_asset_upload") .with_args( product_id=_PRODUCT_ID, track_id=0, asset_upload_type_id=_STEREO_TYPE_ID, is_correction_mode=True, limit=1, ) .and_raise(AssetUploadNotFound(error.ERROR_ASSET_UPLOAD_NOT_FOUND)) .once() ) flexmock(asset_final).should_receive( "get_asset_final_by_asset_upload_id_and_type" ).never() with pytest.raises(AssetUploadNotFound): stereo_reference.get_stereo_for_asset("artwork.jpg") def test_asset_upload_not_found() -> None: ( flexmock(asset_upload_logic) .should_receive("get_asset_upload_by_filename") .with_args("missing.wav") .and_raise(AssetUploadNotFound(error.ERROR_ASSET_UPLOAD_NOT_FOUND)) .once() ) flexmock(asset_upload_model).should_receive("get_latest_asset_upload").never() flexmock(asset_final).should_receive( "get_asset_final_by_asset_upload_id_and_type" ).never() with pytest.raises(AssetUploadNotFound): stereo_reference.get_stereo_for_asset("missing.wav") def test_no_stereo_on_track_raises_not_found() -> None: _expect_input_asset_lookup("atmos_no_stereo.wav") _expect_resolve_stereo_type_id() ( flexmock(asset_upload_model) .should_receive("get_latest_asset_upload") .and_raise(AssetUploadNotFound(error.ERROR_ASSET_UPLOAD_NOT_FOUND)) .once() ) flexmock(asset_final).should_receive( "get_asset_final_by_asset_upload_id_and_type" ).never() with pytest.raises(AssetUploadNotFound, match=error.ERROR_ASSET_UPLOAD_NOT_FOUND): stereo_reference.get_stereo_for_asset("atmos_no_stereo.wav") def test_no_flac_asset_final_raises() -> None: _expect_input_asset_lookup("atmos_no_flac.wav") _expect_resolve_stereo_type_id() ( flexmock(asset_upload_model) .should_receive("get_latest_asset_upload") .and_return([{"id": _STEREO_UPLOAD_ID}]) .once() ) ( flexmock(asset_final) .should_receive("get_asset_final_by_asset_upload_id_and_type") .and_raise(AssetFinalNotFound(error.ERROR_ASSET_FINAL_NOT_FOUND)) .once() ) with pytest.raises(AssetFinalNotFound): stereo_reference.get_stereo_for_asset("atmos_no_flac.wav")