"""Product formatter tests.""" import pytest from switchboard_consumer.constants.deal_responsibilities \ import DIGITAL_DISTRIBUTION from switchboard_consumer.constants.message_fields import UPC from switchboard_consumer.constants.not_for_distribution import ( SWITCHBOARD_DUMMY) from switchboard_consumer.constants.special_instructions import ( NOTE_FEATURED_TO_PRIMARY_TEXT ) from switchboard_consumer.constants.system import ORCHARD from switchboard_consumer.formatters.product import ( format_assigned_responsibility, format_cline, format_create_product_input, format_genres, format_not_applicable_responsibility, format_pline, format_product_configuration, format_product_format, format_result_id, format_special_instructions, format_update_product_input, format_worldwide_responsibility, FormatterValidationError, get_company_code, orchard_has_responsibility) def test_format_create_product_input(primary_artists): """Test that format_create_product_input formats correctly.""" upc = '1234567890123' data = { 'ids': [{ 'system': 'SONY', 'localId': 12345, }], 'displayArtist': { 'name': 'Edguy' }, 'formalTitle': {'titleText': 'cool product'}, 'labelAccount': { 'companyCode': '1234', }, 'metaLanguage': 'nl', 'project': { 'ids': [ { 'system': 'SONY', 'localId': 12345, }, { 'system': 'ORCHARD', 'localId': 1899432, }, ] }, 'imprint': { 'name': 'an imprint', }, } expected_output = { 'productName': data['formalTitle']['titleText'], 'productHighlights': '-', 'projectId': data['project']['ids'][1]['localId'], 'accountId': 1234, 'subaccountId': None, 'upc': upc, 'metaLanguage': 'DUT', 'primaryArtists': primary_artists, 'genreId': None, 'imprint': 'an imprint', 'subgenreId': None, 'productCode': None, 'deliveredVersion': None, 'format': 'Full Length', 'productConfiguration': 'DIGITAL_AUDIO', 'cLine': '', 'specialInstructions': '', 'pLine': '', 'notForDistribution': SWITCHBOARD_DUMMY } formatted_input = format_create_product_input(upc, data, primary_artists) assert formatted_input == expected_output def test_format_update_product_input(primary_artists): """Test that format_update_product_input formats correctly.""" product_id = 23456 data = { 'ids': [ { 'system': 'SONY', 'localId': 12345, }, { 'system': 'ORCHARD', 'localId': 23456, }, ], 'displayArtist': { 'name': 'Edguy' }, 'formalTitle': {'titleText': 'cool product', 'subTitle': 'Sub title'}, 'cLine': { 'cLineText': 'Some cline text' }, 'imprint': { 'name': 'Imprint Name' }, 'metaLanguage': 'en', 'catalogNumber': 209430, 'labelAccount': { 'companyCode': '1234', }, 'project': { 'ids': [ { 'system': 'SONY', 'localId': 12345, }, { 'system': 'ORCHARD', 'localId': 1899432, }, ] }, 'switchboardExtensions': { 'governingDeal': { 'dealResponsibilities': [ { 'dealResponsibilityType': { 'name': 'Digital Distribution' }, 'appliesTo': 'WORLDWIDE', 'assignments': [ { 'system': 'ORCHARD' } ] } ] } } } expected_output = { 'productId': product_id, 'cLine': data['cLine']['cLineText'], 'productName': data['formalTitle']['titleText'], 'imprint': data['imprint']['name'], 'primaryArtists': primary_artists, 'metaLanguage': 'ENG', 'genreId': None, 'subgenreId': None, 'productCode': data['catalogNumber'], 'deliveredVersion': data['formalTitle']['subTitle'], 'format': 'Full Length', 'productConfiguration': 'DIGITAL_AUDIO', 'notForDistribution': 'N', 'specialInstructions': 'Switchboard Deal Summary:\nDigital Distribution: ORCHARD WORLDWIDE', # noqa 'pLine': '' } formatted_input = format_update_product_input(product_id, data, primary_artists) assert formatted_input == expected_output def test_format_update_product_c_line(primary_artists): """Test that we format invalid string sequence out of cLine.""" product_id = 23456 data = { 'displayArtist': { 'name': 'Edguy' }, 'cLine': { 'cLineText': 'Some cline text' }, } expected_output = { 'cLine': 'Some cline text', 'productId': 23456, 'primaryArtists': primary_artists, 'imprint': None, 'metaLanguage': None, 'productName': None, 'deliveredVersion': None, 'genreId': None, 'subgenreId': None, 'productCode': None, 'format': 'Full Length', 'productConfiguration': 'DIGITAL_AUDIO', 'notForDistribution': 'SwitchboardDummy', 'specialInstructions': '', 'pLine': '' } formatted_input = format_update_product_input(product_id, data, primary_artists) assert formatted_input == expected_output def test_format_update_product_from_sme_enricher(primary_artists): """Test that we set correct notFoDistribution in SmeAnalyticsIngest.""" product_id = 23456 data = { 'displayArtist': { 'name': 'Edguy' }, 'cLine': { 'cLineText': 'Some cline text' }, 'smeAnalyticsIngest': True, } expected_output = { 'cLine': 'Some cline text', 'productId': 23456, 'primaryArtists': primary_artists, 'imprint': None, 'metaLanguage': None, 'productName': None, 'deliveredVersion': None, 'genreId': None, 'subgenreId': None, 'productCode': None, 'format': 'Full Length', 'productConfiguration': 'DIGITAL_AUDIO', 'notForDistribution': 'SmeAnalyticsIngestionNotForDistribution', 'specialInstructions': '', 'pLine': '' } formatted_input = format_update_product_input(product_id, data, primary_artists) assert formatted_input == expected_output def test_format_default_product_c_line_from_p_line(primary_artists): """Test that we format invalid string sequence out of cLine.""" product_id = 23456 data = { 'displayArtist': { 'name': 'Edguy' }, 'pLine': { 'pLineText': 'Some pline text' } } expected_output = { 'cLine': 'Some pline text', 'productId': 23456, 'primaryArtists': primary_artists, 'imprint': None, 'metaLanguage': None, 'productName': None, 'deliveredVersion': None, 'genreId': None, 'subgenreId': None, 'productCode': None, 'format': 'Full Length', 'productConfiguration': 'DIGITAL_AUDIO', 'notForDistribution': 'SwitchboardDummy', 'specialInstructions': '', 'pLine': 'Some pline text' } formatted_input = format_update_product_input(product_id, data, primary_artists) assert formatted_input == expected_output def test_format_create_with_genre_data(primary_artists): """Test that we set genre fields correctly on create.""" upc = '1234567890123' data = { 'ids': [{ 'system': 'SONY', 'localId': 12345, }], 'displayArtist': { 'name': 'Edguy' }, 'genres': [ { 'system': 'ORCHARD', 'genreId': 1, 'subGenres': [{'subGenreId': 10}] }, { 'system': 'SONY', 'genreId': 20, 'subGenres': [{'subGenreId': 47}] } ], 'formalTitle': {'titleText': 'cool product'}, 'labelAccount': { 'companyCode': '1234', }, 'project': { 'ids': [ { 'system': 'SONY', 'localId': 12345, }, { 'system': 'ORCHARD', 'localId': 1899432, }, ] } } expected_output = { 'productName': data['formalTitle']['titleText'], 'productHighlights': '-', 'projectId': data['project']['ids'][1]['localId'], 'accountId': 1234, 'subaccountId': None, 'metaLanguage': None, 'upc': upc, 'primaryArtists': primary_artists, 'genreId': 1, 'imprint': None, 'subgenreId': 10, 'productCode': None, 'deliveredVersion': None, 'format': 'Full Length', 'productConfiguration': 'DIGITAL_AUDIO', 'cLine': '', 'specialInstructions': '', 'pLine': '', 'notForDistribution': SWITCHBOARD_DUMMY } formatted_input = format_create_product_input(upc, data, primary_artists) assert formatted_input == expected_output def test_format_update_with_genre_data(primary_artists): """Test that we set genre fields correctly on update.""" product_id = 23456 data = { 'displayArtist': { 'name': 'Edguy' }, 'genres': [ { 'system': 'ORCHARD', 'genreId': 1, 'subGenres': [{'subGenreId': 10}] }, { 'system': 'SONY', 'genreId': 20, 'subGenres': [{'subGenreId': 47}] } ], 'cLine': { 'cLineText': 'Some cline text' }, } expected_output = { 'cLine': 'Some cline text', 'productId': 23456, 'primaryArtists': primary_artists, 'imprint': None, 'metaLanguage': None, 'productName': None, 'deliveredVersion': None, 'genreId': 1, 'subgenreId': 10, 'productCode': None, 'format': 'Full Length', 'productConfiguration': 'DIGITAL_AUDIO', 'notForDistribution': 'SwitchboardDummy', 'specialInstructions': '', 'pLine': '' } formatted_input = format_update_product_input(product_id, data, primary_artists) assert formatted_input == expected_output def test_format_result_id(): """Test that format_result_id formats an id correctly.""" insert_id = 12345 original_id = { 'businessKey': '123456789012', 'businessKeyType': UPC, } expected_output = [{ 'localId': str(insert_id), 'businessKey': original_id['businessKey'], 'businessKeyType': original_id['businessKeyType'], 'system': ORCHARD, }] formatted_result_id = format_result_id(insert_id, original_id) assert formatted_result_id == expected_output @pytest.mark.parametrize('test_input,expected', [ (None, None), ({'companyCode': '1234'}, 1234) ]) def test_format_subaccount(test_input, expected): """Test that format_subaccount formats correctly.""" output = get_company_code(test_input) assert output == expected @pytest.mark.parametrize('genre_data,expected', [ ({'genres': [ {'system': 'ORCHARD', 'genreId': 1, 'subGenres': [{'subGenreId': 40}]}, {'system': 'SONY', 'genreId': 5, 'subGenres': [{'subGenreId': 31}]} ]}, (1, 40)), ({'genres': [ {'system': 'ORCHARD', 'genreId': 1}, {'system': 'SONY', 'genreId': 5, 'subGenres': [{'subGenreId': 31}]} ]}, (1, 1039)), ({'genres': [ {'system': 'ORCHARD', 'genreId': 1, 'subGenres': [{'invalidKey': None}]}, {'system': 'SONY', 'genreId': 5, 'subGenres': [{'subGenreId': 31}]} ]}, (1, 1039)), ({'genres': [ {'system': 'ORCHARD', 'genreId': 1, 'subGenres': None, }, {'system': 'SONY', 'genreId': 5, 'subGenres': None} ]}, (1, 1039)), ({'genres': [ {'system': 'ORCHARD', 'genreId': 1, 'subGenres': [], }, {'system': 'SONY', 'genreId': 5, 'subGenres': []} ]}, (1, 1039)) ]) def test_genre_formatter(genre_data, expected): """Validate genre formatting.""" genres_tuple = format_genres(genre_data) assert genres_tuple == expected def test_invalid_genre_mapping(): """Test not passing Orchard system genre results in a failure.""" genre_data = {'genres': [ {'system': 'INVALID_SYSTEM', 'genreId': 1, 'subGenres': [{'subGenreId': 40}]}, {'system': 'SONY', 'genreId': 5, 'subGenres': [{'subGenreId': 31}]} ]} with pytest.raises(FormatterValidationError): format_genres(genre_data) @pytest.mark.parametrize('data,expected_output', [ ({}, 'DIGITAL_AUDIO'), ({'releaseType': None}, 'DIGITAL_AUDIO'), ({'releaseType': 'UNKNOWN'}, 'DIGITAL_AUDIO'), ({'releaseType': 'VIDEO_SINGLE'}, 'MUSIC_VIDEO'), ({'releaseType': 'VIDEO_ALBUM'}, 'MUSIC_VIDEO'), ({'releaseType': 'SINGLE'}, 'DIGITAL_AUDIO'), ({'releaseType': 'ALBUM'}, 'DIGITAL_AUDIO'), ({'releaseType': 'BUNDLE'}, 'DIGITAL_AUDIO'), ]) def test_format_product_configuration(data, expected_output): """Test product configuration field is formatted correctly.""" output = format_product_configuration(data) assert output == expected_output @pytest.mark.parametrize( 'data,expected_output', [ ({}, 'Full Length'), ({'releaseType': None}, 'Full Length'), ({'releaseType': 'UNKNOWN'}, 'Full Length'), ({'releaseType': 'SINGLE'}, 'Single'), ({'releaseType': 'ALBUM'}, 'Full Length'), ({'releaseType': 'DIGITAL_AUDIO_EXTENDED_PLAY'}, 'EP'), ]) def test_format_product_format(data, expected_output): """Test that product format field is mapped correctly.""" output = format_product_format(data) assert output == expected_output def test_orchard_has_responsibility_returns_true_if_assigned(mock_logger): """Test responsibility check works.""" graphql_json = { 'switchboardExtensions': { 'governingDeal': { 'dealResponsibilities': [ { 'dealResponsibilityType': { 'dealResponsibilityTypeId': 1, 'name': 'Physical Distribution' }, 'assignments': [ { 'system': 'SONY' } ] }, { 'dealResponsibilityType': { 'dealResponsibilityTypeId': 1, 'name': 'Digital Distribution' }, 'assignments': [ { 'system': 'ORCHARD' } ] } ] } } } result = orchard_has_responsibility( mock_logger, graphql_json, DIGITAL_DISTRIBUTION) assert result is True def test_orchard_has_responsibility_returns_false_if_not_assigned(mock_logger): """Test responsibility check works.""" graphql_json = { 'switchboardExtensions': { 'governingDeal': { 'dealResponsibilities': [ { 'dealResponsibilityType': { 'dealResponsibilityTypeId': 1, 'name': 'Physical Distribution' }, 'assignments': [ { 'system': 'SONY' } ] }, { 'dealResponsibilityType': { 'dealResponsibilityTypeId': 1, 'name': 'Digital Distribution' }, 'assignments': [ { 'system': 'SONY' } ] } ] } } } result = orchard_has_responsibility( mock_logger, graphql_json, DIGITAL_DISTRIBUTION) assert result is False @pytest.mark.parametrize('special_instructions_data,expected_output', [ ([ { 'dealResponsibilityType': { 'dealResponsibilityTypeId': '2', 'name': 'Copyright Administration' }, 'appliesTo': 'WORLDWIDE', 'assignments': [ { 'scope': None, 'system': 'ORCHARD', 'territories': [ ] } ] }, ], ('Switchboard Deal Summary:\n' 'Copyright Administration: ORCHARD WORLDWIDE' )), ([ { 'dealResponsibilityType': { 'dealResponsibilityTypeId': '2', 'name': 'Copyright Administration' }, 'appliesTo': 'NOT_APPLICABLE', 'assignments': [] }, ], ('Switchboard Deal Summary:\n' 'Copyright Administration: NOT_APPLICABLE' )), ([ { 'dealResponsibilityType': { 'dealResponsibilityTypeId': '2', 'name': 'Copyright Administration' }, 'appliesTo': 'SPECIFIC_TERRITORIES', 'assignments': [ { 'scope': 'INCLUDED', 'system': 'ORCHARD', 'territories': [ 'BN', 'KH', 'CN', 'GE', 'HK', 'IN' ] }, { 'scope': 'INCLUDED', 'system': 'SONY', 'territories': [ 'HR', 'CY', 'CZ', 'EE', 'FO', 'FR', 'GI', 'GB', 'GR', 'GG', 'HU', ] }, ] }, ], ('Switchboard Deal Summary:\n' 'Copyright Administration: ORCHARD - includes BN, KH, CN, GE, HK, IN\n' # noqa 'Copyright Administration: SONY - includes GB, FR, HR, CY, CZ, EE, FO, GI, GR, GG and some other countries' # noqa )), ]) def test_format_special_instructions( special_instructions_data, expected_output): """Test special instructions formatter.""" output = format_special_instructions({ 'switchboardExtensions': { 'governingDeal': { 'dealResponsibilities': special_instructions_data } } }) assert output == expected_output def test_format_special_instructions_with_featured_to_primary( sony_product_featured_to_primary): """Test special instructions formatter.""" output = format_special_instructions(sony_product_featured_to_primary) assert output.startswith(NOTE_FEATURED_TO_PRIMARY_TEXT) def test_format_not_applicable_responsibility(): """Test not applicable responsibility formatter.""" responsibility = { 'dealResponsibilityType': { 'dealResponsibilityTypeId': '2', 'name': 'A responsibility name' }, 'appliesTo': 'NOT_APPLICABLE', 'assignments': [] } output = format_not_applicable_responsibility(responsibility) assert output == 'A responsibility name: NOT_APPLICABLE' def test_format_worldwide_responsibility(): """Test worldwide responsibility formatter.""" responsibility = { 'dealResponsibilityType': { 'dealResponsibilityTypeId': '2', 'name': 'A responsibility name' }, 'appliesTo': 'WORLDWIDE', 'assignments': [ { 'scope': None, 'system': 'ORCHARD', 'territories': [ ] } ] } output = format_worldwide_responsibility(responsibility) assert output == 'A responsibility name: ORCHARD WORLDWIDE' @pytest.mark.parametrize('assignment,expected_output', [ ({ 'scope': 'INCLUDED', 'system': 'ORCHARD', 'territories': [ 'BN', 'KH', 'CN', 'GE', 'HK', 'IN', 'GB' ] }, ('A responsibility name: ORCHARD' ' - includes GB, BN, KH, CN, GE, HK, IN') ), ({ 'scope': 'INCLUDED', 'system': 'ORCHARD', 'territories': [ 'HR', 'CY', 'CZ', 'EE', 'FO', 'FR', 'GI', 'GB', 'GR', 'GG', 'HU', ] }, ('A responsibility name: ORCHARD - includes ' 'GB, FR, HR, CY, CZ, EE, FO, GI, GR, GG ' 'and some other countries') ), ({ 'scope': 'INCLUDED', 'system': 'ORCHARD', 'territories': [ ] }, ('A responsibility name: ORCHARD - includes ' 'no territories') ), ({ 'scope': 'EXCLUDED', 'system': 'ORCHARD', 'territories': [ ] }, ('A responsibility name: ORCHARD - excludes ' 'no territories') ), ]) def test_format_assigned_responsibility(assignment, expected_output): """Test assignment responsibility formatter.""" responsibility = { 'dealResponsibilityType': { 'dealResponsibilityTypeId': '2', 'name': 'A responsibility name' }, 'appliesTo': 'SPECIFIC_TERRITORIES', } output = format_assigned_responsibility(responsibility, assignment) assert output == expected_output @pytest.mark.parametrize( 'cline,expected_cline', [ ({'cLine': None}, ''), ({'cLine': {'cLineText': None}}, ''), ({'cLine': {'cLineText': 'a great cline'}}, 'a great cline'), ({'cLine': {'cLineText': 'a great cline'}, 'pLine': {'pLineText': 'a great pline'}}, 'a great cline'), ({'pLine': {'pLineText': 'a great pline'}}, 'a great pline'), (None, '') ] ) def test_format_cline(cline, expected_cline): """Test format cLine.""" formatted_cline = format_cline(cline) assert formatted_cline == expected_cline @pytest.mark.parametrize( 'pline,expected_pline', [ ({'pLine': None}, ''), ({'pLine': {'pLineText': None}}, ''), ({'pLine': {'pLineText': 'a great pline'}}, 'a great pline'), ] ) def test_format_pline(pline, expected_pline): """Test format cLine.""" formatted_cline = format_pline(pline) assert formatted_cline == expected_pline