"""Test ows-sound-recordings model.""" from unittest.mock import call from unittest.mock import MagicMock from unittest.mock import patch import pytest from backend.exceptions import RequestError from backend.models import ows_sound_recordings from tests.testutils.mocks.ows_sound_recordings import mock_track_match def test_ows_sound_recordings_track_matches_200(mock_app, request_engine): """Test a successful response from the track matches endpoint.""" mock_params = {'foo': 'baz'} mock_response = [ mock_track_match({'tuid': 1}), mock_track_match({'tuid': 2}), mock_track_match({'tuid': 3})] request_engine['ows-sound-recordings'].add_spec( 'GET', '/sound_recordings/cr', mock_response ) result = ows_sound_recordings.get_track_matches(mock_params) assert result == mock_response def test_ows_sound_recordings_track_matches_400(mock_app, request_engine): """Test a not-found response from the track matches endpoint.""" mock_params = {'foo': 'baz'} request_engine['ows-sound-recordings'].add_spec( 'GET', '/sound_recordings/cr', {'message': 'not found'}, 404 ) result = ows_sound_recordings.get_track_matches(mock_params) assert result == [] def test_ows_sound_recordings_track_matches_500(mock_app, request_engine): """Test an error response from the track matches endpoint.""" request_engine['ows-sound-recordings'].add_spec( 'GET', '/sound_recordings/cr', {'message': 'not found'}, 500 ) with pytest.raises(RequestError) as e: ows_sound_recordings.get_track_matches({}) assert 'Failed to get fingerprint' in str(e.value) @patch('backend.models.ows_sound_recordings.request') def test_ows_sound_recordings_track_matches_request_headers(mock_request, mock_app): """Test that requests to the track matches endpoint honor current request headers.""" mock_response = MagicMock() mock_params = {'foo': 'baz'} mock_response.status_code = 200 mock_request.get.return_value = mock_response mock_app.g.request_context.profile_type = 'ContentProfile' mock_app.g.request_context.roles = ['foo', 'bar'] ows_sound_recordings.get_track_matches(mock_params) mock_request.get.assert_called_with(**{ 'service_name': 'ows-sound-recordings', 'path': '/sound_recordings/cr', 'params': mock_params, 'headers': { 'Orchard-Profile-Type': 'ContentProfile', 'Orchard-Roles': 'foo,bar' } }) def test_parse_sound_recording_matches(): """Test parse sound recording matches.""" # track 1 has no matches # track 2 has 1 match # track 3 has 1 matches mock_product_1_track_1 = {'product_id': 1, 'tuid': 1, 'vendor_id': 1, 'isrc': 'a', 'release_status': 'in_content'} mock_product_1_track_2 = {'product_id': 1, 'tuid': 2, 'vendor_id': 1, 'isrc': 'b', 'release_status': 'in_content'} mock_product_1_track_3 = {'product_id': 1, 'tuid': 3, 'vendor_id': 1, 'isrc': 'c', 'release_status': 'in_content'} mock_product_2_track_2 = {'product_id': 2, 'tuid': 4, 'vendor_id': 2, 'isrc': 'b', 'release_status': 'in_content'} mock_product_2_track_3 = {'product_id': 2, 'tuid': 5, 'vendor_id': 2, 'isrc': 'c', 'release_status': 'in_content'} mock_product_3_track_3 = {'product_id': 3, 'tuid': 6, 'vendor_id': 3, 'isrc': 'c', 'release_status': 'transfer_to_content'} # noqa: E501 mock_matches = [ mock_track_match(mock_product_1_track_1), mock_track_match(mock_product_1_track_2, [mock_product_2_track_2]), mock_track_match(mock_product_1_track_3, [mock_product_2_track_3, mock_product_3_track_3]) ] actual = ows_sound_recordings.parse_sound_recording_matches(mock_matches, 1) assert actual == { 1: {'tuid': 1, 'isrc': 'a', 'matched_tracks': []}, 2: {'tuid': 2, 'isrc': 'b', 'matched_tracks': [ { 'tuid': 4, 'isrc': 'b', 'product_id': 2, 'vendor_id': 2, 'release_status': 'in_content' } ]}, 3: {'tuid': 3, 'isrc': 'c', 'matched_tracks': [ { 'tuid': 5, 'isrc': 'c', 'product_id': 2, 'vendor_id': 2, 'release_status': 'in_content' } ]} } def test_parse_track_isrc_matches(): """Test parse isrc matches.""" # track 1 has no matches # track 2 has 1 match # track 3 has 1 matches mock_product_1_track_1 = {'product_id': 1, 'tuid': 1, 'vendor_id': 1, 'isrc': 'a', 'release_status': 'in_content'} mock_product_1_track_2 = {'product_id': 1, 'tuid': 2, 'vendor_id': 1, 'isrc': 'b', 'release_status': 'in_content'} mock_product_1_track_3 = {'product_id': 1, 'tuid': 3, 'vendor_id': 1, 'isrc': 'c', 'release_status': 'in_content'} mock_product_2_track_2 = {'product_id': 2, 'tuid': 4, 'vendor_id': 2, 'isrc': 'b', 'release_status': 'in_content'} mock_product_2_track_3 = {'product_id': 2, 'tuid': 5, 'vendor_id': 2, 'isrc': 'c', 'release_status': 'in_content'} mock_product_3_track_3 = {'product_id': 3, 'tuid': 6, 'vendor_id': 3, 'isrc': 'c', 'release_status': 'transfer_to_content'} # noqa: E501 mock_matches = [ mock_track_match(mock_product_1_track_1), mock_track_match(mock_product_1_track_2, [mock_product_2_track_2], 'abc'), mock_track_match(mock_product_1_track_3, [mock_product_2_track_3, mock_product_3_track_3], 'def') ] actual = ows_sound_recordings.parse_track_isrc_matches(mock_matches, 1, [1, 2, 3]) assert actual == { 'osrs_to_tracks': { '463c4d20-c9d4-403b-8e7d-7b3a0272fde5': [], 'abc': [ { 'isrc': 'b', 'product_id': 2, 'release_status': 'in_content', 'tuid': 4, 'vendor_id': 2 } ], 'def': [ { 'isrc': 'c', 'product_id': 2, 'release_status': 'in_content', 'tuid': 5, 'vendor_id': 2 } ], }, 'tuids_to_osr_ids': { 1: '463c4d20-c9d4-403b-8e7d-7b3a0272fde5', 2: 'abc', 3: 'def' } } def test_get_formatted_sound_recording_matches(mocker): """Test function call get formatted sound recording matches.""" mock_params = { 'product_id': 3, 'include_transfer_to_content': True } mock_get_track_matches = mocker.patch.object( ows_sound_recordings, 'get_track_matches', return_value=[{'hello': 'some'}] ) mock_parse_sound_recording_matches = mocker.patch.object( ows_sound_recordings, 'parse_sound_recording_matches', return_value={} ) ows_sound_recordings.get_formatted_sound_recording_matches(3) assert mock_get_track_matches.mock_calls == [call(mock_params)] assert mock_parse_sound_recording_matches.mock_calls == [call([{'hello': 'some'}], 3)] def test_get_formatted_isrc_matches(mocker): """Test function call get formatted ISRC matches.""" mock_params = { 'track_isrcs': 'a,b', 'include_transfer_to_content': True } mock_get_track_matches = mocker.patch.object( ows_sound_recordings, 'get_track_matches', return_value=[{'hello': 'some'}] ) mock_parse_isrc_matches = mocker.patch.object( ows_sound_recordings, 'parse_track_isrc_matches', return_value={} ) ows_sound_recordings.get_formatted_isrc_matches(2, ['a', 'b'], [1, 2]) assert mock_get_track_matches.mock_calls == [ call(mock_params) ] assert mock_parse_isrc_matches.mock_calls == [ call([{'hello': 'some'}], 2, [1, 2]) ] def test_split_isrc_list(): """Test split_isrc_list.""" mock_input = [str(i) for i in range(1, 53)] expected = [ [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', ], [ '51', '52' ] ] actual = list(ows_sound_recordings.split_isrc_list(mock_input)) assert actual == expected @patch('backend.models.ows_sound_recordings.parse_track_isrc_matches') @patch('backend.models.ows_sound_recordings.get_track_matches') @patch('backend.models.ows_sound_recordings.split_isrc_list') def test_bulk_isrc_calls(mock_split, mock_get, mock_parse): """Test splitting and merging bulk isrc calls.""" mock_split.return_value = [['a', 'b'], ['c', 'd']] mock_get.side_effect = [[{'a': 'b'}], [{'c': 'd'}]] ows_sound_recordings.get_formatted_isrc_matches(1, [], []) mock_get.assert_has_calls([ call({'track_isrcs': 'a,b', 'include_transfer_to_content': True}), call({'track_isrcs': 'c,d', 'include_transfer_to_content': True}) ]) mock_parse.assert_called_with([{'a': 'b'}, {'c': 'd'}], 1, []) @patch('backend.models.ows_sound_recordings.parse_track_isrc_matches') @patch('backend.models.ows_sound_recordings.get_track_matches') @patch('backend.models.ows_sound_recordings.split_isrc_list') def test_bulk_isrc_calls_ignore_missing(mock_split, mock_get, mock_parse): """Test omitting blank or null ISRCs in bulk get calls.""" mock_split.return_value = [['a', ''], [None]] mock_get.side_effect = [[{'a': 'b'}]] ows_sound_recordings.get_formatted_isrc_matches(1, [], []) mock_get.assert_has_calls([ call({'track_isrcs': 'a', 'include_transfer_to_content': True}), ]) mock_parse.assert_called_with([{'a': 'b'}], 1, [])