"""Test handler.""" from unittest.mock import MagicMock, patch from constants import queries from constants.exceptions import ( DuplicateParticipantException, TrackPerformerTypeException ) from constants.roles import ORCHARD_ROLES from ddex_ingester_common.lambda_exceptions import SetTrackMetadataException import pytest from utils import track_utils from utils.track_utils import ( add_track_artist, add_track_performer, create_tracks, delete_tracks, format_create_track_data, get_all_roles, get_context_participant, get_orchard_tracks, get_track_participants, sanitize_lyrics ) @pytest.mark.parametrize( 'execution_response', [ pytest.param( 'test_get_orchard_tracks_response', id='Has Tracks'), pytest.param( 'test_get_empty_orchard_tracks_response', id='Has No Tracks') ], ) @patch('index.graphql_gateway.execute') def test_get_orchard_tracks( mock_gateway_execute, execution_response, request): """Test get_orchard_tracks function.""" # Vars upc = '1234567890987' execution_response = request.getfixturevalue(execution_response) mock_gateway_execute.return_value = { 'data': { 'productByUpc': { 'tracks': execution_response } } } tracks = get_orchard_tracks(upc, logger=MagicMock()) assert len(tracks) == len(execution_response) mock_gateway_execute.assert_called_once_with( queries.GET_ORCHARD_TRACKS, {'upc': '1234567890987'} ) @patch('utils.track_utils.graphql_gateway.execute') def test_delete_tracks( mock_gateway_execute, test_get_orchard_tracks_response): """Test delete_tracks function.""" test_product_id = '12345' # Make a tuid list from the existing fixture test_tuids = [t['tuid'] for t in test_get_orchard_tracks_response] delete_tracks(test_product_id, test_tuids, logger=MagicMock()) mock_gateway_execute.assert_called_once_with( queries.SAVE_TRACKS, {'data': { 'delete': { 'productId': test_product_id, 'tracks': test_tuids } }} ) @patch('utils.track_utils.graphql_gateway.execute') def test_delete_tracks_skipped( mock_gateway_execute, test_get_empty_orchard_tracks_response): """Test delete_tracks function when product_id or tuids is None.""" test_product_id = '12345' delete_tracks( test_product_id, test_get_empty_orchard_tracks_response, logger=MagicMock()) mock_gateway_execute.assert_not_called() @patch('utils.track_utils.graphql_gateway.execute') @patch('utils.track_utils.save_catalog_ingestion_action') def test_create_tracks( mock_save_catalog_ingestion_action, mock_gateway_execute, test_create_tracks_payload, test_create_tracks_response, test_event): """Test create_tracks function.""" mock_gateway_execute.return_value = { 'data': { 'saveTracks': test_create_tracks_response } } logger = MagicMock() release = MagicMock() result = create_tracks( test_event, release, test_create_tracks_payload, logger ) assert result == test_create_tracks_response mock_save_catalog_ingestion_action.assert_called_once() assert len(mock_save_catalog_ingestion_action.call_args.args) == 4 mock_gateway_execute.assert_called_once_with( queries.SAVE_TRACKS, {'data': test_create_tracks_payload} ) @patch('utils.track_utils.get_country_id') def test_format_create_track_data( mock_get_country_id, test_get_track_participants_response, test_format_create_track_data_response, test_model): """Tests the format_create_track_data function with valid input.""" upc = '197188854119' track_key = 'BCL0B2000004_1_1' track = test_model.tracks[track_key] mock_get_country_id.return_value = 123 result = format_create_track_data( test_get_track_participants_response, upc, track) assert result == test_format_create_track_data_response def test_add_track_artist( test_label_participant_uuid, test_performer, test_track_performers_result): """Test add_track_artist() function.""" track_performers = [] add_track_artist( test_label_participant_uuid, test_performer, track_performers ) assert track_performers == test_track_performers_result[:1] def test_add_track_performer( test_add_track_performers, test_add_track_performers_result): """Test adding a track performer.""" # Create empty list track_performers = [] # Test adding a new performer new_performer = test_add_track_performers['performers'][0] add_track_performer(new_performer, track_performers, ORCHARD_ROLES) # Assert matching out is created. assert test_add_track_performers_result['performers'][0] in track_performers # noqa assert len(track_performers) == 1 # Test adding a duplicate performer is skipped add_track_performer(new_performer, track_performers, ORCHARD_ROLES) assert len(track_performers) == 1 # Test adding a second performer new_performer = test_add_track_performers['performers'][1] add_track_performer(new_performer, track_performers, ORCHARD_ROLES) assert test_add_track_performers_result['performers'][1] in track_performers # noqa assert len(track_performers) == 2 # Test adding an invalid performer role with pytest.raises(SetTrackMetadataException): invalid_performer = { 'name': 'Invalid Performer', 'role': 'invalid_role', 'type': 'featured', } add_track_performer(invalid_performer, track_performers, ORCHARD_ROLES) def test_get_all_roles(test_model, test_all_roles_result): """Test get_all_roles() function.""" # Get a track from the test data model track_key = 'BCL0B2000004_1_1' track = test_model.tracks[track_key] # Call function with test data result = get_all_roles( track, test_model.genre, test_model.subgenre, logger=MagicMock()) # Check that expected keys are present in result assert result == test_all_roles_result # TODO: This whole test suite should be moved to pre-flight @pytest.mark.parametrize( 'test_field, expected_exception', [ pytest.param( 'performer_1_type', TrackPerformerTypeException, id='Performer Type Fails') ]) def test_get_all_roles_artist_fails( test_field, expected_exception, test_model): """Test that get_all_roles() function fails.""" # Get a track from the test data model track_key = 'BCL0B2000004_1_1' # Get a track from the model track = test_model.tracks[track_key] # Set the genre genre = test_model.genre # Set the subgenre subgenre = test_model.subgenre # Overrides # test_field == 'performer_1_type' track = track._track._replace(performer_1_type='Invalid Type') # Check exception is thrown with pytest.raises(expected_exception): # Call function with test data get_all_roles(track, genre, subgenre, MagicMock()) def test_get_track_participants( mocker, test_event, test_track, test_get_all_roles_response, test_get_track_participants_response): """Test the get_track_participants function.""" # Define spys spy_add_artist = mocker.spy(track_utils, 'add_track_artist') spy_add_performer = mocker.spy(track_utils, 'add_track_performer') spy_get_participant = mocker.spy(track_utils, 'get_context_participant') # Call the function result = get_track_participants( test_track, test_event['release']['participants'], test_get_all_roles_response, logger=MagicMock()) # Assert that the expected functions were called appropriately assert spy_add_artist.call_count == 3 assert spy_add_performer.call_count == 1 assert spy_get_participant.call_count == 4 assert result == test_get_track_participants_response def test_get_context_participant_with_matching_name( test_event): """Test get_context_participant returns the correct participant.""" test_release_participants = test_event['release']['participants'] # Valid name name_to_find = 'Rosário Negro' expected_result = test_release_participants[0] result = get_context_participant(test_release_participants, name_to_find) assert result == expected_result def test_get_context_participant_with_no_matching_name( test_event): """Test get_context_participant returns None when name doesn't match.""" test_release_participants = test_event['release']['participants'] # Invalid name name_to_find = 'Bob' result = get_context_participant(test_release_participants, name_to_find) assert result is None def test_get_context_participant_with_duplicate_names( test_event): """Test get_context_participant raises an exception on duplicate name.""" test_release_participants = test_event['release']['participants'] # Valid name name_to_find = 'Rosário Negro' # Add an ad-hoc duplicate participant to the list test_release_participants.append({ 'name': 'Rosário Negro', 'artist_id': '3002836', 'label_participant_id': '1682997067932', 'label_participant_uuid': '02b95897-49c9-49f9-b4f4-6127f48b4c66' }) # Pass duped set with pytest.raises(DuplicateParticipantException): get_context_participant(test_release_participants, name_to_find) def test_sanitize_lyrics(): """Test sanitize_lyrics strips values.""" lyrics = 'Special lyrics ../' expected = 'Special lyrics' sanitized = sanitize_lyrics(lyrics) assert sanitized == expected