diff --git a/test/plugins/lyrics_pages.py b/test/plugins/lyrics_pages.py new file mode 100644 index 0000000000..84c2457ba4 --- /dev/null +++ b/test/plugins/lyrics_pages.py @@ -0,0 +1,564 @@ +from __future__ import annotations + +import os +import textwrap +from typing import NamedTuple +from urllib.parse import urlparse + +import pytest + + +def xfail_on_ci(msg: str) -> pytest.MarkDecorator: + return pytest.mark.xfail( + bool(os.environ.get("GITHUB_ACTIONS")), + reason=msg, + raises=AssertionError, + ) + + +class LyricsPage(NamedTuple): + """Lyrics page representation for integrated tests.""" + + url: str + lyrics: str + artist: str = "The Beatles" + track_title: str = "Lady Madonna" + url_title: str | None = None # only relevant to the Google backend + marks: list[str] = [] # markers for pytest.param + + def __str__(self) -> str: + """Return name of this test case.""" + return f"{self.backend}-{self.source}" + + @classmethod + def make(cls, url, lyrics, *args, **kwargs): + return cls(url, textwrap.dedent(lyrics).strip(), *args, **kwargs) + + @property + def root_url(self) -> str: + return urlparse(self.url).netloc + + @property + def source(self) -> str: + return self.root_url.replace("www.", "").split(".")[0] + + @property + def backend(self) -> str: + if (source := self.source) in {"genius", "tekstowo", "lrclib"}: + return source + return "google" + + +lyrics_pages = [ + LyricsPage.make( + "http://www.absolutelyrics.com/lyrics/view/the_beatles/lady_madonna", + """ + The Beatles - Lady Madonna + + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + Who finds the money? When you pay the rent? + Did you think that money was heaven sent? + Friday night arrives without a suitcase. + Sunday morning creep in like a nun. + Monday's child has learned to tie his bootlace. + See how they run. + Lady Madonna, baby at your breast. + Wonder how you manage to feed the rest. + See how they run. + Lady Madonna, lying on the bed, + Listen to the music playing in your head. + Tuesday afternoon is never ending. + Wednesday morning papers didn't come. + Thursday night you stockings needed mending. + See how they run. + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + """, + url_title="Lady Madonna Lyrics :: The Beatles - Absolute Lyrics", + ), + LyricsPage.make( + "https://www.azlyrics.com/lyrics/beatles/ladymadonna.html", + """ + Lady Madonna, children at your feet + Wonder how you manage to make ends meet + Who finds the money when you pay the rent + Did you think that money was Heaven sent? + Friday night arrives without a suitcase + Sunday morning creeping like a nun + Monday's child has learned to tie his bootlace + See how they run + + Lady Madonna, baby at your breast + Wonders how you manage to feed the rest? + + See how they run + + Lady Madonna lying on the bed + Listen to the music playing in your head + + Tuesday afternoon is never ending + Wednesday morning papers didn't come + Thursday night your stockings needed mending + See how they run + + Lady Madonna, children at your feet + Wonder how you manage to make ends meet + """, + url_title="The Beatles - Lady Madonna Lyrics | AZLyrics.com", + marks=[xfail_on_ci("AZLyrics is blocked by Cloudflare")], + ), + LyricsPage.make( + "http://www.chartlyrics.com/_LsLsZ7P4EK-F-LD4dJgDQ/Lady+Madonna.aspx", + """ + Lady Madonna, + Children at your feet + Wonder how you manage to make ends meet. + + Who finds the money + When you pay the rent? + Did you think that money was heaven-sent? + + Friday night arrives without a suitcase. + Sunday morning creeping like a nun. + Monday's child has learned to tie his bootlace. + + See how they run. + + Lady Madonna, + Baby at your breast + Wonders how you manage to feed the rest. + + See how they run. + + Lady Madonna, + Lying on the bed. + Listen to the music playing in your head. + + Tuesday afternoon is never ending. + Wednesday morning papers didn't come. + Thursday night your stockings needed mending. + + See how they run. + + Lady Madonna, + Children at your feet + Wonder how you manage to make ends meet. + """, + url_title="The Beatles Lady Madonna lyrics", + ), + LyricsPage.make( + "https://genius.com/The-beatles-lady-madonna-lyrics", + """ + [Intro: Instrumental] + + [Verse 1: Paul McCartney] + Lady Madonna, children at your feet + Wonder how you manage to make ends meet + Who finds the money when you pay the rent? + Did you think that money was heaven sent? + + [Bridge: Paul McCartney] + Friday night arrives without a suitcase + Sunday morning creeping like a nun + Monday's child has learned to tie his bootlace + See how they run + + [Verse 2: Paul McCartney] + Lady Madonna, baby at your breast + Wonders how you manage to feed the rest + + [Bridge: Paul McCartney, John Lennon & George Harrison] + [Tenor Saxophone Solo: Ronnie Scott] + See how they run + + [Verse 3: Paul McCartney] + Lady Madonna, lying on the bed + Listen to the music playing in your head + + [Bridge: Paul McCartney] + Tuesday afternoon is never ending + Wednesday morning papers didn't come + Thursday night your stockings needed mending + See how they run + + [Verse 4: Paul McCartney] + Lady Madonna, children at your feet + Wonder how you manage to make ends meet + + [Outro: Instrumental] + """, + marks=[xfail_on_ci("Genius returns 403 FORBIDDEN in CI")], + ), + LyricsPage.make( + "https://www.lacoccinelle.net/259956-the-beatles-lady-madonna.html", + """ + Lady Madonna + Mademoiselle Madonna + + Lady Madonna, children at your feet. + Mademoiselle Madonna, les enfants à vos pieds + Wonder how you manage to make ends meet. + Je me demande comment vous vous débrouillez pour joindre les deux bouts + Who finds the money, when you pay the rent ? + Qui trouve l'argent pour payer le loyer ? + Did you think that money was heaven sent ? + Pensiez-vous que ça allait être envoyé du ciel ? + + Friday night arrives without a suitcase. + Le vendredi soir arrive sans bagages + Sunday morning creeping like a nun. + Le dimanche matin elle se traine comme une nonne + Monday's child has learned to tie his bootlace. + Lundi l'enfant a appris à lacer ses chaussures + See how they run. + Regardez comme ils courent + + Lady Madonna, baby at your breast. + Mademoiselle Madonna, le bébé a votre sein + Wonder how you manage to feed the rest. + Je me demande comment vous faites pour nourrir le reste + + Lady Madonna, lying on the bed, + Mademoiselle Madonna, couchée sur votre lit + Listen to the music playing in your head. + Vous écoutez la musique qui joue dans votre tête + """, + url_title="Paroles et traduction The Beatles : Lady Madonna - paroles de chanson", # noqa: E501 + ), + LyricsPage.make( + # note that this URL needs to be followed with a slash, otherwise it + # redirects to the same URL with a slash + "https://www.letras.mus.br/the-beatles/275/", + """ + Lady Madonna + Children at your feet + Wonder how you manage + To make ends meet + Who finds the money + When you pay the rent? + Did you think that money + Was Heaven sent? + Friday night arrives without a suitcase + Sunday morning creeping like a nun + Monday's child has learned + To tie his bootlace + See how they run + Lady Madonna + Baby at your breast + Wonders how you manage + To feed the rest + See how they run + Lady Madonna + Lying on the bed + Listen to the music + Playing in your head + Tuesday afternoon is neverending + Wednesday morning papers didn't come + Thursday night your stockings + Needed mending + See how they run + Lady Madonna + Children at your feet + Wonder how you manage + To make ends meet + """, + url_title="Lady Madonna - The Beatles - LETRAS.MUS.BR", + ), + LyricsPage.make( + "https://lrclib.net/api/get/14038", + """ + [00:08.35] Lady Madonna, children at your feet + [00:12.85] Wonder how you manage to make ends meet + [00:17.56] Who finds the money when you pay the rent + [00:21.78] Did you think that money was heaven sent + [00:26.22] Friday night arrives without a suitcase + [00:30.02] Sunday morning creeping like a nun + [00:34.53] Monday's child has learned to tie his bootlace + [00:39.18] See how they run + [00:43.33] Lady Madonna, baby at your breast + [00:48.50] Wonders how you manage to feed the rest + [00:52.54] + [01:01.32] Ba-ba, ba-ba, ba-ba, ba-ba-ba + [01:05.03] Ba-ba, ba-ba, ba-ba, ba, ba-ba, ba-ba + [01:09.58] Ba-ba, ba-ba, ba-ba, ba-ba-ba + [01:14.27] See how they run + [01:19.05] Lady Madonna, lying on the bed + [01:22.99] Listen to the music playing in your head + [01:27.92] + [01:36.33] Tuesday afternoon is never ending + [01:40.47] Wednesday morning papers didn't come + [01:44.76] Thursday night your stockings needed mending + [01:49.35] See how they run + [01:53.73] Lady Madonna, children at your feet + [01:58.65] Wonder how you manage to make ends meet + [02:06.04] + """, + ), + LyricsPage.make( + "https://www.lyricsmania.com/lady_madonna_lyrics_the_beatles.html", + """ + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + Who finds the money? When you pay the rent? + Did you think that money was heaven sent? + + Friday night arrives without a suitcase. + Sunday morning creep in like a nun. + Monday's child has learned to tie his bootlace. + See how they run. + + Lady Madonna, baby at your breast. + Wonder how you manage to feed the rest. + + See how they run. + Lady Madonna, lying on the bed, + Listen to the music playing in your head. + + Tuesday afternoon is never ending. + Wednesday morning papers didn't come. + Thursday night you stockings needed mending. + See how they run. + + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + """, + url_title="The Beatles - Lady Madonna Lyrics", + ), + LyricsPage.make( + "https://www.lyricsmode.com/lyrics/b/beatles/lady_madonna.html", + """ + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + Who finds the money? When you pay the rent? + Did you think that money was heaven sent? + + Friday night arrives without a suitcase. + Sunday morning creep in like a nun. + Mondays child has learned to tie his bootlace. + See how they run. + + Lady Madonna, baby at your breast. + Wonder how you manage to feed the rest. + + See how they run. + Lady Madonna, lying on the bed, + Listen to the music playing in your head. + + Tuesday afternoon is never ending. + Wednesday morning papers didn't come. + Thursday night you stockings needed mending. + See how they run. + + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + """, + url_title="Lady Madonna lyrics by The Beatles - original song full text. Official Lady Madonna lyrics, 2024 version | LyricsMode.com", # noqa: E501 + ), + LyricsPage.make( + "https://www.lyricsontop.com/amy-winehouse-songs/jazz-n-blues-lyrics.html", + """ + It's all gone within two days, + Follow my father + His extravagant ways + So, if I got it out I'll spend it all. + Heading In parkway, til I hit the wall. + I cross my fingers at the cash machine, + As I check my balance I kiss the screen, + I love it when it says I got the main's + To got o Miss Sixty and pick up my jeans. + Money ever last long + Had to fight what's wrong, + Blow it all on bags and shoes, + Jazz n' blues. + Money ever last long, + Had to fight what's wrong, + Blow it all on bags and shoes, + Jazz n' blues. + + Standing to the … bar today, + Waiting impatient to throw my cash away, + For that Russian JD and coke + Had the drinks all night, and now I am bold + But that's cool, cause I can buy more from you. + And I didn't forgot about that 50 Compton, + Tell you what? My fancy's coming through + I'll take you at shopping, can you wait til next June? + Yeah, Money ever last long + Had to fight what's wrong, + Blow it all on bags and shoes, + Jazz n' blues. + Money ever last long, + Had to fight what's wrong, + Blow it all on bags and shoes, + Jazz n' blues. + + (Instrumental Break) + + Money ever last long + Had to fight what's wrong, + Blow it all on bags and shoes, + Jazz n' blues. + Money ever last long, + Had to fight what's wrong, + Blow it all on bags and shoes, + Jazz n' blues. + Money ever last long, + Had to fight what's wrong, + Blow it all on bags and shoes, + Jazz n' blues. + """, + artist="Amy Winehouse", + track_title="Jazz N' Blues", + url_title="Amy Winehouse - Jazz N' Blues lyrics complete", + ), + LyricsPage.make( + "https://www.musica.com/letras.asp?letra=59862", + """ + Lady Madonna + Lady Madonna, children at your feet + Wonder how you manage to make ends meet + Who finds the money when you pay the rent? + Did you think that money was heaven sent? + Friday night arrives without a suitcase + Sunday morning creeping like a nun + Monday's child has learned to tie his bootlace + See how they run + Lady Madonna, baby at your breast + Wonders how you manage to feed the rest + See how they run + Lady Madonna lying on the bed + Listen to the music playing in your head + Tuesday afternoon is never ending + Wednesday morning papers didn't come + Thursday night your stockings needed mending + See how they run + Lady Madonna, children at your feet + Wonder how you manage to make ends meet + """, + url_title="Lady Madonna - Letra - The Beatles - Musica.com", + ), + LyricsPage.make( + "https://www.paroles.net/the-beatles/paroles-lady-madonna", + """ + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + Who finds the money? When you pay the rent? + Did you think that money was heaven sent? + + Friday night arrives without a suitcase. + Sunday morning creep in like a nun. + Monday's child has learned to tie his bootlace. + See how they run. + + Lady Madonna, baby at your breast. + Wonders how you manage to feed the rest. + + See how they run. + Lady Madonna, lying on the bed, + Listen to the music playing in your head. + """, + url_title="Paroles Lady Madonna par The Beatles - Lyrics - Paroles.net", + ), + LyricsPage.make( + "https://www.songlyrics.com/the-beatles/lady-madonna-lyrics", + """ + Lady Madonna, children at your feet + Wonder how you manage to make ends meet + Who finds the money? When you pay the rent? + Did you think that money was Heaven sent? + Friday night arrives without a suitcase + Sunday morning creep in like a nun + Monday's child has learned to tie his bootlace + See how they run + + Lady Madonna, baby at your breast + Wonder how you manage to feed the rest + + See how they run + + Lady Madonna, lying on the bed + Listen to the music playing in your head + + Tuesday afternoon is never ending + Wednesday morning papers didn't come + Thursday night you stockings needed mending + See how they run + + Lady Madonna, children at your feet + Wonder how you manage to make ends meet + """, + url_title="THE BEATLES - LADY MADONNA LYRICS", + ), + LyricsPage.make( + "https://sweetslyrics.com/the-beatles/lady-madonna-lyrics", + """ + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + Who finds the money when you pay the rent? + Did you think that money was heaven sent? + + Friday night arrives without a suitcase. + Sunday morning creeping like a nun. + Monday's child has learned to tie his bootlace. + See how they run... + + Lady Madonna, baby at your breast. + Wonders how you manage to feed the rest. + + (Sax solo) + + See how they run... + + Lady Madonna, lying on the bed. + Listen to the music playing in your head. + + Tuesday afternoon is never ending. + Wednesday morning papers didn't come. + Thursday night your stockings needed mending. + See how they run... + + Lady Madonna, children at your feet. + Wonder how you manage to make ends meet. + """, + url_title="The Beatles - Lady Madonna", + ), + LyricsPage.make( + "https://www.tekstowo.pl/piosenka,the_beatles,lady_madonna.html", + """ + Lady Madonna, + Children at your feet + Wonder how you manage to make ends meet. + + Who find the money + When you pay the rent? + Did you think that money was Heaven sent? + + Friday night arrives without a suitcase + Sunday morning creeping like a nun + Monday's child has learned to tie his bootlace + + See how they run + + Lady Madonna + Baby at your breast + Wonders how you manage to feed the rest + + See how they run + + Lady Madonna + Lying on the bed + Listen to the music playing in your head + + Tuesday afternoon is neverending + Wednesday morning papers didn't come + Thursday night your stockings needed mending + + See how they run + + Lady Madonna, + Children at your feet + Wonder how you manage to make ends meet + """, + ), +] diff --git a/test/plugins/test_lyrics.py b/test/plugins/test_lyrics.py index a222500b92..99e6f8a4e8 100644 --- a/test/plugins/test_lyrics.py +++ b/test/plugins/test_lyrics.py @@ -14,9 +14,7 @@ """Tests for the 'lyrics' plugin.""" -import os from functools import partial -from urllib.parse import urlparse import pytest @@ -24,6 +22,8 @@ from beets.test.helper import PluginMixin from beetsplug import lyrics +from .lyrics_pages import LyricsPage, lyrics_pages + PHRASE_BY_TITLE = { "Lady Madonna": "friday night arrives without a suitcase", "Jazz'n'blues": "as i check my balance i kiss the screen", @@ -31,14 +31,6 @@ } -def xfail_on_ci(msg: str) -> pytest.MarkDecorator: - return pytest.mark.xfail( - bool(os.environ.get("GITHUB_ACTIONS")), - reason=msg, - raises=AssertionError, - ) - - class TestLyricsUtils: @pytest.mark.parametrize( "artist, title", @@ -181,12 +173,16 @@ def plugin_config(self): return {} @pytest.fixture - def backend(self, backend_name, plugin_config): - """Set configuration and returns the backend instance.""" + def lyrics_plugin(self, backend_name, plugin_config): + """Set configuration and returns the plugin's instance.""" plugin_config["sources"] = [backend_name] self.config[self.plugin].set(plugin_config) - lyrics_plugin = lyrics.LyricsPlugin() + return lyrics.LyricsPlugin() + + @pytest.fixture + def backend(self, lyrics_plugin): + """Return a lyrics backend instance.""" return lyrics_plugin.backends[0] @pytest.fixture @@ -195,17 +191,48 @@ def lyrics_html(self, lyrics_root_dir, file_name): encoding="utf-8" ) - @pytest.mark.on_lyrics_update - def test_backend_source(self, backend): - """Test default backends with a song known to exist in respective - databases. - """ - title = "Lady Madonna" - lyrics = backend.fetch("The Beatles", title, "", 0) +@pytest.mark.on_lyrics_update +class TestLyricsSources(LyricsBackendTest): + @pytest.fixture(scope="class") + def plugin_config(self): + return {"google_API_key": "test", "synced": True} + + @pytest.fixture( + params=[pytest.param(lp, marks=lp.marks) for lp in lyrics_pages], + ids=str, + ) + def lyrics_page(self, request): + return request.param + + @pytest.fixture + def backend_name(self, lyrics_page): + return lyrics_page.backend + + @pytest.fixture(autouse=True) + def _patch_google_search(self, requests_mock, lyrics_page): + """Mock the Google Search API to return the lyrics page under test.""" + requests_mock.real_http = True + + data = { + "items": [ + { + "title": lyrics_page.url_title, + "link": lyrics_page.url, + "displayLink": lyrics_page.root_url, + } + ] + } + requests_mock.get(lyrics.Google.SEARCH_URL, json=data) + + def test_backend_source(self, lyrics_plugin, lyrics_page: LyricsPage): + """Test parsed lyrics from each of the configured lyrics pages.""" + lyrics = lyrics_plugin.get_lyrics( + lyrics_page.artist, lyrics_page.track_title, "", 0 + ) assert lyrics - assert PHRASE_BY_TITLE[title] in lyrics.lower() + assert lyrics == lyrics_page.lyrics class TestGoogleLyrics(LyricsBackendTest): @@ -225,100 +252,6 @@ def plugin_config(self): def file_name(self): return "examplecom/beetssong" - @pytest.fixture - def response_data(self, url_title, url): - return { - "items": [ - { - "title": url_title, - "link": url, - "displayLink": urlparse(url).netloc, - } - ] - } - - @pytest.fixture - def fetch_lyrics( - self, backend, requests_mock, response_data, artist, title - ): - requests_mock.get(backend.SEARCH_URL, json=response_data) - requests_mock.real_http = True - - return partial(backend.fetch, artist, title) - - @pytest.mark.on_lyrics_update - @pytest.mark.parametrize( - "artist, title, url_title, url", - [ - *( - ("The Beatles", "Lady Madonna", url_title, url) - for url_title, url in ( - ( - "The Beatles Lady Madonna lyrics", - "http://www.chartlyrics.com/_LsLsZ7P4EK-F-LD4dJgDQ/Lady+Madonna.aspx", - ), - ( - "Lady Madonna Lyrics :: The Beatles - Absolute Lyrics", - "http://www.absolutelyrics.com/lyrics/view/the_beatles/lady_madonna", - ), - ( - "Lady Madonna - The Beatles - LETRAS.MUS.BR", - "https://www.letras.mus.br/the-beatles/275/", - ), - ( - "The Beatles - Lady Madonna Lyrics", - "https://www.lyricsmania.com/lady_madonna_lyrics_the_beatles.html", - ), - ( - "Lady Madonna lyrics by The Beatles - original song full text. Official Lady Madonna lyrics, 2024 version | LyricsMode.com", # noqa: E501 - "https://www.lyricsmode.com/lyrics/b/beatles/lady_madonna.html", - ), - ( - "Paroles Lady Madonna par The Beatles - Lyrics - Paroles.net", - "https://www.paroles.net/the-beatles/paroles-lady-madonna", - ), - ( - "THE BEATLES - LADY MADONNA LYRICS", - "https://www.songlyrics.com/the-beatles/lady-madonna-lyrics/", - ), - ( - "The Beatles - Lady Madonna", - "https://sweetslyrics.com/the-beatles/lady-madonna-lyrics", - ), - ( - "Lady Madonna - Letra - The Beatles - Musica.com", - "https://www.musica.com/letras.asp?letra=59862", - ), - ( - "Paroles et traduction The Beatles : Lady Madonna - paroles de chanson", # noqa: E501 - "https://www.lacoccinelle.net/259956-the-beatles-lady-madonna.html", - ), - ) - ), - pytest.param( - "The Beatles", - "Lady Madonna", - "The Beatles - Lady Madonna Lyrics | AZLyrics.com", - "https://www.azlyrics.com/lyrics/beatles/ladymadonna.html", - marks=xfail_on_ci("AZLyrics is blocked by Cloudflare"), - ), - ( - "Amy Winehouse", - "Jazz'n'blues", - "Amy Winehouse - Jazz N' Blues lyrics complete", - "https://www.lyricsontop.com/amy-winehouse-songs/jazz-n-blues-lyrics.html", - ), - ], - ) - def test_backend_source(self, fetch_lyrics, title): - """Test if lyrics present on websites registered in beets google custom - search engine are correctly scraped. - """ - lyrics = fetch_lyrics() - - assert lyrics - assert PHRASE_BY_TITLE[title].lower() in lyrics.lower() - def test_mocked_source_ok(self, backend, lyrics_html): """Test that lyrics of the mocked page are correctly scraped""" result = lyrics.scrape_lyrics_from_html(lyrics_html).lower() @@ -374,11 +307,6 @@ class TestGeniusLyrics(LyricsBackendTest): def backend_name(self): return "genius" - @pytest.mark.on_lyrics_update - @xfail_on_ci("Genius returns 403 FORBIDDEN in CI") - def test_backend_source(self, backend): - super().test_backend_source(backend) - @pytest.mark.parametrize( "file_name, expected_line_count", [