"""Tests for ParticpantHandlers.""" from mock import Mock import pytest from switchboard_consumer.constants.exceptions import ( ParticipantHandlerGraphQLError) from switchboard_consumer.constants.participant_roles import PRIMARY_ARTIST from switchboard_consumer.logic.participant.product_participant_handler \ import BaseParticipantHandler def test_get_artist(mock_logger, orchard_client, create_product_message): """Test get artist.""" vendor_id = '2000' get_artist_results = { 'artistId': '123', 'artistName': 'Test Artist', 'artistType': 'artist', 'vendorId': vendor_id } orchard_client.get_artist = Mock(return_value=get_artist_results) participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) result = participant_handler._get_artist('AIID:123') assert result == get_artist_results def test_get_artist_error(mock_logger, orchard_client, create_product_message): """Test get artist with error.""" get_artist_results = {'errors': [ { 'extensions': { 'code': 'error_code', }, 'message': 'An error message', } ]} expected_error = [{'code': 'error_code', 'message': 'An error message'}] orchard_client.get_artist = Mock(return_value=get_artist_results) vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) with pytest.raises(ParticipantHandlerGraphQLError) as exception: participant_handler._get_artist('AIID:123') assert exception.value.raw_errors == expected_error def test_create_artist(mock_logger, orchard_client, create_product_message): """Test create artist.""" create_artist_results = { 'artistId': '123', 'artistName': 'Test Artist', 'artistType': 'artist', 'vendorId': '2000' } expected_artist_result = { 'artistInfoId': 123, 'artistName': 'Test Artist', 'artistType': 'primary_artist' } sony_mapping = { 'localId': '5000', 'system': 'SONY' } expected_mapping = [ sony_mapping, { 'localId': 'AIID:123', 'system': 'ORCHARD' } ] orchard_client.create_artist = Mock(return_value=create_artist_results) vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) processing_result, artist = participant_handler._create_artist( {'name': create_artist_results['artistName']}, PRIMARY_ARTIST, sony_mapping ) assert processing_result.get('ids') == expected_mapping assert artist == expected_artist_result, 'Invalid create artist result' def test_create_artist_error(mock_logger, orchard_client, create_product_message): """Test create artist with error.""" create_artist_results = {'errors': [ { 'extensions': { 'code': 'error_code', }, 'message': 'An error message', } ]} expected_error = [{'code': 'error_code', 'message': 'An error message'}] sony_mapping = { 'localId': '5000', 'system': 'SONY' } orchard_client.create_artist = Mock(return_value=create_artist_results) vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) with pytest.raises(ParticipantHandlerGraphQLError) as exception: participant_handler._create_artist( {'name': 'Arty McArtist'}, 'performer', sony_mapping ) assert exception.value.raw_errors == expected_error def test_build_result_mapping_with_role(mock_logger, orchard_client, create_product_message): """Test build result mapping with role.""" create_artist_results = { 'artistId': '123', 'artistName': 'Test Artist', 'artistType': 'artist', 'vendorId': '2000' } sony_mapping = { 'localId': '5000', 'system': 'SONY' } expected_mapping = [ sony_mapping, { 'localId': 'AIID:123', 'system': 'ORCHARD' } ] role = 'performer' expected_formatted_artist = { 'artistInfoId': 123, 'artistName': 'Test Artist', 'artistType': role } vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None ) (processing_result, artist) = participant_handler._build_result_mapping( sony_mapping, create_artist_results, role ) assert processing_result.get('ids') == expected_mapping assert artist == expected_formatted_artist def test_handle_participant_without_mapping(mock_logger, orchard_client, create_product_message): """Test participant handling without a mapping.""" vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) participant = { 'name': 'Arty McArtist' } artist_name = participant['name'] role = 'Performer' source_mapping = { 'localId': '8888', 'system': 'SONY' } target_mapping = None mock_get_artist = Mock() mock_find_artists = Mock(return_value=[]) mock_create_artist = Mock() participant_handler._get_artist = mock_get_artist participant_handler._find_artists = mock_find_artists participant_handler._create_artist = mock_create_artist participant_handler.handle_participant(participant, role, source_mapping, target_mapping) # Not called as there is no target mapping to get an ID for mock_get_artist.assert_not_called() # Tries to find an artist on vendor by name mock_find_artists.assert_called_with(artist_name) # No artist found on vendor with matching name, create it instead mock_create_artist.assert_called_with(participant, role, source_mapping) def test_handle_participant_with_mapping(mock_logger, orchard_client, create_product_message): """Test participant handling with a mapping.""" vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) orchard_local_id = 'AIID:1234' participant = { 'name': 'Arty McArtist' } artist_name = participant['name'] role = 'Performer' source_mapping = { 'localId': '8888', 'system': 'SONY' } target_mapping = { 'localId': orchard_local_id, 'system': 'ORCHARD' } mock_get_artist = Mock(return_value={ 'artistId': orchard_local_id, 'artistName': artist_name, 'artistType': 'artist', 'vendorId': vendor_id }) mock_find_artists = Mock(return_value=[]) mock_create_artist = Mock() participant_handler._get_artist = mock_get_artist participant_handler._find_artists = mock_find_artists participant_handler._create_artist = mock_create_artist participant_handler.handle_participant(participant, role, source_mapping, target_mapping) mock_get_artist.assert_called_with(orchard_local_id) # A valid artist mapping was found, find and create should not be called mock_find_artists.assert_not_called() mock_create_artist.assert_not_called() def test_handle_participant_with_invalid_mapping(mock_logger, orchard_client, create_product_message): """Test participant handling with a mapping that is invalid.""" vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) orchard_local_id = 'AIID:1234' participant = { 'name': 'Arty McArtist' } artist_name = participant['name'] role = 'Performer' source_mapping = { 'localId': '8888', 'system': 'SONY' } target_mapping = { 'localId': orchard_local_id, 'system': 'ORCHARD' } mock_get_artist = Mock(return_value={ 'artistId': orchard_local_id, 'artistName': artist_name, 'artistType': 'artist', 'vendorId': '77777' # A different vendor id than our target }) mock_find_artists = Mock(return_value=[]) mock_create_artist = Mock() participant_handler._get_artist = mock_get_artist participant_handler._find_artists = mock_find_artists participant_handler._create_artist = mock_create_artist participant_handler.handle_participant(participant, role, source_mapping, target_mapping) # Vendor ID returned for mapping does not match target vendor mock_get_artist.assert_called_with(orchard_local_id) # We should try to find artist with target name on vendor mock_find_artists.assert_called_with(artist_name) # When none are found we should create an artist against the vendor mock_create_artist.assert_called_with(participant, role, source_mapping) def test_handle_participant_without_mapping_but_existing_vendor_artist( mock_logger, orchard_client, create_product_message): """Test without mapping but finds a vendor artist to use.""" vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) orchard_local_id = '575757' participant = { 'name': 'Arty McArtist' } artist_name = participant['name'] role = 'Performer' source_mapping = { 'localId': '8888', 'system': 'SONY' } target_mapping = None # No target mapping mock_build_result_mapping = Mock() found_artists = [ { 'artistName': artist_name, 'artistType': 'artist', 'artistId': orchard_local_id }, { 'artistName': 'Some duplicate artist on vendor', 'artistType': 'artist', 'artistId': '12345675664' } ] mock_get_artist = Mock() # An existing vendor artist matching the name we want mock_find_artists = Mock(return_value=found_artists) mock_create_artist = Mock() participant_handler._get_artist = mock_get_artist participant_handler._find_artists = mock_find_artists participant_handler._create_artist = mock_create_artist participant_handler._build_result_mapping = mock_build_result_mapping participant_handler.handle_participant(participant, role, source_mapping, target_mapping) # Not called as there is no target mapping to get an ID for mock_get_artist.assert_not_called() # Tries to find an artist on vendor by name mock_find_artists.assert_called_with(artist_name) # Artists have been found on target vendor # The first matched artist should be used and returned mock_create_artist.assert_not_called() mock_build_result_mapping.assert_called_with(source_mapping, found_artists[0], role) def test_handle_participant_with_invalid_mapping_but_existing_vendor_artist( mock_logger, orchard_client, create_product_message): """Test with mapping that is invalid but finds a vendor artist to use.""" vendor_id = '12345' participant_handler = BaseParticipantHandler(mock_logger, orchard_client, create_product_message, vendor_id, None) orchard_local_id = 'AIID:1234' participant = { 'name': 'Arty McArtist' } artist_name = participant['name'] role = 'Performer' source_mapping = { 'localId': '8888', 'system': 'SONY' } target_mapping = { 'localId': orchard_local_id, 'system': 'ORCHARD' } mock_build_result_mapping = Mock() mock_get_artist = Mock(return_value={ 'artistId': orchard_local_id, 'artistName': artist_name, 'artistType': 'artist', 'vendorId': '77777' # A different vendor id than our target }) found_artists = [ { 'artistName': artist_name, 'artistType': 'artist', 'artistId': orchard_local_id }, { 'artistName': 'Some duplicate artist on vendor', 'artistType': 'artist', 'artistId': '12345675664' } ] mock_find_artists = Mock(return_value=found_artists) mock_create_artist = Mock() participant_handler._get_artist = mock_get_artist participant_handler._find_artists = mock_find_artists participant_handler._create_artist = mock_create_artist participant_handler._build_result_mapping = mock_build_result_mapping participant_handler.handle_participant(participant, role, source_mapping, target_mapping) # Vendor ID returned for mapping does not match target vendor mock_get_artist.assert_called_with(orchard_local_id) # We should try to find artist with target name on vendor mock_find_artists.assert_called_with(artist_name) # Artists have been found on target vendor # The first matched artist should be used and returned mock_create_artist.assert_not_called() mock_build_result_mapping.assert_called_with(source_mapping, found_artists[0], role)