/
/
/
1"""Tests for utility/helper functions."""
2
3import pytest
4from music_assistant_models.enums import MediaType
5from music_assistant_models.errors import MusicAssistantError
6
7from music_assistant.helpers import uri, util
8
9
10def test_version_extract() -> None:
11 """Test the extraction of version from title."""
12 test_str = "Bam Bam (feat. Ed Sheeran)"
13 title, version = util.parse_title_and_version(test_str)
14 assert title == "Bam Bam"
15 assert version == ""
16 test_str = "Bam Bam (feat. Ed Sheeran) - Karaoke Version"
17 title, version = util.parse_title_and_version(test_str)
18 assert title == "Bam Bam"
19 assert version == "Karaoke Version"
20 test_str = "Bam Bam (feat. Ed Sheeran) [Karaoke Version]"
21 title, version = util.parse_title_and_version(test_str)
22 assert title == "Bam Bam"
23 assert version == "Karaoke Version"
24 test_str = "SuperSong (2011 Remaster)"
25 title, version = util.parse_title_and_version(test_str)
26 assert title == "SuperSong"
27 assert version == "2011 Remaster"
28 test_str = "SuperSong (Live at Wembley)"
29 title, version = util.parse_title_and_version(test_str)
30 assert title == "SuperSong"
31 assert version == "Live at Wembley"
32 test_str = "SuperSong (Instrumental)"
33 title, version = util.parse_title_and_version(test_str)
34 assert title == "SuperSong"
35 assert version == "Instrumental"
36 test_str = "SuperSong (Explicit)"
37 title, version = util.parse_title_and_version(test_str)
38 assert title == "SuperSong"
39 assert version == ""
40 # Version keywords in main title should NOT be stripped (only in parentheses)
41 test_str = "Great live unplugged song"
42 title, version = util.parse_title_and_version(test_str)
43 assert title == "Great live unplugged song"
44 assert version == ""
45 test_str = "I Do (featuring Sonny of P.O.D.) (Album Version)"
46 title, version = util.parse_title_and_version(test_str)
47 assert title == "I Do"
48 assert version == "Album Version"
49 test_str = "Get Up Stand Up (Phunk Investigation instrumental club mix)"
50 title, version = util.parse_title_and_version(test_str)
51 assert title == "Get Up Stand Up"
52 assert version == "Phunk Investigation instrumental club mix"
53 # Complex case: non-version part + version part with 'mix' keyword
54 test_str = "Lovin' You More (That Big Track) (Mosquito Chillout mix)"
55 title, version = util.parse_title_and_version(test_str)
56 assert title == "Lovin' You More (That Big Track)"
57 assert version == "Mosquito Chillout mix"
58
59
60def test_with_handling_in_titles() -> None:
61 """Test 'with' handling - preserved in title, stripped as featuring credit."""
62 # 'with you' (preserved as title word)
63 test_str = "CCF (I'm Gonna Stay with You)"
64 title, version = util.parse_title_and_version(test_str)
65 assert title == "CCF (I'm Gonna Stay with You)"
66 assert version == ""
67 # 'with someone' (preserved as title word)
68 test_str = "Ever Fallen in Love (With Someone You Shouldn't've)"
69 title, version = util.parse_title_and_version(test_str)
70 assert title == "Ever Fallen in Love (With Someone You Shouldn't've)"
71 assert version == ""
72 # 'with u' (preserved as title word)
73 test_str = "Dance (With U)"
74 title, version = util.parse_title_and_version(test_str)
75 assert title == "Dance (With U)"
76 assert version == ""
77 # 'with the' (preserved as title word)
78 test_str = "Girl (With the Patent Leather Face)"
79 title, version = util.parse_title_and_version(test_str)
80 assert title == "Girl (With the Patent Leather Face)"
81 assert version == ""
82 # 'with you' - different phrasing (preserved as title word)
83 test_str = "Rockin' Around (With You)"
84 title, version = util.parse_title_and_version(test_str)
85 assert title == "Rockin' Around (With You)"
86 assert version == ""
87 # 'with no' (preserved as title word)
88 test_str = "Ain't Gonna Bump No More (With No Big Fat Woman)"
89 title, version = util.parse_title_and_version(test_str)
90 assert title == "Ain't Gonna Bump No More (With No Big Fat Woman)"
91 assert version == ""
92 # 'with that' - not in WITH_TITLE_WORDS but not stripped because it doesn't start with "with "
93 test_str = "The Catastrophe (Good Luck with That Man)"
94 title, version = util.parse_title_and_version(test_str)
95 assert title == "The Catastrophe (Good Luck with That Man)"
96 assert version == ""
97 # 'with [artist name]' - should still be stripped (not a title word)
98 test_str = "Great Song (with John Smith)"
99 title, version = util.parse_title_and_version(test_str)
100 assert title == "Great Song"
101 assert version == ""
102 # 'with [artist name]' in brackets - should still be stripped
103 test_str = "Great Song [with Jane Doe]"
104 title, version = util.parse_title_and_version(test_str)
105 assert title == "Great Song"
106 assert version == ""
107 # Title word preserved + version extracted from dash notation
108 test_str = "CCF (I'm Gonna Stay with You) - Live Version"
109 title, version = util.parse_title_and_version(test_str)
110 assert title == "CCF (I'm Gonna Stay with You)"
111 assert version == "Live Version"
112 # Title word preserved + version extracted from brackets
113 test_str = "Dance (With U) [Remix]"
114 title, version = util.parse_title_and_version(test_str)
115 assert title == "Dance (With U)"
116 assert version == "Remix"
117
118
119async def test_uri_parsing() -> None:
120 """Test parsing of URI."""
121 # test regular uri
122 test_uri = "spotify://track/123456789"
123 media_type, provider, item_id = await uri.parse_uri(test_uri)
124 assert media_type == MediaType.TRACK
125 assert provider == "spotify"
126 assert item_id == "123456789"
127 # test spotify uri
128 test_uri = "spotify:track:123456789"
129 media_type, provider, item_id = await uri.parse_uri(test_uri)
130 assert media_type == MediaType.TRACK
131 assert provider == "spotify"
132 assert item_id == "123456789"
133 # test public play/open url
134 test_uri = "https://open.spotify.com/playlist/5lH9NjOeJvctAO92ZrKQNB?si=04a63c8234ac413e"
135 media_type, provider, item_id = await uri.parse_uri(test_uri)
136 assert media_type == MediaType.PLAYLIST
137 assert provider == "spotify"
138 assert item_id == "5lH9NjOeJvctAO92ZrKQNB"
139 # test filename with slashes as item_id
140 test_uri = "filesystem://track/Artist/Album/Track.flac"
141 media_type, provider, item_id = await uri.parse_uri(test_uri)
142 assert media_type == MediaType.TRACK
143 assert provider == "filesystem"
144 assert item_id == "Artist/Album/Track.flac"
145 # test regular url to builtin provider
146 test_uri = "http://radiostream.io/stream.mp3"
147 media_type, provider, item_id = await uri.parse_uri(test_uri)
148 assert media_type == MediaType.UNKNOWN
149 assert provider == "builtin"
150 assert item_id == "http://radiostream.io/stream.mp3"
151 # test local file to builtin provider
152 test_uri = __file__
153 media_type, provider, item_id = await uri.parse_uri(test_uri)
154 assert media_type == MediaType.UNKNOWN
155 assert provider == "builtin"
156 assert item_id == __file__
157 # test invalid uri
158 with pytest.raises(MusicAssistantError):
159 await uri.parse_uri("invalid://blah")
160