"""Unit tests for episodes links importer.""" import copy from unittest.mock import Mock, patch from scripts import episodes_links_importer from podcast.models import episode as episode_model from podcast.models import episode_links as episode_links_model from tests.utils import db_operations @patch('scripts.episodes_links_importer._get_episodes_from_spotify') def test_get_spotify_links(mock_get_episodes_from_spotify, spotify_episodes_fixture_1): """Test get episode link in spotify episodes.""" mock_get_episodes_from_spotify.return_value = spotify_episodes_fixture_1 podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] store_id = db_operations.stores[3]['id'] mock_link = 'https://spotify.com/show/12345' results = episodes_links_importer.get_spotify_links( episodes, [], mock_link, podcast_id, store_id ) assert results[0] == { 'podcast_id': 1, 'episode_id': 1, 'store_id': 4, 'link': 'https://www.spotify.com/xyz/episode/123' } @patch('scripts.episodes_links_importer._get_episodes_from_spotify') def test_get_spotify_links_not_found(mock_get_episodes_from_spotify, spotify_episodes_fixture_2): """Test episode link not found in spotify episodes.""" mock_get_episodes_from_spotify.return_value = spotify_episodes_fixture_2 podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] store_id = db_operations.stores[3]['id'] mock_link = 'https://spotify.com/show/12345' results = episodes_links_importer.get_spotify_links( episodes, [], mock_link, podcast_id, store_id ) assert results == [] @patch('requests.get') @patch('podcast.models.episode.update_episode') @patch('scripts.episodes_links_importer._get_apple_podcast_auth_token') def test_get_apple_links(mock_get_apple_podcast_auth_token, mock_update_episode, mock_get, apple_episodes_fixture): """Test get episode links in apple episodes.""" mock_get_apple_podcast_auth_token.return_value = 'testtoken' mock_get.return_value.json.return_value = apple_episodes_fixture podcast = db_operations.podcast_data[0] episodes = episode_model.get_episodes(podcast['id'], filter_by_state='DONE')['items'] store_id = db_operations.stores[0]['id'] apple_id = db_operations.podcast_data[0]['apple_id'] mock_link = 'https://apple.com/id12345' results = episodes_links_importer.get_apple_links( episodes, [], mock_link, apple_id, podcast, store_id ) mock_get.assert_called_once() mock_update_episode.assert_called_once_with(1, {'apple_id': '1'}) assert results == [{ 'podcast_id': 1, 'episode_id': 1, 'store_id': 1, 'link': 'test-apple-episode-link' }] @patch('requests.get') @patch('podcast.models.episode.update_episode') @patch('scripts.episodes_links_importer._get_apple_podcast_auth_token') def test_get_apple_links_and_apple_id_not_stored( mock_get_apple_podcast_auth_token, mock_update_episode, mock_get, apple_episodes_fixture): """Test get episode links in apple episodes and apple_id_not_store for non public rss feed .""" mock_get_apple_podcast_auth_token.return_value = 'testtoken' mock_get.return_value.json.return_value = apple_episodes_fixture podcast = db_operations.podcast_data[1] episodes = [db_operations.episode_data[2]] store_id = db_operations.stores[0]['id'] apple_id = db_operations.podcast_data[0]['apple_id'] mock_link = 'https://apple.com/id12345' results = episodes_links_importer.get_apple_links( episodes, [], mock_link, apple_id, podcast, store_id ) mock_get.assert_called_once() assert not mock_update_episode.called assert results == [{ 'podcast_id': 2, 'episode_id': 3, 'store_id': 1, 'link': 'test-apple-episode-link-2' }] @patch('requests.get') @patch('podcast.models.episode.update_episode') @patch('scripts.episodes_links_importer._get_apple_podcast_auth_token') def test_get_apple_links_none_found( mock_get_apple_podcast_auth_token, mock_update_episode, mock_get, apple_episodes_error_fixture): """Test get episode links in apple episodes not found.""" mock_get_apple_podcast_auth_token.return_value = 'testtoken' mock_get.return_value.json.return_value = apple_episodes_error_fixture podcast = db_operations.podcast_data[0] episodes = episode_model.get_episodes(podcast['id'], filter_by_state='DONE')['items'] store_id = db_operations.stores[0]['id'] apple_id = db_operations.podcast_data[0]['apple_id'] mock_link = 'https://apple.com/id12345' results = episodes_links_importer.get_apple_links( episodes, [], mock_link, apple_id, podcast, store_id ) mock_get.assert_called_once() assert not mock_update_episode.called assert results == [] @patch('requests.get') def test_get_radio_public_links_successful(mock_get, rss_feed_episode_fixture): """Test get episode links from radio public.""" mock_get.return_value.status_code = 200 mock_get.return_value.url = 'https://radiopublic.com/random-pod/randomep' podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] mock_link = 'https://radiopublic.com/random-pod' store_id = db_operations.stores[4]['id'] results = episodes_links_importer.get_radio_public_links( episodes, [], mock_link, podcast_id, store_id, rss_feed_episode_fixture ) assert results == [{ 'podcast_id': podcast_id, 'episode_id': episodes[0]['id'], 'store_id': store_id, 'link': 'https://radiopublic.com/random-pod/randomep' }] mock_get.assert_called_once_with( 'https://radiopublic.com/random-pod/{}'.format(episodes[0]['megaphone_id'])) @patch('requests.get') def test_get_deezer_links_successful(mock_get): """Test get episode links for deezer.""" mock_return_value = [ { 'title': 'title', 'id': 111, }, { 'title': 'title 2', 'id': 112, } ] mock_link = 'https://www.deezer.com/en/show/abc' mock_get.return_value.json.return_value = { 'data': mock_return_value, 'total': len(mock_return_value) } podcast_id = db_operations.podcast_data[0]['id'] store_id = db_operations.stores[6]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] results = episodes_links_importer.get_deezer_links( episodes, [], mock_link, podcast_id, store_id) mock_get.assert_called_once_with('https://api.deezer.com/podcast/abc/episodes?limit=50&index=0') assert results[0] == { 'podcast_id': 1, 'episode_id': 1, 'store_id': 7, 'link': 'https://www.deezer.com/episode/111' } @patch('requests.get') def test_get_deezer_links_unsuccessful(mock_get): """Test unsuccessful get episode links for deezer.""" mock_return_value = [ { 'title': 'title 2', 'id': 112, } ] mock_link = 'https://www.deezer.com/en/show/abc' mock_get.return_value.json.return_value = { 'data': mock_return_value, 'total': len(mock_return_value) } podcast_id = db_operations.podcast_data[0]['id'] store_id = db_operations.stores[6]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] results = episodes_links_importer.get_deezer_links( episodes, [], mock_link, podcast_id, store_id) mock_get.assert_called_once_with('https://api.deezer.com/podcast/abc/episodes?limit=50&index=0') assert results == [] @patch('requests.get') def test_get_radio_public_links_unsuccessful(mock_get, rss_feed_episode_fixture): """Test get unsuccessful episode links from radio public.""" mock_get.return_value.status_code = 200 mock_get.return_value.url = 'https://radiopublic.com/random-pod' podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] mock_link = 'https://radiopublic.com/random-pod' store_id = db_operations.stores[4]['id'] results = episodes_links_importer.get_radio_public_links( episodes, [], mock_link, podcast_id, store_id, rss_feed_episode_fixture ) assert results == [] mock_get.assert_called_once_with( 'https://radiopublic.com/random-pod/{}'.format(episodes[0]['megaphone_id'])) @patch('requests.get') def test_get_player_fm_links_successful(mock_get, player_fm_episodes_fixture): """Test get episode links from player fm.""" mock_get.return_value.json.return_value = player_fm_episodes_fixture podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] mock_link = 'https://playerfm.com/random-pod' store_id = db_operations.stores[5]['id'] results = episodes_links_importer.get_player_fm_links( episodes, [], mock_link, podcast_id, store_id ) mock_get.assert_called_once() assert results == [{ 'podcast_id': 1, 'episode_id': 1, 'store_id': 6, 'link': 'https://playerfm.com/random-pod/test-1' }] @patch('requests.get') def test_get_player_fm_links_unsuccessful(mock_get): """Test get unsuccessful episode links from player fm.""" mock_get.return_value.status_code = 404 podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] mock_link = 'https://playerfm.com/random-pod' store_id = db_operations.stores[5]['id'] results = episodes_links_importer.get_player_fm_links( episodes, [], mock_link, podcast_id, store_id ) mock_get.assert_called_once() assert results == [] @patch('requests.get') def test_get_podcast_addict_links(mock_get, rss_feed_episode_fixture): """Test episode links for podcast addict episodes.""" mock_get.return_value.status_code = 200 mock_get.return_value.url = 'https://podcastaddict.com/episode/https%3A%2F%2Ftest%2Fmpuid.mp3&podcastId=123' podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] mock_link = 'https://podcastaddict.com/123' store_id = db_operations.stores[8]['id'] results = episodes_links_importer.get_podcast_addict_links( episodes, [], mock_link, podcast_id, store_id, rss_feed_episode_fixture ) assert results == [{ 'podcast_id': 1, 'episode_id': 1, 'store_id': 9, 'link': 'https://podcastaddict.com/episode/https%3A%2F%2Ftest%2Fmpuid.mp3&podcastId=123' }] @patch('requests.get') def test_get_podcast_addict_links_not_found(mock_get, rss_feed_episode_fixture): """Test episode link not found in podcast addict episodes.""" rss_feed_episode_fixture[0]['title'] = 'title 2' podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] mock_link = 'https://podcastaddict.com/123' store_id = db_operations.stores[8]['id'] results = episodes_links_importer.get_podcast_addict_links( episodes, [], mock_link, podcast_id, store_id, rss_feed_episode_fixture ) assert results == [] @patch('requests.get') def test_get_stitcher_links(mock_get, stitcher_episodes_fixture): """Test get episode links in stitcher episodes.""" mock_get.return_value.status_code = 200 mock_get.return_value.json.return_value = stitcher_episodes_fixture podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] mock_link = 'https://stitcher.com/show/random-pod' store_id = db_operations.stores[7]['id'] results = episodes_links_importer.get_stitcher_links( episodes, [], mock_link, podcast_id, store_id ) mock_get.assert_called_once_with( 'https://api.prod.stitcher.com/search/show/random-pod/allEpisodes' '?count=500&offset=0&sort=publish_date&sort_order=desc' ) assert results == [{ 'podcast_id': 1, 'episode_id': 1, 'store_id': 8, 'link': 'https://stitcher.com/show/random-pod/episode/random-episode-1' }] @patch('requests.get') def test_get_stitcher_links_not_found(mock_get, stitcher_episodes_error_fixture): """Test episode link not found in stitcher episodes.""" mock_get.return_value.status_code = 404 mock_get.return_value.json.return_value = stitcher_episodes_error_fixture podcast_id = db_operations.podcast_data[0]['id'] episodes = episode_model.get_episodes(podcast_id, filter_by_state='DONE')['items'] mock_link = 'https://stitcher.com/show/invalid-pod' store_id = db_operations.stores[7]['id'] results = episodes_links_importer.get_stitcher_links( episodes, [], mock_link, podcast_id, store_id ) mock_get.assert_called_once_with( 'https://api.prod.stitcher.com/search/show/invalid-pod/allEpisodes' '?count=500&offset=0&sort=publish_date&sort_order=desc' ) assert results == [] @patch('selenium.webdriver.Remote') def test_get_amazon_links(mock_driver): """Test episode link found for amazon.""" mock_driver.return_value.get.return_value = None link_1 = Mock() link_2 = Mock() link_3 = Mock() link_1.get_attribute.side_effect = ['some title', '/podcasts/ddd/episodes/123/title'] link_2.get_attribute.side_effect = ['title', '/podcasts/ddd/episodes/456/title'] link_3.get_attribute.side_effect = ['title', '/podcasts/eee/episodes/456/title'] mock_attributes = [link_1, link_2, link_3] mock_driver.return_value.find_elements.return_value = mock_attributes podcast = db_operations.podcast_data[0] episodes = episode_model.get_episodes(podcast['id'], filter_by_state='DONE')['items'] mock_link = 'https://music.amazon.com/podcasts/ddd/title' store_id = 9 results = episodes_links_importer.get_amazon_links( episodes, [], mock_link, podcast, store_id ) mock_search_url = 'https://music.amazon.com/search/title%20title/episodes?filter=IsLibrary%7Cfalse&sc=none' mock_driver.return_value.get.assert_called_once_with(mock_search_url) assert results == [{ 'podcast_id': 1, 'episode_id': 1, 'store_id': 9, 'link': 'https://music.amazon.com/podcasts/ddd/episodes/456/title' }] @patch('selenium.webdriver.Remote') def test_get_amazon_links_none_found(mock_driver): """Test episode link none found for amazon.""" mock_driver.return_value.get.return_value = None link_1 = Mock() link_2 = Mock() link_1.get_attribute.side_effect = ['some title', 'https://music.amazon.com/podcasts/ddd/episodes/123/title'] link_2.get_attribute.side_effect = ['title', 'https://music.amazon.com/podcasts/eee/episodes/456/title'] mock_attributes = [link_1, link_2] mock_driver.return_value.find_elements_by_tag_name.return_value = mock_attributes podcast = db_operations.podcast_data[0] episodes = episode_model.get_episodes(podcast['id'], filter_by_state='DONE')['items'] mock_link = 'https://music.amazon.com/podcasts/ddd/title' store_id = 9 results = episodes_links_importer.get_amazon_links( episodes, [], mock_link, podcast, store_id ) mock_search_url = 'https://music.amazon.com/search/title%20title/episodes?filter=IsLibrary%7Cfalse&sc=none' mock_driver.return_value.get.assert_called_once_with(mock_search_url) assert results == [] @patch('scripts.episodes_links_importer._get_pandora_episodes') def test_get_pandora_links(mock_get_pandora_episodes, pandora_data_fixture): """Test successful get pandora store links.""" mock_get_pandora_episodes.return_value = pandora_data_fixture['annotations'] episodes = copy.deepcopy(db_operations.episode_data) episodes[0]['title'] = 'test-podcast' episodes[1]['title'] = 'test-second-podcast' links = episodes_links_importer.get_pandora_links( episodes, [], 'https://www.pandora.com/podcast/test-podcast/PE:6273776', 1, 1 ) assert links == [ { 'episode_id': 1, 'link': 'https://www.pandora.com/podcast/test-podcast/PE:9673056', 'podcast_id': 1, 'store_id': 1 }, { 'episode_id': 2, 'link': 'https://www.pandora.com/podcast/test-second-podcast/PE:9673012', 'podcast_id': 1, 'store_id': 1 } ] @patch('scripts.episodes_links_importer._get_pandora_episodes') def test_get_pandora_links_not_found(mock_get_pandora_episodes, pandora_data_fixture): """Test successful get pandora store links not_found.""" mock_get_pandora_episodes.return_value = pandora_data_fixture['annotations'] links = episodes_links_importer.get_pandora_links( db_operations.episode_data, [], 'https://www.pandora.com/podcast/test-podcast/PE:6273776', 1, 1 ) assert links == [] @patch('scripts.episodes_links_importer._get_apple_podcast_auth_token') @patch('scripts.episodes_links_importer._get_episodes_from_spotify') def test_populate_podcast_episodes_links( mock_get_episodes_from_spotify, mock_get_apple_podcast_auth_token, spotify_episodes_fixture_1, stores_fixture): """Test successful fetching and population of episode links for a podcast.""" mock_get_apple_podcast_auth_token.return_value = 'testtoken' mock_get_episodes_from_spotify.return_value = spotify_episodes_fixture_1 results = episode_links_model.get_episode_links(db_operations.podcast_data[0]['id']) assert results['items'] == [{ 'episode_id': 1, 'id': 2, 'link': 'https://apple-link/xyz/12434/episode/=i?1234567890122', 'podcast_id': 1, 'store_id': 1 }] episodes_links_importer.populate_podcast_episodes_links( db_operations.podcast_data[0], stores_fixture) results = episode_links_model.get_episode_links(db_operations.podcast_data[0]['id']) assert results['items'] == [ { 'episode_id': 1, 'id': 2, 'link': 'https://apple-link/xyz/12434/episode/=i?1234567890122', 'podcast_id': 1, 'store_id': 1, }, { 'id': 3, 'store_id': 2, 'podcast_id': 1, 'episode_id': 1, 'link': 'https://www.spotify.com/xyz/episode/123' } ] @patch('scripts.episodes_links_importer._get_episodes_from_spotify') def test_populate_podcast_episodes_links_available( mock_get_episodes_from_spotify, spotify_episodes_fixture_2, stores_fixture): """Test when all episode links are available in db.""" mock_get_episodes_from_spotify.return_value = spotify_episodes_fixture_2 results = episode_links_model.get_episode_links(db_operations.podcast_data[1]['id']) assert results['items'] == [{ 'id': 1, 'store_id': 2, 'podcast_id': 2, 'episode_id': 3, 'link': 'https://www.spotify.com/xyz/episode/123' }] episodes_links_importer.populate_podcast_episodes_links( db_operations.podcast_data[1], stores_fixture) results = episode_links_model.get_episode_links(db_operations.podcast_data[1]['id']) assert results['items'] == [{ 'id': 1, 'store_id': 2, 'podcast_id': 2, 'episode_id': 3, 'link': 'https://www.spotify.com/xyz/episode/123' }]