async def test_find_media_items__multiple_search_results_w_same_artist__returns_only_one( self): text = "\"American Pie\" by Don McLean" self.song_scrounger._get_paragraphs = MagicMock(return_value=[text]) self.song_scrounger.find_names = MagicMock( return_value=["American Pie"]) less_popular_version = Song("American Pie", "spotify:track:1fDsrQ23eTAVFElUMaf38X", ["Don McLean"], popularity=1) more_popular_version = Song("American Pie", "spotify:track:2ZbTw8awL7EFat9Wz1DIHN", ["Don McLean"], popularity=2) songs = [less_popular_version, more_popular_version] self.mock_spotify_client.find_track = AsyncMock( return_value=set(songs)) self.song_scrounger.filter_if_any_artists_mentioned = MagicMock( return_value=set(songs)) self.song_scrounger.reduce_by_popularity_per_artist = MagicMock( return_value=set([more_popular_version])) results = await self.song_scrounger.find_media_items( text, self.mock_spotify_client.find_track) self.assertEqual(len(results.keys()), 1) self.assertTrue("American Pie" in results.keys()) self.assertEqual(len(results["American Pie"]), 1) self.assertEqual(results["American Pie"], set([more_popular_version]))
async def test_filter_if_any_artists_mentioned_greedy__no_matching_artist_in_cur_paragraph_and_multiple_matching_songs__finds_artist_elsewhere_in_doc( self): song_w_matching_artist = Song( "American Pie", "spotify:track:1fDsrQ23eTAVFElUMaf38X", ["Don McLean"], ) songs = set([ song_w_matching_artist, Song( "American Pie", "spotify:track:xxxxxxxxxxxxxxxxxxxxxx", ["Some other dude"], ) ]) self.song_scrounger.filter_if_any_artists_mentioned = MagicMock( side_effect=[songs, [song_w_matching_artist]]) results = self.song_scrounger.filter_if_any_artists_mentioned_greedy( songs, "\"American Pie\" by someone...", "\"American Pie\" by someone...\nOh yeah, by Don McLean") results = list(results) self.assertEqual(len(results), 1) self.assertEqual("American Pie", results[0].name) self.assertEqual(["Don McLean"], results[0].artists) self.assertEqual("spotify:track:1fDsrQ23eTAVFElUMaf38X", results[0].spotify_uri)
async def test_find_media_items__homonym_items_w_different_artists__returns_both_versions( self): text = "\"Sorry\" by Justin Bieber...\"Sorry\" by Nothing But Thieves" self.song_scrounger._get_paragraphs = MagicMock(return_value=[ "\"Sorry\" by Justin Bieber...\"Sorry\" by Nothing But Thieves" ]) self.song_scrounger.find_names = MagicMock(return_value=["Sorry"]) songs = [ Song("Sorry", "spotify:track:09CtPGIpYB4BrO8qb1RGsF", ["Justin Bieber"]), Song("Sorry", "spotify:track:6rAXHPd18PZ6W8m9EectzH", ["Nothing But Thieves"]) ] self.mock_spotify_client.find_track = AsyncMock( return_value=set(songs)) self.song_scrounger.filter_if_any_artists_mentioned = MagicMock( return_value=set(songs)) self.song_scrounger.reduce_by_popularity_per_artist = MagicMock( return_value=set(songs)) results = await self.song_scrounger.find_media_items( text, self.mock_spotify_client.find_track) self.assertEqual(len(results.keys()), 1) self.assertTrue("Sorry" in results.keys()) self.assertEqual(len(results["Sorry"]), 2) self.assertEqual(results["Sorry"], set(songs))
async def test_find_songs__spotify_song_title_contains_metadata__song_is_matched_regardless( self, mock_read_file_contents): self.mock_spotify_client.find_song.return_value = [ Song("Time Is On My Side - Mono Version", "spotify:track:2jaN6NgXflZTj2z9CWcqaP", ["The Rolling Stones"], popularity=None), Song("Time Is On My Side", "spotify:track:6IpxLzChgCbFSJwso2Q84D", ["Irma Thomas"], popularity=None), ] results = await self.song_scrounger.find_songs("mock file path") mock_read_file_contents.assert_called_once_with("mock file path") self.mock_spotify_client.find_song.assert_any_call( "Time Is On My Side") self.assertEqual(1, len(results.keys())) self.assertIn("Time Is On My Side", results.keys()) self.assertEqual(len(results["Time Is On My Side"]), 1) self.assertEqual( set([song.spotify_uri for song in results["Time Is On My Side"]]), set(["spotify:track:2jaN6NgXflZTj2z9CWcqaP"])) self.assertIn("The Rolling Stones", list(results["Time Is On My Side"])[0].artists)
async def test_reduce_by_popularity_per_artist__by_diff_artists__does_not_reduce( self): song_by_artist1 = Song("American Pie", "spotify:track:1fDsrQ23eTAVFElUMaf38X", ["Don McLean"]) song_by_artist2 = Song("American Pie", "spotify:track:1vo6TY0FyLRBTXohxvflhJ", ["Madonna"]) songs = [song_by_artist1, song_by_artist2] def pick_most_popular__ret_vals(songs): songs = list(songs) if len(songs) != 1: raise ValueError(f"Mock did expected list of len==1: {songs}") elif "Don McLean" in songs[0].artists[0]: return song_by_artist1 elif "Madonna" in songs[0].artists[0]: return song_by_artist2 else: raise ValueError(f"Mock did not expect arg: {songs}") self.song_scrounger.pick_most_popular = MagicMock( side_effect=pick_most_popular__ret_vals) results = self.song_scrounger.reduce_by_popularity_per_artist(songs) self.assertEqual(len(results), 2) self.assertTrue(song_by_artist1 in results) self.assertTrue(song_by_artist2 in results)
async def test_find_songs__multiple_artists_match__prefers_artist_in_same_paragraph( self, mock_read_file_contents): self.mock_spotify_client.find_song.return_value = [ Song("Mock Song Name", "spotify:track:mock1", ["Mock Artist"], popularity=1), Song("Mock Song Name", "spotify:track:mock2", ["Other Mock Artist"], popularity=1) ] results = await self.song_scrounger.find_songs("mock file path") mock_read_file_contents.assert_called_once_with("mock file path") self.mock_spotify_client.find_song.assert_called_once_with( "Mock Song Name") self.assertEqual(len(results.keys()), 1) self.assertEqual(len(results["Mock Song Name"]), 1) self.assertEqual( list(results["Mock Song Name"])[0].name, "Mock Song Name") self.assertEqual( list(results["Mock Song Name"])[0].spotify_uri, "spotify:track:mock1") self.assertEqual(len(list((results["Mock Song Name"]))[0].artists), 1) self.assertEqual( list(results["Mock Song Name"])[0].artists[0], "Mock Artist")
async def test_set_union__all_dups__keeps_one(self): song_A = Song("Song A", "URI A", "Artist A") song_A_dup = Song("Song A", "URI A", "Artist A") set_union = self.song_scrounger.set_union(set([song_A]), set([song_A_dup])) self.assertEqual(len(set_union), 1) self.assertTrue(song_A in set_union or song_A_dup in set_union)
async def test_set_union__no_dups__keeps_all(self): song_A = Song("Song A", "URI A", "Artist A") song_B = Song("Song B", "URI B", "Artist B") set_union = self.song_scrounger.set_union(set([song_A]), set([song_B])) self.assertEqual(len(set_union), 2) self.assertTrue(song_A in set_union) self.assertTrue(song_B in set_union)
async def test_set_union__one_dups__removes_dup_keeps_others(self): song_A = Song("Song A", "URI A", "Artist A") song_B = Song("Song B", "URI B", "Artist B") song_B_dup = Song("Song B", "URI B", "Artist B") song_C = Song("Song C", "URI C", "Artist C") set_union = self.song_scrounger.set_union(set([song_A, song_B]), set([song_B_dup, song_C])) self.assertEqual(len(set_union), 3) self.assertTrue(song_A in set_union) self.assertTrue(song_B in set_union or song_B_dup in set_union) self.assertTrue(song_C in set_union)
async def test_pick_most_popular__two_songs_w_diff_popularity__picks_most_popular( self): less_popular_song = Song("some song", "some spotify uri", ["some artist"], popularity=1) more_popular_song = Song("mock name of more popular version", "mock spotify uri of more popular version", ["mock artist of more popular version"], popularity=2) mock_songs = [less_popular_song, more_popular_song] result = self.song_scrounger.pick_most_popular(mock_songs) self.assertEqual(result, more_popular_song)
async def test_reduce_by_popularity_per_artist__by_same_artist__reduces_to_one( self): songs = [ Song("American Pie", "spotify:track:1fDsrQ23eTAVFElUMaf38X", ["Don McLean"]), Song("American Pie", "spotify:track:4wpuHehFEEpWAlkw3vjH0s", ["Don McLean"]) ] self.song_scrounger.pick_most_popular = MagicMock( return_value=songs[0]) results = self.song_scrounger.reduce_by_popularity_per_artist(songs) self.song_scrounger.pick_most_popular.assert_called_once_with( set(songs)) self.assertEqual(len(results), 1) self.assertEqual(list(results)[0], songs[0])
async def test__order_album_songs__incomplete_album(self): songs_w_number = [ (Song("Got To Get You Into My Life - Remastered 2009", "", []), (13)), (Song("Tomorrow Never Knows - Remastered 2009", "", []), (14)), (Song("Taxman - Remastered 2009", "", []), (1)), ] expected_album_song_list = [ "Taxman - Remastered 2009", "Got To Get You Into My Life - Remastered 2009", "Tomorrow Never Knows - Remastered 2009", ] ordered_songs = self.spotify_client._order_album_songs(songs_w_number) self.assertEqual([song.name for song in ordered_songs], expected_album_song_list)
async def test_find_songs__song_dups_same_artist__returns_most_popular_version_only( self, mock_read_file_contents): self.mock_spotify_client.find_song.return_value = [ Song("Mock Song Name", "spotify:track:mock1", ["MOCKARTIST"], popularity=1), Song("Mock Song Name", "spotify:track:mock2", ["MOCKARTIST"], 50), Song("Mock Song Name", "spotify:track:mock3", ["MOCKARTIST"], 100) ] results = await self.song_scrounger.find_songs("mock file path") mock_read_file_contents.assert_called_once_with("mock file path") self.mock_spotify_client.find_song.assert_called_once_with( "Mock Song Name") self.assertEqual(len(results.keys()), 1) self.assertEqual(len(results["Mock Song Name"]), 1)
async def test_pick_most_popular__only_one_song__defaults_to_that_song( self): some_song = Song("mock song", "mock spotify uri", ["mock artist"], popularity=1) result = self.song_scrounger.pick_most_popular([some_song]) self.assertEqual(result, some_song)
async def test_filter_if_any_artists_mentioned__no_artist_mentioned__keeps_all_songs( self): text = "\"Sorry\"" songs = [ Song("Sorry", "spotify:track:09CtPGIpYB4BrO8qb1RGsF", ["Justin Bieber"]), Song("Sorry", "spotify:track:6rAXHPd18PZ6W8m9EectzH", ["Nothing But Thieves"]) ] self.song_scrounger.filter_by_mentioned_artist = MagicMock( return_value=set()) filtered_songs = self.song_scrounger.filter_if_any_artists_mentioned( songs, text) self.song_scrounger.filter_by_mentioned_artist.assert_called_once_with( songs, text) self.assertEqual(filtered_songs, set(songs))
async def test_pick_most_popular__compares_undefined_popularity__raises( self): song_w_undefined_popularity = Song("mock song", "mock spotify uri", ["mock artist"], popularity=None) with self.assertRaises(ValueError): result = self.song_scrounger.pick_most_popular( [song_w_undefined_popularity, song_w_undefined_popularity])
async def test_filter_by_mentioned_artist__only_returns_song_by_mentioned_artist( self): text = "\"Sorry\" by Justin Bieber" song_by_mentioned_artist = Song("Sorry", "spotify:track:09CtPGIpYB4BrO8qb1RGsF", artists=["Justin Bieber"]) song_by_unmentioned_artist = Song( "Sorry", "spotify:track:6rAXHPd18PZ6W8m9EectzH", artists=["Nothing But Thieves"]) self.song_scrounger.is_mentioned = MagicMock( side_effect=[True, False, False, False]) filtered_songs = self.song_scrounger.filter_by_mentioned_artist( [song_by_mentioned_artist, song_by_unmentioned_artist], text) self.song_scrounger.is_mentioned.assert_any_call("Justin Bieber", text) self.song_scrounger.is_mentioned.assert_any_call( "Nothing But Thieves", text) self.assertEqual(len(filtered_songs), 1) self.assertEqual(list(filtered_songs)[0], song_by_mentioned_artist)
async def test_find_songs__artist_name_appears_as_substr_only__artist_not_matched( self, mock_read_file_contents): # NOTE: its important that the spotify URIs don't match self.mock_spotify_client.find_song.return_value = [ Song("Satisfaction", "spotify:track:mock1", ["MOCKARTIST"], None), Song("Satisfaction", "spotify:track:mock2", ["Allen Stone"], None), ] results = await self.song_scrounger.find_songs("mock file path") mock_read_file_contents.assert_called_once_with("mock file path") self.mock_spotify_client.find_song.assert_any_call("Satisfaction") self.assertEqual(len(results.keys()), 1) self.assertEqual(len(results["Satisfaction"]), 2) self.assertIn( "MOCKARTIST", list(results["Satisfaction"])[0].artists + list(results["Satisfaction"])[1].artists) self.assertIn( "Allen Stone", list(results["Satisfaction"])[0].artists + list(results["Satisfaction"])[1].artists)
async def test_find_media_items__single_item_with_matching_artist__returns_that_version_only( self): text = "\"Sorry\" by Justin Bieber." self.song_scrounger._get_paragraphs = MagicMock(return_value=[text]) self.song_scrounger.find_names = MagicMock(return_value=["Sorry"]) songs = [ Song("Sorry", "spotify:track:09CtPGIpYB4BrO8qb1RGsF", ["Justin Bieber"]), Song("Sorry", "spotify:track:6rAXHPd18PZ6W8m9EectzH", ["Nothing But Thieves"]) ] self.mock_spotify_client.find_song = AsyncMock(return_value=set(songs)) self.song_scrounger.filter_if_any_artists_mentioned_greedy = MagicMock( return_value=set([songs[0]])) self.song_scrounger.reduce_by_popularity_per_artist = MagicMock( return_value=set([songs[0]])) results = await self.song_scrounger.find_media_items( text, self.mock_spotify_client.find_song) self.assertEqual(len(results.keys()), 1) self.assertTrue("Sorry" in results.keys()) self.assertEqual(len(results["Sorry"]), 1) self.assertEqual(results["Sorry"], set([songs[0]]))
async def test_filter_by_mentioned_artist__no_artists_mentioned__returns_empty_set( self): text = "\"Sorry\" by ... someone" songs = [ Song("Sorry", "spotify:track:09CtPGIpYB4BrO8qb1RGsF", artists=["Justin Bieber"]) ] self.song_scrounger.is_mentioned_verbatim = MagicMock( return_value=False) filtered_songs = self.song_scrounger.filter_by_mentioned_artist( songs, text) self.song_scrounger.is_mentioned_verbatim.assert_any_call( "Justin Bieber", text) self.assertEqual(len(filtered_songs), 0)
async def test_find_songs__mocked_spotify_client__song_w_single_artist( self, mock_read_file_contents): self.mock_spotify_client.find_song.return_value = [ Song("American Pie", "spotify:track:1fDsrQ23eTAVFElUMaf38X", ["Don McLean"], popularity=None), ] results = await self.song_scrounger.find_songs("mock file path") mock_read_file_contents.assert_called_once_with("mock file path") self.mock_spotify_client.find_song.assert_any_call("American Pie") self.assertEqual(1, len(results.keys())) self.assertIn("American Pie", results.keys()) self.assertEqual(len(results["American Pie"]), 1) self.assertEqual( set([song.spotify_uri for song in results["American Pie"]]), set(["spotify:track:1fDsrQ23eTAVFElUMaf38X"]))
async def test_find_media_items__same_item_mentioned_twice__returns_only_one_copy( self): text = "\"Sorry\" by Justin Bieber... as I said, \"Sorry\"..." self.song_scrounger._get_paragraphs = MagicMock(return_value=[text]) self.song_scrounger.find_names = MagicMock( return_value=["Sorry", "Sorry"]) songs = [ Song("Sorry", "spotify:track:09CtPGIpYB4BrO8qb1RGsF", ["Justin Bieber"]) ] self.mock_spotify_client.find_song = AsyncMock(return_value=set(songs)) self.song_scrounger.filter_if_any_artists_mentioned_greedy = MagicMock( return_value=set(songs)) self.song_scrounger.reduce_by_popularity_per_artist = MagicMock( return_value=set(songs)) results = await self.song_scrounger.find_media_items( text, self.mock_spotify_client.find_song) self.assertEqual(len(results.keys()), 1) self.assertTrue("Sorry" in results.keys()) self.assertEqual(len(results["Sorry"]), 1) self.assertEqual(results["Sorry"], set(songs))
async def test_filter_by_mentioned_artist__multiple_artist_per_song__skips_duplicates( self): text = "\"Sorry\" by Billie Eilish and brother Finneas O'Connell" songs = [ Song("bad guy", "spotify:track:2Fxmhks0bxGSBdJ92vM42m", ["Billie Eilish", "Finneas O'Connell"]) ] self.song_scrounger.is_mentioned_verbatim = MagicMock( return_value=True) filtered_songs = self.song_scrounger.filter_by_mentioned_artist( songs, text) self.assertTrue( get_num_times_called(self.song_scrounger.is_mentioned_verbatim) >= 1) self.assertEqual(len(filtered_songs), 1) filtered_songs_list = list(filtered_songs) self.assertEqual(filtered_songs_list[0].name, "bad guy") self.assertEqual(filtered_songs_list[0].spotify_uri, "spotify:track:2Fxmhks0bxGSBdJ92vM42m") self.assertEqual(filtered_songs_list[0].artists, ["Billie Eilish", "Finneas O'Connell"])
async def test_filter_if_any_artists_mentioned_greedy__immediate_matching_artist__avoid_extra_search_call( self): songs = [ Song( "American Pie", "spotify:track:1fDsrQ23eTAVFElUMaf38X", ["Don McLean"], ) ] self.song_scrounger.filter_if_any_artists_mentioned = MagicMock( return_value=set(songs)) results = self.song_scrounger.filter_if_any_artists_mentioned_greedy( songs, "\"American Pie\" by Don McLean", "\"American Pie\" by Don McLean") results = list(results) self.song_scrounger.filter_if_any_artists_mentioned.assert_called_once_with( songs, "\"American Pie\" by Don McLean") self.assertEqual(len(results), 1) self.assertEqual("American Pie", results[0].name) self.assertEqual(["Don McLean"], results[0].artists) self.assertEqual("spotify:track:1fDsrQ23eTAVFElUMaf38X", results[0].spotify_uri)
async def test__order_album_songs__full_album(self): songs_w_number = [ (Song("Good Day Sunshine - Remastered 2009", "", []), (8)), (Song("And Your Bird Can Sing - Remastered 2009", "", []), (9)), (Song("For No One - Remastered 2009", "", []), (10)), (Song("Doctor Robert - Remastered 2009", "", []), (11)), (Song("I Want To Tell You - Remastered 2009", "", []), (12)), (Song("Got To Get You Into My Life - Remastered 2009", "", []), (13)), (Song("Tomorrow Never Knows - Remastered 2009", "", []), (14)), (Song("Taxman - Remastered 2009", "", []), (1)), (Song("Eleanor Rigby - Remastered 2009", "", []), (2)), (Song("I'm Only Sleeping - Remastered 2009", "", []), (3)), (Song("Love You To - Remastered 2009", "", []), (4)), (Song("Here, There And Everywhere - Remastered 2009", "", []), (5)), (Song("Yellow Submarine - Remastered 2009", "", []), (6)), (Song("She Said She Said - Remastered 2009", "", []), (7)), ] expected_album_song_list = [ "Taxman - Remastered 2009", "Eleanor Rigby - Remastered 2009", "I'm Only Sleeping - Remastered 2009", "Love You To - Remastered 2009", "Here, There And Everywhere - Remastered 2009", "Yellow Submarine - Remastered 2009", "She Said She Said - Remastered 2009", "Good Day Sunshine - Remastered 2009", "And Your Bird Can Sing - Remastered 2009", "For No One - Remastered 2009", "Doctor Robert - Remastered 2009", "I Want To Tell You - Remastered 2009", "Got To Get You Into My Life - Remastered 2009", "Tomorrow Never Knows - Remastered 2009", ] ordered_songs = self.spotify_client._order_album_songs(songs_w_number) self.assertEqual([song.name for song in ordered_songs], expected_album_song_list)