"""Tests for track metadata update logic.""" from mock import Mock, patch from switchboard_consumer.constants import product_status from switchboard_consumer.constants.entity_type import TRACK from switchboard_consumer.constants.exceptions import ( ParticipantHandlerError, ) from switchboard_consumer.constants.message_type import PROCESSING_RESULT from switchboard_consumer.logic.track_metadata_update import ( determine_track_update_method, handle_track_metadata_update) @patch(('switchboard_consumer.logic.' 'product_metadata_update.TrackParticipantHandler.process'), return_value=([], [], [])) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch('switchboard_consumer.logic.track_metadata_update.' 'LabelParticipantHandler') def test_handle_track_metadata_update_success( mock_label_participant_handler, mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1, sony_product): """Test for success of track metadata update.""" mock_logger = Mock() orchard_client = Mock() orchard_client.update_tracks.return_value = [ {'tuid': 1001}, {'tuid': 2001} ] orchard_client.get_track_by_tuid.return_value = { 'upc': '09876543210987' } swb_client = Mock() swb_client.get_product_by_upc.return_value = sony_product swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] mock_determine_track_update_method.return_value = ( [], update_track_payload.ids ) result = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del result[0]['messageCreatedDateTime'] del result[0]['messageId'] assert result == [ { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' }] def test_handle_track_metadata_update_fail_on_get_swb_track( update_track_payload): """Test for failure of track metadata update on swb track error.""" mock_logger = Mock() orchard_client = Mock() orchard_client.update_tracks.return_value = [ {'tuid': 1001}, {'tuid': 2001} ] swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = { 'errors': [ { 'extensions': { 'code': 'get_track_by_isrc_error_code', }, 'message': 'An error message', } ] } result = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del result[0]['messageCreatedDateTime'] del result[0]['messageId'] assert result == [ { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [ { 'code': 'get_track_by_isrc_error_code', 'message': 'An error message' } ], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' }] @patch(('switchboard_consumer.logic.' 'track_metadata_update.TrackParticipantHandler.process'), return_value=([], [], [])) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch('switchboard_consumer.logic.track_metadata_update.' 'LabelParticipantHandler') def test_handle_track_metadata_update_fail_on_update_orchard_track( mock_label_participant_handler, mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1, sony_product): """Test for failure of track metadata update on orchard track error.""" mock_logger = Mock() orchard_client = Mock() orchard_client.update_tracks.return_value = { 'errors': [ { 'extensions': { 'code': 'update_track_error_code', }, 'message': 'An error message', } ] } orchard_client.get_track_by_tuid.return_value = { 'upc': '09876543210987' } swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] swb_client.get_product_by_upc.return_value = sony_product mock_determine_track_update_method.return_value = ( [], update_track_payload.ids ) result = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del result[0]['messageCreatedDateTime'] del result[0]['messageId'] assert result == [ { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [ { 'code': 'update_track_error_code', 'message': 'An error message' } ], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' }] def test_handle_track_metadata_update_success_no_orchard_tracks( update_track_payload): """Test for success of track metadata update with no tracks mapping.""" mock_logger = Mock() orchard_client = Mock() swb_client = Mock() del update_track_payload.ids[1] del update_track_payload.ids[1] result = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) assert result == [] assert orchard_client.update_tracks.call_count == 0 assert swb_client.lookup_track_by_isrc.call_count == 0 @patch(('switchboard_consumer.logic.' 'product_metadata_update.TrackParticipantHandler.process'), return_value=([{ 'entityType': 'PARTICIPANT', 'messageType': 'METADATA_UPDATE' }], [{ 'artistInfoId': 123, 'artistName': 'Test Artist', 'artistType': 'primary_artist' }], [])) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch('switchboard_consumer.logic.track_metadata_update.' 'LabelParticipantHandler') def test_handle_track_metadata_update_success_with_participants( mock_label_participant_handler, mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1, sony_product): """Test that participant processing results get returned as well.""" mock_logger = Mock() orchard_client = Mock() orchard_client.update_tracks.return_value = [ {'tuid': 1001}, {'tuid': 2001} ] orchard_client.get_track_by_tuid.return_value = { 'upc': '09876543210987' } swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] swb_client.get_product_by_upc.return_value = sony_product mock_determine_track_update_method.return_value = ( [], update_track_payload.ids ) results = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del results[1]['messageCreatedDateTime'] del results[1]['messageId'] assert len(results) == 2 assert results == [ { 'entityType': 'PARTICIPANT', 'messageType': 'METADATA_UPDATE' }, { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' } ] @patch(('switchboard_consumer.logic.' 'product_metadata_update.TrackParticipantHandler.process')) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) def test_handle_track_metadata_update_success_with_participants_error( mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1, sony_product): """Test that participant errors are handled.""" exception_message = 'An error message for an exception in a handler' exception = ParticipantHandlerError(exception_message) expected_error = [{ 'code': 'daemon_exception', 'message': '{}: {}'.format(type(exception).__name__, exception) }] # Throw a ParticipantHandlerError from the participant handler mock_participant_handler.side_effect = Mock(side_effect=exception) mock_logger = Mock() orchard_client = Mock() orchard_client.get_track_by_tuid.return_value = { 'upc': '09876543210987' } swb_client = Mock() swb_client.get_product_by_upc.return_value = sony_product mock_determine_track_update_method.return_value = ( [], update_track_payload.ids ) swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] results = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) assert len(results) == 1 assert results[0]['errors'] == expected_error @patch(('switchboard_consumer.logic.participant.' 'track_participant_handler.TrackParticipantHandler.process'), return_value=([], [], [])) @patch(('switchboard_consumer.logic.' 'performer.track_performer_handler.TrackPerformerHandler.process'), return_value=[]) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch('switchboard_consumer.logic.track_metadata_update.' 'LabelParticipantHandler') def test_handle_track_metadata_update_success_with_performers( mock_label_participant_handler, mock_determine_track_update_method, mock_performer_handler, mock_participant_handler, update_track_payload, switchboard_track_item_1, sony_product): """Test for success of track metadata update with participants.""" publishers = switchboard_track_item_1['track']['publishers'] publishers[0]['ids'] = [ { 'system': 'SONY', 'localId': 'SONY:10001' } ] publishers[1]['ids'] = [ { 'system': 'SONY', 'localId': 'SONY:10002' }, { 'system': 'ORCHARD', 'localId': 'UNID:10002=' } ] publishers[2]['ids'] = [ { 'system': 'SONY', 'localId': 'SONY:10003' } ] publishers[3]['ids'] = [ { 'system': 'SONY', 'localId': 'SONY:10004' }, { 'system': 'ORCHARD', 'localId': 'UNID:10004=' } ] publishers[4]['ids'] = [ { 'system': 'SONY', 'localId': 'SONY:10005' } ] mock_logger = Mock() orchard_client = Mock() orchard_client.update_tracks.return_value = [ { 'tuid': 1001, 'isrc': 'USSM11307800', 'publishing': { 'publisherNames': [ 'B-Day Publishing', 'Solange MVP Publishing', 'Music World, LLC' ] } }, ] orchard_client.get_track_by_tuid.return_value = { 'upc': '09876543210987' } swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] swb_client.get_product_by_upc.return_value = sony_product mock_determine_track_update_method.return_value = ( [], update_track_payload.ids ) result = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del result[0]['messageCreatedDateTime'] del result[0]['messageId'] assert len(result) == 3 assert result[0] == { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' } assert result[1]['entityType'] == 'PUBLISHER' assert result[1]['ids'] == [ {'localId': 'SONY:10001', 'system': 'SONY'}, {'localId': 'UNID:vYfYGAAlgNwQ9CY0jJ+aM6TVZv4=', 'system': 'ORCHARD'}] assert result[2]['entityType'] == 'PUBLISHER' assert result[2]['ids'] == [ {'localId': 'SONY:10003', 'system': 'SONY'}, {'localId': 'UNID:xHckqjx1/C9bnth5LQtTxpCwnN4=', 'system': 'ORCHARD'}] def test_handle_track_metadata_update_fail_validation(update_track_payload): """Test track metadata update fails validation.""" mock_logger = Mock() orchard_client = Mock() response = { 'ids': [ { 'system': 'SONY', 'localId': 'D1631147620131205:' } ], 'isrc': 'USSM11307800', 'trackType': 'TRACK', 'pLine': { 'pLineText': '(p) 2013, Columbia Records, ' 'a Division of Sony Music Entertainment' }, } swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = response result = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) assert len(result) == 1 assert result[0]['entityType'] == TRACK assert result[0]['messageType'] == PROCESSING_RESULT assert result[0]['errors'][0]['code'] == 'validation' @patch(('switchboard_consumer.logic.' 'product_metadata_update.TrackParticipantHandler.process'), return_value=([{ 'entityType': 'PARTICIPANT', 'messageType': 'METADATA_UPDATE' }], [{ 'artistInfoId': 123, 'artistName': 'Test Artist', 'artistType': 'primary_artist' }], [])) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch(('switchboard_consumer.logic.' 'track_metadata_update.release_correct_product')) @patch('switchboard_consumer.logic.track_metadata_update.' 'LabelParticipantHandler') def test_handle_track_metadata_update_with_rc( mock_label_participant_handler, mock_release_correct_product, mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1, sony_product): """Test track with multiple mappings, one being associated with an RC""" mock_logger = Mock() orchard_client = Mock() orchard_client.update_tracks.return_value = [ {'tuid': 1001}, {'tuid': 2001} ] orchard_client.get_track_by_tuid.return_value = { 'upc': '09876543210987' } swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] swb_client.get_product_by_upc.return_value = sony_product mock_determine_track_update_method.return_value = ( [sony_product], [update_track_payload.ids[1]] ) rc_product_processing_result = { 'correlationId': update_track_payload.correlation_id, 'entityType': 'PRODUCT', 'errors': [], 'ids': [ { 'businessKey': '09876543210987', 'businessKeyType': 'UPC', 'localId': '1022869', 'system': 'SONY' }, { 'businessKey': '09876543210987', 'businessKeyType': 'UPC', 'localId': '123456', 'system': 'ORCHARD' } ], 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' } mock_release_correct_product.return_value = [ rc_product_processing_result ] results = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del results[2]['messageCreatedDateTime'] del results[2]['messageId'] assert len(results) == 3 assert results == [ rc_product_processing_result, { 'entityType': 'PARTICIPANT', 'messageType': 'METADATA_UPDATE' }, { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' } ] @patch(('switchboard_consumer.logic.' 'product_metadata_update.TrackParticipantHandler.process'), return_value=([{ 'entityType': 'PARTICIPANT', 'messageType': 'METADATA_UPDATE' }], [{ 'artistInfoId': 123, 'artistName': 'Test Artist', 'artistType': 'primary_artist' }], [])) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch(('switchboard_consumer.logic.' 'track_metadata_update.release_correct_product')) @patch('switchboard_consumer.logic.track_metadata_update.' 'LabelParticipantHandler') def test_handle_track_metadata_update_with_rc_only( mock_label_participant_handler, mock_release_correct_product, mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1, sony_product): """Test track with one mapping that is associated with an RC""" mock_logger = Mock() orchard_client = Mock() orchard_client.update_tracks.return_value = [ {'tuid': 1001}, ] orchard_client.get_track_by_tuid.return_value = { 'upc': '09876543210987' } swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] swb_client.get_product_by_upc.return_value = sony_product mock_determine_track_update_method.return_value = ( [sony_product], [] ) rc_product_processing_result = { 'correlationId': update_track_payload.correlation_id, 'entityType': 'PRODUCT', 'errors': [], 'ids': [ { 'businessKey': '09876543210987', 'businessKeyType': 'UPC', 'localId': '1022869', 'system': 'SONY' }, { 'businessKey': '09876543210987', 'businessKeyType': 'UPC', 'localId': '123456', 'system': 'ORCHARD' } ], 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' } mock_release_correct_product.return_value = [ rc_product_processing_result ] results = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del results[1]['messageCreatedDateTime'] del results[1]['messageId'] assert len(results) == 2 assert results == [ rc_product_processing_result, { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' } ] @patch(('switchboard_consumer.logic.' 'product_metadata_update.TrackParticipantHandler.process'), return_value=([{ 'entityType': 'PARTICIPANT', 'messageType': 'METADATA_UPDATE' }], [{ 'artistInfoId': 123, 'artistName': 'Test Artist', 'artistType': 'primary_artist' }], [])) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch(('switchboard_consumer.logic.' 'track_metadata_update.release_correct_product')) def test_handle_track_metadata_update_with_rc_error( mock_release_correct_product, mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1, sony_product): """Test track with multiple mappings, one being associated with an RC""" mock_logger = Mock() orchard_client = Mock() orchard_client.update_tracks.return_value = [ {'tuid': 1001}, {'tuid': 2001} ] swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] mock_determine_track_update_method.return_value = ( [sony_product], [update_track_payload.ids[1]] ) rc_product_processing_result = { 'correlationId': update_track_payload.correlation_id, 'entityType': 'PRODUCT', 'errors': [{'random_error'}], 'ids': [ { 'businessKey': '09876543210987', 'businessKeyType': 'UPC', 'localId': '1022869', 'system': 'SONY' }, { 'businessKey': '09876543210987', 'businessKeyType': 'UPC', 'localId': '123456', 'system': 'ORCHARD' } ], 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' } mock_release_correct_product.return_value = [ rc_product_processing_result ] results = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) expected_track_errors = [{ 'code': 'error', 'message': 'Failed to update associated Product via release correction' }] # Release correcting a Product associated with a track failed. # Both a Track and Product processing message sent assert len(results) == 2 assert results[0] == rc_product_processing_result assert results[1]['entityType'] == 'TRACK' assert results[1]['errors'] == expected_track_errors def test_determine_track_update_method(update_track_payload): mock_logger = Mock() orchard_client = Mock() swb_client = Mock() orchard_tuids = [] # Track tuid 1001 = Normal track update # Track tuid 2002 = Belongs to a Product that needs release correcting for orchard_local_id in update_track_payload.orchard_local_ids: orchard_tuids.append(int(orchard_local_id['localId'])) orchard_client.get_track_by_tuid = Mock(side_effect=[ {'productId': '1', 'upc': 'SOMETHING1'}, {'productId': '2', 'upc': 'SOMETHING2'}, ]) swb_client.get_product_by_upc.return_value = { 'releaseType': 'DIGITAL_AUDIO' } orchard_client.get_product_by_id = Mock(side_effect=[ {'displayStatus': product_status.IN_PROGRESS}, {'displayStatus': product_status.COMPLETED}, ]) (products_to_rc, tracks_to_update) = determine_track_update_method( orchard_tuids, orchard_client, swb_client, update_track_payload, mock_logger ) assert orchard_client.get_track_by_tuid.call_count == 2 assert swb_client.get_product_by_upc.call_count == 2 assert orchard_client.get_product_by_id.call_count == 2 assert len(products_to_rc) == 1 assert len(tracks_to_update) == 1 assert tracks_to_update[0] == 1001 def test_determine_track_update_video_parent_product(update_track_payload): """Test track update handles video parent products in completed.""" mock_logger = Mock() orchard_client = Mock() swb_client = Mock() orchard_tuids = [] # Track tuid 1001 = Normal track update # Track tuid 2002 = Belongs to a Product that needs release correcting for orchard_local_id in update_track_payload.orchard_local_ids: orchard_tuids.append(int(orchard_local_id['localId'])) orchard_client.get_track_by_tuid = Mock(side_effect=[ {'productId': '1', 'upc': 'SOMETHING1'}, {'productId': '2', 'upc': 'SOMETHING2'}, ]) swb_client.get_product_by_upc.return_value = { 'releaseType': 'VIDEO_SINGLE'} orchard_client.get_product_by_id = Mock(side_effect=[ {'displayStatus': product_status.IN_PROGRESS}, {'displayStatus': product_status.COMPLETED}, ]) (products_to_rc, tracks_to_update) = determine_track_update_method( orchard_tuids, orchard_client, swb_client, update_track_payload, mock_logger ) assert orchard_client.get_track_by_tuid.call_count == 2 assert swb_client.get_product_by_upc.call_count == 2 assert orchard_client.get_product_by_id.call_count == 2 # No Product to RC since parent of Track is a Video Product assert len(products_to_rc) == 0 assert len(tracks_to_update) == 1 assert tracks_to_update[0] == 1001 @patch(('switchboard_consumer.logic.' 'product_metadata_update.TrackParticipantHandler.process'), return_value=([], [], [])) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch('switchboard_consumer.logic.track_metadata_update.' 'LabelParticipantHandler') def test_handle_track_metadata_error_on_orchard_track_call( mock_label_participant_handler, mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1): """Test if error handled when calling Orchard for track info.""" mock_logger = Mock() orchard_client = Mock() orchard_client.get_track_by_tuid.return_value = { 'errors': [ { 'extensions': { 'code': 'get_track_by_tuid_error_code', }, 'message': 'An error message', } ] } swb_client = Mock() swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] mock_determine_track_update_method.return_value = ( [], update_track_payload.ids ) result = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del result[0]['messageCreatedDateTime'] del result[0]['messageId'] assert result == [ { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [ { 'code': 'error', 'message': ( 'Error encountered getting Track info from The Orchard' ) } ], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' }] @patch(('switchboard_consumer.logic.' 'product_metadata_update.TrackParticipantHandler.process'), return_value=([], [], [])) @patch(('switchboard_consumer.logic.' 'track_metadata_update.determine_track_update_method')) @patch('switchboard_consumer.logic.track_metadata_update.' 'LabelParticipantHandler') def test_handle_track_metadata_error_on_swb_product_call( mock_label_participant_handler, mock_determine_track_update_method, mock_participant_handler, update_track_payload, switchboard_track_item_1): """Test if error handled when calling SWB for product info.""" mock_logger = Mock() orchard_client = Mock() orchard_client.get_track_by_tuid.return_value = { 'upc': '09876543210987' } swb_client = Mock() swb_client.get_product_by_upc.return_value = { 'errors': [ { 'extensions': { 'code': 'get_product_by_upc_error_code', }, 'message': 'An error message', } ] } swb_client.lookup_track_by_isrc.return_value = switchboard_track_item_1[ 'track'] mock_determine_track_update_method.return_value = ( [], update_track_payload.ids ) result = handle_track_metadata_update( mock_logger, update_track_payload, swb_client, orchard_client) del result[0]['messageCreatedDateTime'] del result[0]['messageId'] assert result == [ { 'correlationId': 'r8j49hj389dhs93he', 'entityType': 'TRACK', 'errors': [ { 'code': 'error', 'message': ( 'Error encountered getting Product info from SWB' ) } ], 'ids': update_track_payload.ids, 'messageType': 'PROCESSING_RESULT', 'sendingSystem': 'ORCHARD' }]