"""Fixtures for unit tests.""" import datetime import uuid from typing import Any, Generator from unittest import mock import boto3 import pytest from flask.ctx import AppContext from flask.testing import FlaskClient from mypy_boto3_s3 import S3Client import application from assets.constants import asset_types, error, field_const @pytest.fixture def fixture_client() -> FlaskClient: """Create an api test client fixture.""" return application.app.test_client() @pytest.fixture def fixture_app() -> Generator[AppContext, Any, None]: """Push a Flask app context with mocked globals. Required by tests using ``@patch("assets.utils.handlers.g")`` — the patcher inspects the original ``LocalProxy`` at enter time, which needs an active application context. """ with application.app.app_context() as context: context.g.ows = mock.MagicMock() context.g.request_context = mock.MagicMock() context.g.log = mock.MagicMock() yield context @pytest.fixture def valid_oa_headers() -> dict[str, str]: """Function that returns valid oa headers. Returns: dict: header dict """ return { field_const.CORRELATION_ID: str(uuid.uuid4()), field_const.ORCHARD_USER_ID: "oa:1234", } @pytest.fixture def fixture_vendor_entity() -> str: """Fixture to get vendor entity name.""" return "vendor" @pytest.fixture def fixture_vendor_id() -> int: """Fixture to get vendor id.""" return 1234 @pytest.fixture def fixture_artist_id() -> int: """Fixture to get artist id.""" return 1234 @pytest.fixture def fixture_artist_entity() -> str: """Fixture to get an artist entity name.""" return "artist" @pytest.fixture def fixture_is_valid_vendor() -> str: """Fixture to return valid vendor response.""" return error.SUCCESS_CODE @pytest.fixture def fixture_is_valid_artist() -> str: """Fixture to return valid artist response.""" return error.SUCCESS_CODE @pytest.fixture def fixture_is_valid_path() -> dict[str, str]: """Fixture of valid path.""" icon_path = "images/vendor/icon" logo_path = "images/vendor/logo" return {"logo": logo_path, "icon": icon_path} @pytest.fixture def valid_alw_headers() -> dict[str, str]: """Function that returns valid headers for alw user. Returns: dict: header dict """ return { field_const.CORRELATION_ID: str(uuid.uuid4()), field_const.ORCHARD_USER_ID: "alw:1234", field_const.GRASS_ACCOUNT_ID: "1234", field_const.GRASS_ACCOUNT_TYPE: "vendor", } @pytest.fixture def valid_bit_per_sample_data_for_upc() -> list[dict[str, Any]]: """Function that returns valid bit depth data for tracks for given UPC. Returns: list: dict """ return [ {"asset_type_id": 1, "filename": "191773123376_1_1.wav", "bits_per_sample": 24}, {"asset_type_id": 1, "filename": "191773123376_1_2.wav", "bits_per_sample": 24}, ] @pytest.fixture def mixed_bit_per_sample_data_for_upc() -> list[dict[str, Any]]: """Function that returns mixed bit depth data for tracks for given UPC. Returns: list: dict """ return [ {"asset_type_id": 1, "filename": "191773123376_1_1.wav", "bits_per_sample": 16}, {"asset_type_id": 1, "filename": "191773123376_1_2.wav", "bits_per_sample": 24}, ] @pytest.fixture def valid_bit_per_sample_data_upc_error_correction() -> list[dict[str, Any]]: """Function that returns valid bit depth data for some reuploaded tracks. Returns: list: dict """ return [ {"asset_type_id": 1, "filename": "191773123376_1_2.wav", "bits_per_sample": 16}, { "asset_type_id": 353, "filename": "191773123376_1_2.wav", "bits_per_sample": 24, }, {"asset_type_id": 1, "filename": "191773123376_1_3.wav", "bits_per_sample": 24}, ] @pytest.fixture def invalid_bit_per_sample_upc_error_correction() -> list[dict[str, Any]]: """Function that returns invalid bit depth data for some reuploaded tracks. Returns: list: dict """ return [ {"asset_type_id": 1, "filename": "191773123376_1_2.wav", "bits_per_sample": 16}, { "asset_type_id": 353, "filename": "191773123376_1_2.wav", "bits_per_sample": 24, }, {"asset_type_id": 1, "filename": "191773123376_1_3.wav", "bits_per_sample": 16}, ] @pytest.fixture def valid_bit_per_sample_error_correction_reupload_all() -> list[dict[str, Any]]: """Function that returns valid bit depth data for all reuploaded tracks. Returns: list: dict """ return [ {"asset_type_id": 1, "filename": "191773123376_1_2.wav", "bits_per_sample": 16}, { "asset_type_id": 353, "filename": "191773123376_1_2.wav", "bits_per_sample": 24, }, {"asset_type_id": 1, "filename": "191773123376_1_3.wav", "bits_per_sample": 16}, { "asset_type_id": 353, "filename": "191773123376_1_3.wav", "bits_per_sample": 24, }, ] @pytest.fixture def invalid_bit_per_sample_error_correction_reupload_all() -> list[dict[str, Any]]: """Function that returns invalid bit depth data for all reuploaded tracks. Returns: list: dict """ return [ {"asset_type_id": 1, "filename": "191773123376_1_2.wav", "bits_per_sample": 16}, { "asset_type_id": 353, "filename": "191773123376_1_2.wav", "bits_per_sample": 24, }, {"asset_type_id": 1, "filename": "191773123376_1_3.wav", "bits_per_sample": 32}, { "asset_type_id": 353, "filename": "191773123376_1_3.wav", "bits_per_sample": 16, }, ] @pytest.fixture def upcs_by_product_ids() -> dict[str, Any]: """Get list of upcs for provided product ids. Returns: dict: upcs/product ids dict """ return { "items": [ {"upc": 191773467098, "product_id": 2080166}, {"upc": 191773467104, "product_id": 2080168}, ] } @pytest.fixture def product_ids_by_upc() -> dict[str, Any]: """Get list of products for provided upcs. Returns: (dict): List of product dict """ return { "items": [ {"product_id": 123, "upc": 111111111}, {"product_id": 456, "upc": 222222222}, ] } @pytest.fixture def product_ids_not_found() -> dict[str, Any]: """Product id not found error. Returns: dict: some product ids not found response dict """ return { "code": "not_found", "message": [ { "208016820801682080168": { "code": "not_found", "message": "Invalid Product id", } } ], } @pytest.fixture def product_ids_all_not_found() -> dict[str, Any]: """All product ids not found error. Returns: dict: all product ids not found response dict """ return {"code": "not_found_error", "message": "All product ids are invalid"} @pytest.fixture def upcs_by_product_ids_bad_request() -> dict[str, Any]: """Bad request. Returns: dict: bad request response dict """ return { "code": "bad_request", "message": "Invalid product ids. " "They must be comma separated numbers." "Alphabets and special characters are not allowed", } @pytest.fixture def products_upcs_for_uniform_bit_depth_assets() -> dict[str, Any]: """Get products which have uniform bit depth assets. Returns: dict: products and upcs which having uniform bit depth assets dict """ return { "items": [{"upc": 191773467098, "product_id": 2080166}], "pagination": { "type": "standard", "offset": 0, "limit": 100, "total_records": 1, }, } # Legacy image assets table setup: PHYS-2970 IMAGE_CATEGORIES = {7: "cover_image", 10: "large_cover_image"} IMAGE_CATEGORY_IDS = list(IMAGE_CATEGORIES.keys()) def asset_copy_helper(image_datum: dict[str, Any]) -> dict[str, Any]: """Copy an image_asset element adding some differing properties.""" new_datum = image_datum.copy() new_datum["category_id"] = 10 return new_datum @pytest.fixture def legacy_image_asset_data() -> list[dict[str, Any]]: """Get data to seed image_asset table.""" init_data = [ { "category_id": 7, "path": "/21989/21989/", "filename": "100937027651{}.jpg".format(i), "height": (100 + i), "width": (100 + i), "mime_type": "image/jpeg", "file_size": (24470 + i), "date_added": "2011-07-22 14:09:{:02d}".format(i), "date_modified": "2011-07-22 14:09:{:02d}".format(i), "cdn_url": None, } for i in range(30) ] final_data = [] # Copy another record into the database response # Creates a scenario where we have two records in the DB # with category 7 and category 10. for image_datum in init_data: final_data.append(image_datum) final_data.append(asset_copy_helper(image_datum)) return final_data @pytest.fixture def updated_image_asset_records( legacy_image_asset_data: list[dict[str, Any]], ) -> list[dict[str, Any]]: """Fixture for testing image_asset updates.""" records_to_update = [] for index, record in enumerate(legacy_image_asset_data): record["id"] = index record["cdn_url"] = "http://mycdn.com/{}".format(record["filename"]) records_to_update.append(record) return records_to_update @pytest.fixture def valid_legacy_image_upc() -> int: """Return a valid upc.""" return 7009370276511 @pytest.fixture def valid_legacy_image_asset(valid_legacy_image_upc: int) -> dict[str, Any]: """Dict of valid input to make an `image_asset` record.""" return { "category_id": 17, "filename": "{}.jpg".format(valid_legacy_image_upc), "height": 2000, "width": 2000, "mime_type": "image/jpeg", "file_size": "2000", "cdn_url": "http://mycdn.com/{}.jpg".format(valid_legacy_image_upc), } @pytest.fixture def s3_client() -> S3Client: """Create an boto3 test client fixture.""" return boto3.client( "s3", region_name="us-east-1", aws_access_key_id="fake key", aws_secret_access_key="fake secret", ) @pytest.fixture def fixture_upload_token_data() -> dict[str, Any]: """Return upload_token data.""" return { "credentials": { "token": "a real token", "aws_secret_access_key": "a real secret", "aws_secret_key_id": "a real key", "expiration": "2017-02-28 21:14:43", }, "bucket": "test-orcd-raw-assets", "filename": "fred123", } @pytest.fixture def fixture_upload_token_data_for_entity() -> dict[str, Any]: """Return upload_token data.""" return { "credentials": { "token": "a real token", "aws_secret_access_key": "a real secret", "aws_secret_key_id": "a real key", "expiration": "2017-02-28 21:14:43", }, "bucket": "test-asset-assets", "path": {"logo": "images/vendor/logo", "icon": "images/vendor/icon"}, "filename": "81dc9bdb52d04dc20036dbd8313ed055.jpg", } @pytest.fixture def fixture_get_status_filename() -> str: """Fixture to return filename for get asset endpoint param.""" return "unique_filename.ext" @pytest.fixture def correct_post_assets_v2_body() -> dict[str, Any]: """Correct post asset body fixture.""" return { "product_id": 12345, "upc": "123456", "track_unique_id": 54321, "filename": "unique_filename.wav", "original_filename": "original_filename.mp3", "is_correction": True, } @pytest.fixture def correct_post_asset_final_v2_body() -> dict[str, Any]: """Correct post asset final body fixture.""" return { "filename": "unique_filename.ext", "status": "COMPLETED", "message": { "function": "some_function", "status": "COMPLETED", "input": {"key": "unique_filename.ext"}, }, "timestamp": "timestamp", "final_assets": [], } @pytest.fixture def correct_post_asset_status_v2_body() -> dict[str, Any]: """Correct post asset status body fixture.""" return { "filename": "unique_filename.ext", "status": "success", "description": "Success description", "message": { "function": "some_function", "status": "success", "description": "Success description", "input": {"key": "unique_filename.ext"}, }, "timestamp": "timestamp", } @pytest.fixture def asset_upload_data() -> list[dict[str, Any]]: return [ { "id": 1, "bucket_name": "some_bucket", "filename": "unique_filename_2", "api_version": 1, "user_id": "oa:654321", "token": "session_token_2".encode(), "original_filename": "original_filename_2", "track_unique_id": 2, "product_id": 1, "deleted": False, "updated_timestamp": datetime.datetime(2017, 1, 1, 0, 0), }, { "id": 2, "bucket_name": "some_bucket", "filename": "unique_filename_3", "api_version": 1, "user_id": "oa:654321", "token": "session_token_3".encode(), "original_filename": "original_filename_3", "track_unique_id": 0, "product_id": 2, "deleted": False, "updated_timestamp": datetime.datetime(2017, 1, 1, 0, 0), }, { "id": 3, "bucket_name": "some_bucket", "filename": "unique_filename_4", "api_version": 1, "user_id": "oa:123456", "token": "session_token_4".encode(), "original_filename": "original_filename_1", "track_unique_id": 1, "product_id": 1, "deleted": True, "updated_timestamp": datetime.datetime(2017, 1, 1, 0, 0), }, ] @pytest.fixture def status_data() -> dict[str, Any]: """Fixture for status data.""" return { "filename": "filename.ext", "status": "success", "description": "", "message": { "function": "some_function", "status": "success", "input": {"key": "filename.ext"}, }, "timestamp": "2017-05-05T22:23:24.333Z", } @pytest.fixture def hive_segment_data() -> list[dict[str, Any]]: """Fixture for hive segment data list.""" return [ { "asset_final_id": 111, "time": 300, "ai_generated_music": 1, "ai_generated_music_vocal": 1.66, "mubert": 1, "musicgen": 1, "riffusion": 1, "stable_audio": 1, "suno": 1, "udio": 1, "created_at": datetime.datetime(2017, 1, 6, 0, 0), }, { "asset_final_id": 222, "time": 300, "ai_generated_music": 1.77, "ai_generated_music_vocal": 1, "mubert": 1, "musicgen": 1, "riffusion": 1, "stable_audio": 1, "suno": 1, "udio": 1, "created_at": datetime.datetime(2020, 12, 6, 0, 0), }, { "asset_final_id": 333, "time": 500, "ai_generated_music": 0.80, "ai_generated_music_vocal": 1.88, "mubert": 1, "musicgen": 1, "riffusion": 1, "stable_audio": 1, "suno": 1, "udio": 1, "created_at": datetime.datetime(2024, 1, 30, 0, 0), }, { "asset_final_id": 444, "time": 497, "ai_generated_music": 0.99, "ai_generated_music_vocal": 1.88, "mubert": 1, "musicgen": 1, "riffusion": 1, "stable_audio": 1, "suno": 1, "udio": 1, "created_at": datetime.datetime(2024, 1, 30, 0, 0), }, { "asset_final_id": 444, "time": 500, "ai_generated_music": 0.99, "ai_generated_music_vocal": 1.88, "mubert": 1, "musicgen": 1, "riffusion": 1, "stable_audio": 1, "suno": 1, "udio": 1, "created_at": datetime.datetime(2024, 1, 30, 0, 0), }, ] @pytest.fixture def hive_task_data() -> dict[str, Any]: return { "id": 11, field_const.ASSET_FINAL_ID: 111, field_const.TASK_ID: uuid.UUID("a22414c0-0cba-11f1-bc98-c7fc13f309f3"), field_const.MODEL: "ai_music_classifier_DORIAN_2025_04_02_v00", field_const.MODEL_VERSION: 1, } @pytest.fixture def asset_upload_data_for_hive() -> list[dict[str, Any]]: """Fixture for asset_upload data list.""" return [ { "id": 1, "user_id": "oa:123456", "asset_upload_type_id": 1, "token": "test_token_1".encode(), "filename": "track_111", "api_version": 2, "product_id": 1001, "upc": "123456789012", "track_unique_id": 123, "bucket_name": "test-bucket", "original_filename": "original_111", "deleted": False, "is_correction": False, "updated_timestamp": datetime.datetime(2017, 1, 3, 0, 0), }, { "id": 2, "user_id": "oa:123456", "asset_upload_type_id": 1, "token": "test_token_2".encode(), "filename": "track_222.flac", "api_version": 2, "product_id": 1001, "upc": "123456789012", "track_unique_id": 234, "bucket_name": "test-bucket", "original_filename": "original_222.flac", "deleted": False, "is_correction": False, "updated_timestamp": datetime.datetime(2018, 1, 3, 0, 0), }, { "id": 3, "user_id": "oa:123456", "asset_upload_type_id": 1, "token": "test_token_3".encode(), "filename": "track_333", "api_version": 2, "product_id": 1001, "upc": "123456789012", "track_unique_id": 345, "bucket_name": "test-bucket", "original_filename": "original_333.flac", "deleted": False, "is_correction": False, "updated_timestamp": datetime.datetime(2019, 1, 3, 0, 0), }, { "id": 4, "user_id": "oa:123456", "asset_upload_type_id": 1, "token": "test_token_4".encode(), "filename": "track_444", "api_version": 2, "product_id": 1001, "upc": "123456789012", "track_unique_id": 456, "bucket_name": "test-bucket", "original_filename": "original_444.flac", "deleted": False, "is_correction": False, "updated_timestamp": datetime.datetime(2020, 1, 3, 0, 0), }, { "id": 5, "user_id": "oa:123456", "asset_upload_type_id": 1, "token": "test_token_5".encode(), "filename": "track_555", "api_version": 2, "product_id": 1001, "upc": "123456789012", "track_unique_id": 567, "bucket_name": "test-bucket", "original_filename": "original_555.flac", "deleted": False, "is_correction": False, "updated_timestamp": datetime.datetime(2021, 1, 3, 0, 0), }, { "id": 6, "user_id": "oa:123456", "asset_upload_type_id": 2, "token": "test_token_6".encode(), "filename": "image_006", "api_version": 2, "product_id": 1003, "upc": "123456789014", "track_unique_id": 0, "bucket_name": "test-bucket", "original_filename": "original_image_006.jpg", "deleted": False, "is_correction": False, "updated_timestamp": datetime.datetime(2024, 1, 3, 0, 0), }, ] @pytest.fixture def asset_final_data() -> list[dict[str, Any]]: """Fixture for asset_final data list.""" return [ { "id": 111, "asset_upload_id": 1, "asset_type": asset_types.TYPE_FILE_FLAC, "asset_subtype": "none", "bucket": "test-bucket", "filename": "track_111.flac", "duration": 300, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, { "id": 222, "asset_upload_id": 2, "asset_type": asset_types.TYPE_FILE_FLAC, "asset_subtype": "none", "bucket": "test-bucket", "filename": "track_222.flac", "duration": 300, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, { "id": 333, "asset_upload_id": 3, "asset_type": asset_types.TYPE_FILE_FLAC, "asset_subtype": "none", "bucket": "test-bucket", "filename": "track_333.flac", "duration": 500, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, { "id": 444, "asset_upload_id": 4, "asset_type": asset_types.TYPE_FILE_FLAC, "asset_subtype": "none", "bucket": "test-bucket", "filename": "track_444.flac", "duration": 497, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, { "id": 555, "asset_upload_id": 5, "asset_type": asset_types.TYPE_FILE_FLAC, "asset_subtype": "none", "bucket": "test-bucket", "filename": "track_555.flac", "duration": 600, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, { "id": 103, "asset_upload_id": 6, "asset_type": asset_types.TYPE_FILE_JPG, "asset_subtype": "cover", "bucket": "test-bucket", "filename": "image_003.jpeg", "duration": None, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, { "id": 104, "asset_upload_id": 6, "asset_type": asset_types.TYPE_FILE_JPG, "asset_subtype": "large_cover", "bucket": "test-bucket", "filename": "image_004.jpeg", "duration": None, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, { "id": 105, "asset_upload_id": 6, "asset_type": asset_types.TYPE_FILE_JPG, "asset_subtype": "xlarge_cover", "bucket": "test-bucket", "filename": "image_005.jpeg", "duration": None, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, { "id": 106, "asset_upload_id": 6, "asset_type": asset_types.TYPE_FILE_TIF, "asset_subtype": None, "bucket": "test-bucket", "filename": "image_006.tif", "duration": None, "channels": None, "codec": None, "sample_rate": None, "bit_rate": None, "bit_depth": None, }, ] @pytest.fixture def hive_text_recognition_data() -> list[dict[str, Any]]: """Fixture for hive_text_recognition data.""" return [ { "asset_final_id": 104, "block_text": "some extracted text", } ] @pytest.fixture def valid_hive_ai_image_task_data() -> dict[str, Any]: """Fixture for valid data for hive_ai_image_task.""" return { "asset_final_id": 111, "task_id": "task_001", "class_name": "violence", "score_value": 0.97, }