"""Test product metadata utils.""" import pytest from content_utils.constants.product import PRODUCT_CONFIGURATION_DIGITAL_AUDIO from content_utils.utils import product_metadata @pytest.mark.parametrize(( 'test_description', 'review_queue_item', 'expected_result', ), [ ( 'review_queue_item is None', None, { 'queue_name': None, 'moved_to_queue_by_user_id': None, 'moved_to_queue_by_user_name': None, 'moved_to_target_email': None, 'moved_to_target_id': None, 'moved_to_target_name': None, 'moved_to_group_name': None, 'escalation_type': None, 'submission_datetime': None }, ), ( 'movedToQueueByIdentity is None', { 'queueName': 'initial', 'movedToQueueByIdentity': None, }, { 'queue_name': 'initial', 'moved_to_queue_by_user_id': None, 'moved_to_queue_by_user_name': None, 'moved_to_target_email': None, 'moved_to_target_id': None, 'moved_to_target_name': None, 'moved_to_group_name': None, 'escalation_type': None, 'submission_datetime': None }, ), ( 'movedToTarget fields are not None', { 'queueName': 'initial', 'movedToQueueByIdentity': {'id': 1, 'firstName': 'Bar', 'lastName': 'Foo'}, 'movedToTargetEmail': 'hello@world.com', 'movedToTargetName': 'Foo Bar', 'movedToTargetId': 1, 'movedToTarget': {'escalationType': 'abc test', 'targetGroup': {'displayName': 'Support'}}, }, { 'queue_name': 'initial', 'moved_to_queue_by_user_id': 1, 'moved_to_queue_by_user_name': 'Bar Foo', 'moved_to_target_email': 'hello@world.com', 'moved_to_target_id': 'foo_bar', 'moved_to_target_name': 'Foo Bar', 'moved_to_group_name': 'Support', 'escalation_type': 'abc test', 'submission_datetime': None }, ), ]) def test_get_queue_fields_defaults(test_description, review_queue_item, expected_result): """Test get_queue_fields defaults.""" assert product_metadata.get_queue_fields(review_queue_item) == expected_result none_name = None whitespace_name = ' ' name = 'name' padded_name = f' {name} ' @pytest.mark.parametrize('first_name, last_name, expected_name', [ (none_name, none_name, None), (none_name, whitespace_name, None), (none_name, padded_name, name), (whitespace_name, none_name, None), (whitespace_name, whitespace_name, None), (whitespace_name, padded_name, name), (padded_name, none_name, 'name'), (padded_name, whitespace_name, name), (' first ', ' last ', 'first last'), ]) def test_get_queue_fields_name_formatting( mock_review_queue_item, first_name, last_name, expected_name, ): """Test get_queue_fields name formatting.""" mock_review_queue_item['movedToQueueByIdentity'].update( firstName=first_name, lastName=last_name, ) assert product_metadata.get_queue_fields( mock_review_queue_item )['moved_to_queue_by_user_name'] == expected_name def test_get_indexable_document( mock_row_data, mock_graphql_response, mock_index_document, mock_review_queue_item, ): """Test get_indexable_document.""" mock_product = mock_graphql_response['data']['product'] response = product_metadata.get_indexable_document( mock_row_data, mock_product, mock_review_queue_item) assert response == mock_index_document def test_get_indexable_document_product_never_moved( mock_row_data, mock_graphql_response, mock_index_document, mock_review_queue_item, ): """Test get_indexable_document with product that has never been moved.""" mock_product = mock_graphql_response['data']['product'] mock_review_queue_item['movedToQueueByIdentity'] = None response = product_metadata.get_indexable_document( mock_row_data, mock_product, mock_review_queue_item) mock_index_document['moved_to_queue_by_user_id'] = None mock_index_document['moved_to_queue_by_user_name'] = None assert response == mock_index_document def test_get_d3_subaccount_indexable_document( mock_row_data, mock_graphql_d3_subaccount_response, mock_d3_subaccount_index_document, mock_review_queue_item, ): """Test get_d3_subaccount_indexable_document.""" mock_product = mock_graphql_d3_subaccount_response['data']['product'] response = product_metadata.get_indexable_document( mock_row_data, mock_product, mock_review_queue_item) assert response == mock_d3_subaccount_index_document def test_get_indexable_document_subaccount_product( mock_row_data, mock_graphql_response_subaccount, mock_review_queue_item, ): """Test get_indexable_document.""" mock_product = mock_graphql_response_subaccount['data']['product'] response = product_metadata.get_indexable_document( mock_row_data, mock_product, mock_review_queue_item) assert response == { 'account_id': '16160:10', 'account_name': 'Subaccount1', 'account_country': 'USA', 'account_country_code': 'US', 'added_at': mock_row_data.get('added_at'), 'assigned_reviewer_id': 1, 'assigned_reviewer_name': 'foo bar', 'assigned_to_id': 1, 'assigned_to_name': 'foo bar', 'bulk_session_id': 'test-bulk-session-id', 'company_brand': { 'displayName': 'Brandie', 'name': 'brandie', 'uuid': '0fd602fc-76b0-42fd-8607-2a0ddeca46e7', }, 'company_brand_display_name': 'Brandie', 'company_brand_name': 'brandie', 'company_brand_uuid': '0fd602fc-76b0-42fd-8607-2a0ddeca46e7', 'configuration': PRODUCT_CONFIGURATION_DIGITAL_AUDIO, 'display_status': 'error_correction', 'distribution_format_id': 1, 'escalation_type': None, 'featuring_artist': 'PRONOUN', 'format': 'Full Length', 'genre_id': 20, 'genre_name': 'Blues', 'image_location': 'http://image.png', 'imprint': 'petertest', 'label_id': 16160, 'label_name': 'Label1', 'label_owner': 'odd', 'locked_by_user_id': None, 'locked_until_datetime': None, 'metadata_language_code': 'ENG', 'metadata_language_name': 'English', 'moved_to_group_name': None, 'moved_to_queue_by_user_id': 'cce11590-be86-4fb6-a384-afffff643af1', 'moved_to_queue_by_user_name': 'Very Cool', 'moved_to_target_email': None, 'moved_to_target_id': None, 'moved_to_target_name': None, 'notices': [], 'preorder_date': None, 'primary_artist': 'Sinaloha', 'product_id': mock_row_data.get('product_id'), 'product_name': 'Contest02', 'queue_name': 'initial', 'release_correction_status': mock_row_data.get('releaseCorrections', {}).get('status', ''), 'review_queue_id': mock_row_data.get('review_queue_id'), 'sale_start_date': '2022-07-01', 'secondary_internal_contact_id': 2, 'secondary_internal_contact_name': 'baz qux', 'service_tier_name': 'applesauce-bananas', 'service_tier_uuid': '93185c0c-fe01-4bff-bb0d-a7609b8711e5', 'special_instructions': 'SI', 'subaccount_id': 10, 'subaccount_name': 'Subaccount1', 'submission_count': 1, 'submission_type': 'New', 'upc': '196292189827', 'submission_datetime': '1975-04-09 09:17:24', 'version': 'Content Review UI Testing' } def test_get_indexable_document_track_error_product( mock_row_data, mock_graphql_response_track_validation, mock_review_queue_item, ): """Test get_indexable_document with a track error.""" mock_product = mock_graphql_response_track_validation['data']['product'] response = product_metadata.get_indexable_document( mock_row_data, mock_product, mock_review_queue_item) assert response == { 'account_id': '16160:0', 'account_name': 'Non-Mechanical M/USD', 'account_country': 'USA', 'account_country_code': 'US', 'added_at': mock_row_data.get('added_at'), 'assigned_reviewer_id': 1, 'assigned_reviewer_name': 'foo bar', 'assigned_to_id': 1, 'assigned_to_name': 'foo bar', 'bulk_session_id': 'test-bulk-session-id', 'company_brand': {'name': 'foo', 'uuid': 'abc', 'displayName': 'Foo'}, 'company_brand_display_name': 'Foo', 'company_brand_name': 'foo', 'company_brand_uuid': 'abc', 'configuration': PRODUCT_CONFIGURATION_DIGITAL_AUDIO, 'display_status': 'error_correction', 'distribution_format_id': 1, 'escalation_type': None, 'featuring_artist': 'PRONOUN', 'format': 'Full Length', 'genre_id': 20, 'genre_name': 'Blues', 'image_location': 'http://image.png', 'imprint': 'petertest', 'label_id': 16160, 'label_name': 'Non-Mechanical M/USD', 'label_owner': 'odd', 'locked_by_user_id': None, 'locked_until_datetime': None, 'metadata_language_code': 'ENG', 'metadata_language_name': 'English', 'moved_to_group_name': None, 'moved_to_queue_by_user_id': 'cce11590-be86-4fb6-a384-afffff643af1', 'moved_to_queue_by_user_name': 'Very Cool', 'moved_to_target_email': None, 'moved_to_target_id': None, 'moved_to_target_name': None, 'notices': [{ 'code': 'MISSING_AUDIO_FILE', 'level': 'errors', 'reason': 'Field `audio_file` is required' }], 'preorder_date': None, 'primary_artist': 'Sinaloha', 'product_id': mock_row_data.get('product_id'), 'product_name': 'Contest02', 'queue_name': 'initial', 'release_correction_status': '', 'review_queue_id': mock_row_data.get('review_queue_id'), 'sale_start_date': '2022-07-01', 'secondary_internal_contact_id': 2, 'secondary_internal_contact_name': 'baz qux', 'service_tier_name': 'applesauce-bananas', 'service_tier_uuid': '93185c0c-fe01-4bff-bb0d-a7609b8711e5', 'special_instructions': 'SI', 'submission_count': 1, 'submission_type': 'New', 'subaccount_id': 0, 'subaccount_name': '', 'upc': '196292189827', 'submission_datetime': '1975-04-09 09:17:24', 'version': 'Content Review UI Testing' } def test_format_multiple_added_at_types( mock_row_data, mock_graphql_response_product_validation, mock_review_queue_item, ): """Test formatting string and microtime inputs.""" mock_product = mock_graphql_response_product_validation['data']['product'] response = product_metadata.get_indexable_document( mock_row_data, mock_product, mock_review_queue_item) assert response['added_at'] == mock_row_data['added_at'] input_with_microtime = { **mock_row_data, 'added_at': 1677236329000000 } response = product_metadata.get_indexable_document( input_with_microtime, mock_product, mock_review_queue_item) assert response['added_at'] == '2023-02-24T10:58:49Z' input_with_millitime = { **mock_row_data, 'added_at': 1677236329000 } response = product_metadata.get_indexable_document( input_with_millitime, mock_product, mock_review_queue_item) assert response['added_at'] == '2023-02-24T10:58:49Z' def test_get_indexable_document_product_error_product( mock_row_data, mock_graphql_response_product_validation, mock_review_queue_item, ): """Test get_indexable_document with a product error.""" mock_product = mock_graphql_response_product_validation['data']['product'] response = product_metadata.get_indexable_document( mock_row_data, mock_product, mock_review_queue_item) assert response == { 'account_id': '16160:0', 'account_name': 'Non-Mechanical M/USD', 'account_country': 'USA', 'account_country_code': 'US', 'added_at': mock_row_data.get('added_at'), 'assigned_reviewer_id': 1, 'assigned_reviewer_name': 'foo bar', 'assigned_to_id': 1, 'assigned_to_name': 'foo bar', 'bulk_session_id': 'test-bulk-session-id', 'company_brand': {'name': 'foo', 'uuid': 'abc', 'displayName': 'Foo'}, 'company_brand_display_name': 'Foo', 'company_brand_name': 'foo', 'company_brand_uuid': 'abc', 'configuration': PRODUCT_CONFIGURATION_DIGITAL_AUDIO, 'display_status': 'error_correction', 'distribution_format_id': 1, 'escalation_type': None, 'featuring_artist': 'PRONOUN', 'format': 'Full Length', 'genre_id': 20, 'genre_name': 'Blues', 'image_location': 'http://image.png', 'imprint': 'petertest', 'label_id': 16160, 'label_name': 'Non-Mechanical M/USD', 'label_owner': 'odd', 'locked_by_user_id': None, 'locked_until_datetime': None, 'metadata_language_code': 'ENG', 'metadata_language_name': 'English', 'moved_to_group_name': None, 'moved_to_queue_by_user_id': 'cce11590-be86-4fb6-a384-afffff643af1', 'moved_to_queue_by_user_name': 'Very Cool', 'moved_to_target_email': None, 'moved_to_target_id': None, 'moved_to_target_name': None, 'notices': [{ 'code': 'MISSING_AUDIO_FILE', 'level': 'warnings', 'reason': 'Field `audio_file` is required' }], 'preorder_date': None, 'primary_artist': 'Sinaloha', 'product_id': mock_row_data.get('product_id'), 'product_name': 'Contest02', 'queue_name': 'initial', 'release_correction_status': '', 'review_queue_id': mock_row_data.get('review_queue_id'), 'sale_start_date': '2022-07-01', 'secondary_internal_contact_id': 2, 'secondary_internal_contact_name': 'baz qux', 'service_tier_name': 'applesauce-bananas', 'service_tier_uuid': '93185c0c-fe01-4bff-bb0d-a7609b8711e5', 'special_instructions': 'SI', 'submission_count': 1, 'submission_type': 'New', 'subaccount_id': 0, 'subaccount_name': '', 'upc': '196292189827', 'submission_datetime': '1975-04-09 09:17:24', 'version': 'Content Review UI Testing' } def test_get_submission_type_new(): """Test returns correct status for new submissions.""" mock_data = {'submissionType': 'new'} response = product_metadata.get_submission_type(mock_data) assert response == 'New' def test_get_submission_type_resubmission(): """Test returns correct status for re-submissions.""" mock_data = {'submissionType': 're_submission'} response = product_metadata.get_submission_type(mock_data) assert response == 'Re-Submission' def test_get_submission_type_revision(): """Test returns correct status for revisions.""" mock_data = {'submissionType': 'revision'} response = product_metadata.get_submission_type(mock_data) assert response == 'Revision' def test_get_submission_count_from_row_data(): """Test get submission count from row data.""" actual = product_metadata.get_submission_count({'submission_count': 2}, None) assert actual == 2 def test_get_submission_count_from_gql(): """Test get submission count from gql response.""" actual = product_metadata.get_submission_count({}, {'submissionCount': 3}) assert actual == 3 def test_format_error_corrections( mock_graphql_response_with_corrections, mock_formatted_corrections): """Test returns formatted error corrections.""" response = product_metadata.format_product_corrections( mock_graphql_response_with_corrections['data']['product']['releaseCorrection']['items']) assert response == mock_formatted_corrections @pytest.mark.parametrize('bulk_session_object, expected_value', [ (None, None), ({'id': 'test-bulk-session-id', 'ingestion': {'submittedProductsCount': 1}}, None), ({'id': 'test-bulk-session-id', 'ingestion': {'submittedProductsCount': 2}}, 'test-bulk-session-id'), ]) def test_get_bulk_session_id_from_metadata(bulk_session_object, expected_value): """Test get_bulk_session_id returns None when bulkSession is None.""" mock_product_metadata = { 'bulkSession': bulk_session_object } response = product_metadata.get_bulk_session_id_from_metadata(mock_product_metadata) assert response is expected_value def test_get_complete_product_document_basic_fields(): """Test get_complete_product_document with basic fields.""" mock_product_metadata = { 'productId': '12345', 'productName': 'Test Album', 'productCode': 'TESTCODE', 'imprint': 'Test Imprint', 'upc': '123456789012', 'deliveredVersion': 'v1.0', 'format': 'Full Length', 'version': 'Original', 'cLine': '2026 Test Label', 'specialInstructions': 'Handle with care', 'imageLocation': 'http://example.com/image.jpg', 'releaseDate': '2026-06-01', 'saleStartDate': '2026-05-15', 'preorderDate': '2026-05-01', 'previewable': True } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['product_id'] == '12345' assert result['product_name'] == 'Test Album' assert result['product_code'] == 'TESTCODE' assert result['imprint'] == 'Test Imprint' assert result['upc'] == '123456789012' assert result['delivered_version'] == 'v1.0' assert result['format'] == 'Full Length' assert result['version'] == 'Original' assert result['c_line'] == '2026 Test Label' assert result['special_instructions'] == 'Handle with care' assert result['image_location'] == 'http://example.com/image.jpg' assert result['release_date'] == '2026-06-01' assert result['sale_start_date'] == '2026-05-15' assert result['preorder_date'] == '2026-05-01' assert result['previewable'] is True def test_get_complete_product_document_schema(): """Test that get_complete_product_document always returns all keys with defaults.""" mock_product_metadata = { 'productId': '12345', 'productName': 'Minimal Product' } result = product_metadata.get_complete_product_document(mock_product_metadata) expected_keys = [ 'product_id', 'product_name', 'product_code', 'imprint', 'upc', 'delivered_version', 'format', 'version', 'c_line', 'special_instructions', 'image_location', 'release_date', 'sale_start_date', 'preorder_date', 'previewable', 'metadata_language', 'bulk_session', 'label', 'label_participations', 'product_localizations', 'artists', 'tracks', 'validation', 'review_history', 'subgenre', 'album_pricing_tier', 'track_pricing_tier', 'release_schedule', 'release_correction' ] for key in expected_keys: assert key in result, f"Key '{key}' should always be present in result" assert result['metadata_language'] is None assert result['bulk_session'] is None assert result['label'] is None assert result['label_participations'] == [] assert result['product_localizations'] == [] assert result['artists'] == [] assert result['tracks'] == [] assert result['validation'] is None assert result['review_history'] is None assert result['subgenre'] is None assert result['album_pricing_tier'] is None assert result['track_pricing_tier'] is None assert result['release_schedule'] is None assert result['release_correction'] is None def test_get_complete_product_document_with_validation(): """Test get_complete_product_document with validation.""" mock_product_metadata = { 'productId': '12345', 'validation': { 'isValid': False, 'errors': [ {'reason': 'Invalid Artwork', 'codeV2': 'INVALID_ARTWORK'} ], 'warnings': [ {'reason': 'Potential Audio Infringement', 'codeV2': 'POTENTIAL_AUDIO_INFRINGEMENT'} ] } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['validation']['isValid'] is False assert len(result['validation']['errors']) == 1 assert result['validation']['errors'][0]['reason'] == 'Invalid Artwork' assert result['validation']['errors'][0]['codeV2'] == 'INVALID_ARTWORK' assert len(result['validation']['warnings']) == 1 assert result['validation']['warnings'][0]['reason'] == 'Potential Audio Infringement' def test_get_complete_product_document_with_metadata_language(): """Test get_complete_product_document with metadata language.""" mock_product_metadata = { 'productId': '12345', 'metadataLanguage': { 'code': 'ENG', 'name': 'English' } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['metadata_language']['code'] == 'ENG' assert result['metadata_language']['name'] == 'English' def test_get_complete_product_document_with_bulk_session(): """Test get_complete_product_document with bulk session.""" mock_product_metadata = { 'productId': '12345', 'bulkSession': { 'id': 'bulk-123', 'ingestion': { 'submittedProductsCount': 5 } } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['bulk_session']['id'] == 'bulk-123' assert result['bulk_session']['ingestion']['submittedProductsCount'] == 5 def test_get_complete_product_document_with_vendor_label(): """Test get_complete_product_document with vendor label (not subaccount).""" mock_product_metadata = { 'productId': '12345', 'label': { 'id': { 'vendorId': 100, 'subaccountId': 0 }, 'name': 'Test Label', 'countryCode': 'US', 'contentReviewNote': 'Test note', 'serviceTier': { 'name': 'premium', 'displayName': 'Premium' } } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['label']['vendor_id'] == 100 assert result['label']['subaccount_id'] == 0 assert result['label']['name'] == 'Test Label' assert result['label']['country_code'] == 'US' assert result['label']['content_review_note'] == 'Test note' assert result['label']['service_tier']['name'] == 'premium' assert result['label']['service_tier']['display_name'] == 'Premium' def test_get_complete_product_document_with_subaccount_label(): """Test get_complete_product_document with subaccount label.""" mock_product_metadata = { 'productId': '12345', 'label': { 'id': { 'vendorId': 100, 'subaccountId': 10 }, 'name': 'Subaccount Name', 'countryCode': 'US', 'contentReviewNote': 'Sub note', 'serviceTier': { 'name': 'basic', 'displayName': 'Basic' }, 'vendor': { 'name': 'Parent Label', 'contentReviewNote': 'Parent note', 'serviceTier': { 'name': 'premium', 'displayName': 'Premium' } } } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['label']['vendor_id'] == 100 assert result['label']['subaccount_id'] == 10 assert result['label']['name'] == 'Subaccount Name' assert result['label']['vendor']['name'] == 'Parent Label' assert result['label']['vendor']['content_review_note'] == 'Parent note' assert result['label']['vendor']['service_tier']['name'] == 'premium' assert result['label']['vendor']['service_tier']['display_name'] == 'Premium' def test_get_complete_product_document_with_artists(): """Test get_complete_product_document with artists.""" mock_product_metadata = { 'productId': '12345', 'artists': [ { 'artistId': '1', 'artistName': 'Artist One', 'artistType': 'primary_artist' }, { 'artistId': '2', 'artistName': 'Artist Two', 'artistType': 'featuring' } ] } result = product_metadata.get_complete_product_document(mock_product_metadata) assert len(result['artists']) == 2 assert result['artists'][0]['artistName'] == 'Artist One' assert result['artists'][1]['artistType'] == 'featuring' def test_get_complete_product_document_with_tracks(): """Test get_complete_product_document with tracks.""" mock_product_metadata = { 'productId': '12345', 'tracks': [ { 'trackNumber': 1, 'trackName': 'Track One', 'isrc': 'USABC1234567', 'durationMinutes': 3, 'durationSeconds': 45 } ] } result = product_metadata.get_complete_product_document(mock_product_metadata) assert len(result['tracks']) == 1 assert result['tracks'][0]['trackName'] == 'Track One' assert result['tracks'][0]['isrc'] == 'USABC1234567' def test_get_complete_product_document_with_subgenre(): """Test get_complete_product_document with subgenre and genre.""" mock_product_metadata = { 'productId': '12345', 'subgenre': { 'id': 100, 'name': 'Alternative Rock', 'genre': { 'id': 10, 'name': 'Rock' } } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['subgenre']['id'] == 100 assert result['subgenre']['name'] == 'Alternative Rock' assert result['subgenre']['genre']['id'] == 10 assert result['subgenre']['genre']['name'] == 'Rock' def test_get_complete_product_document_with_review_history(): """Test get_complete_product_document with review history.""" mock_product_metadata = { 'productId': '12345', 'reviewHistory': { 'totalCount': 2, 'items': [ { 'createdDatetime': '2026-03-01T10:00:00Z', 'userAction': 'approved', 'note': 'Looks good' } ] } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['review_history']['totalCount'] == 2 assert len(result['review_history']['items']) == 1 assert result['review_history']['items'][0]['userAction'] == 'approved' def test_get_complete_product_document_with_release_schedule(): """Test get_complete_product_document with release schedule.""" mock_product_metadata = { 'productId': '12345', 'releaseSchedule': { 'timed': { 'saleDateTime': '2026-06-01T00:00:00Z' } } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['release_schedule']['timed']['saleDateTime'] == '2026-06-01T00:00:00Z' def test_get_complete_product_document_with_release_correction(): """Test get_complete_product_document with release correction.""" mock_product_metadata = { 'productId': '12345', 'releaseCorrection': { 'items': [ { 'keyId': '1', 'keyValue': 'New Value', 'tableName': 'releases', 'fieldName': 'product_name' } ] } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert len(result['release_correction']['items']) == 1 assert result['release_correction']['items'][0]['fieldName'] == 'product_name' def test_get_complete_product_document_with_localizations(): """Test get_complete_product_document with product and label localizations.""" mock_product_metadata = { 'productId': '12345', 'productLocalizations': [ { 'productName': 'Album en Español', 'deliveredVersion': 'v1.0', 'iTunesLanguage': { 'id': 'es', 'name': 'Spanish' } } ], 'labelParticipations': [ { 'participated_as': 'label', 'localizations': [ { 'language': { 'id': 'fr', 'name': 'French' }, 'localizedName': 'Label Français' } ] } ] } result = product_metadata.get_complete_product_document(mock_product_metadata) assert len(result['product_localizations']) == 1 assert result['product_localizations'][0]['productName'] == 'Album en Español' assert len(result['label_participations']) == 1 assert result['label_participations'][0]['participated_as'] == 'label' def test_get_complete_product_document_comprehensive(mock_graphql_response): """Test get_complete_product_document with comprehensive mock data.""" mock_product = mock_graphql_response['data']['product'] result = product_metadata.get_complete_product_document(mock_product) # Verify basic fields assert result['product_id'] == 1 assert result['product_name'] == 'Contest02' assert result['upc'] == '196292189827' assert result['format'] == 'Full Length' # Verify metadata language assert result['metadata_language']['code'] == 'ENG' assert result['metadata_language']['name'] == 'English' # Verify bulk session assert result['bulk_session']['id'] == 'test-bulk-session-id' # Verify label assert result['label']['vendor_id'] == 16160 assert result['label']['name'] == 'Non-Mechanical M/USD' # Verify artists assert len(result['artists']) == 4 assert result['artists'][0]['artistName'] == 'Sinaloha' # Verify tracks assert len(result['tracks']) == 1 # Verify pricing tiers assert result['album_pricing_tier'] is not None assert result['album_pricing_tier']['pricingFamily'] == 'MUSIC_ALBUM' assert result['track_pricing_tier'] is not None assert result['track_pricing_tier']['pricingFamily'] == 'MUSIC_TRACK' def test_get_complete_product_document_with_album_pricing_tier(): """Test get_complete_product_document with album pricing tier.""" mock_product_metadata = { 'productId': '12345', 'albumPricingTier': { 'pricingFamily': 'MUSIC_ALBUM', 'orchardPricingTier': { 'id': '1', 'name': 'Front Line', '__typename': 'OrchardPricingTier' }, 'productOverrides': [ { 'intervalStart': 1, 'intervalEnd': 10, 'orchardPricingTier': { 'id': '2', 'name': 'Mid Line' } } ] } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['album_pricing_tier'] is not None assert result['album_pricing_tier']['pricingFamily'] == 'MUSIC_ALBUM' assert result['album_pricing_tier']['orchardPricingTier']['name'] == 'Front Line' assert len(result['album_pricing_tier']['productOverrides']) == 1 def test_get_complete_product_document_with_track_pricing_tier(): """Test get_complete_product_document with track pricing tier.""" mock_product_metadata = { 'productId': '12345', 'trackPricingTier': { 'pricingFamily': 'MUSIC_TRACK', 'orchardPricingTier': { 'id': '1', 'name': 'Front Line' }, 'trackOverrides': [ { 'trackId': '1001', 'orchardPricingTier': { 'id': '3', 'name': 'Budget' } } ] } } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['track_pricing_tier'] is not None assert result['track_pricing_tier']['pricingFamily'] == 'MUSIC_TRACK' assert result['track_pricing_tier']['orchardPricingTier']['name'] == 'Front Line' assert len(result['track_pricing_tier']['trackOverrides']) == 1 def test_get_complete_product_document_without_pricing_tiers(): """Test get_complete_product_document without pricing tiers.""" mock_product_metadata = { 'productId': '12345', 'productName': 'Test Product' } result = product_metadata.get_complete_product_document(mock_product_metadata) assert result['album_pricing_tier'] is None assert result['track_pricing_tier'] is None