yutipy 2.0.0__tar.gz → 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of yutipy might be problematic. Click here for more details.
- {yutipy-2.0.0 → yutipy-2.1.0}/PKG-INFO +1 -1
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/api_reference.rst +8 -0
- yutipy-2.1.0/tests/test_deezer.py +132 -0
- yutipy-2.1.0/tests/test_itunes.py +87 -0
- yutipy-2.1.0/tests/test_kkbox.py +104 -0
- yutipy-2.1.0/tests/test_musicyt.py +88 -0
- yutipy-2.1.0/tests/test_spotify.py +276 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/tests/test_utils.py +2 -2
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/deezer.py +5 -5
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/itunes.py +7 -7
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/kkbox.py +181 -72
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/models.py +13 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/musicyt.py +13 -12
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/spotify.py +211 -40
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/yutipy_music.py +2 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy.egg-info/PKG-INFO +1 -1
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy.egg-info/SOURCES.txt +0 -1
- yutipy-2.0.0/tests/test_deezer.py +0 -54
- yutipy-2.0.0/tests/test_itunes.py +0 -49
- yutipy-2.0.0/tests/test_kkbox.py +0 -44
- yutipy-2.0.0/tests/test_musicyt.py +0 -56
- yutipy-2.0.0/tests/test_spotify.py +0 -130
- yutipy-2.0.0/tests/test_yutipy_music.py +0 -48
- {yutipy-2.0.0 → yutipy-2.1.0}/.gitattributes +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/.github/FUNDING.yml +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/.github/dependabot.yml +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/.github/workflows/pytest-unit-testing.yml +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/.github/workflows/release.yml +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/.gitignore +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/.readthedocs.yaml +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/LICENSE +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/MANIFEST.in +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/README.md +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/Makefile +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/_static/yutipy_header.png +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/_static/yutipy_logo.png +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/available_platforms.rst +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/cli.rst +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/conf.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/faq.rst +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/index.rst +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/installation.rst +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/make.bat +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/requirements.txt +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/docs/usage_examples.rst +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/pyproject.toml +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/requirements-dev.txt +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/requirements.txt +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/setup.cfg +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/tests/__init__.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/tests/test_models.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/__init__.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/cli/__init__.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/cli/config.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/cli/search.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/exceptions.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/logger.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/utils/__init__.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy/utils/helpers.py +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy.egg-info/dependency_links.txt +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy.egg-info/entry_points.txt +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy.egg-info/requires.txt +0 -0
- {yutipy-2.0.0 → yutipy-2.1.0}/yutipy.egg-info/top_level.txt +0 -0
|
@@ -82,6 +82,14 @@ MusicInfos
|
|
|
82
82
|
:noindex:
|
|
83
83
|
:exclude-members: album_art, album_art_source, album_title, album_type, artists, genre, id, isrc, lyrics, release_date, tempo, title, type, upc, url
|
|
84
84
|
|
|
85
|
+
UserPlaying
|
|
86
|
+
-----------
|
|
87
|
+
|
|
88
|
+
.. autoclass:: yutipy.models.UserPlaying
|
|
89
|
+
:members:
|
|
90
|
+
:noindex:
|
|
91
|
+
:exclude-members: album_art, album_art_source, album_title, album_type, artists, genre, id, isrc, lyrics, release_date, tempo, title, type, upc, url, is_playing
|
|
92
|
+
|
|
85
93
|
Exceptions
|
|
86
94
|
=============
|
|
87
95
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from yutipy.deezer import Deezer
|
|
4
|
+
from yutipy.models import MusicInfo
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@pytest.fixture
|
|
8
|
+
def deezer():
|
|
9
|
+
return Deezer()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MockSearchResponse:
|
|
13
|
+
status_code = 200
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def raise_for_status():
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def json():
|
|
21
|
+
return {
|
|
22
|
+
"data": [
|
|
23
|
+
{
|
|
24
|
+
"id": "1234567",
|
|
25
|
+
"title": "Test Track",
|
|
26
|
+
"link": "https://www.deezer.com/track/1234567",
|
|
27
|
+
"type": "track",
|
|
28
|
+
"artist": {"id": "1", "name": "Artist X"},
|
|
29
|
+
"album": {
|
|
30
|
+
"id": "110678",
|
|
31
|
+
"title": "Test Album",
|
|
32
|
+
"cover_xl": "https://example.com/image/1234567",
|
|
33
|
+
"type": "album",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "789253",
|
|
38
|
+
"title": "Test Album",
|
|
39
|
+
"link": "https://www.deezer.com/track/789253",
|
|
40
|
+
"type": "album",
|
|
41
|
+
"cover_xl": "https://example.com/image/789253",
|
|
42
|
+
"record_type": "album",
|
|
43
|
+
"artist": {"id": "2", "name": "Artist Y"},
|
|
44
|
+
},
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class MockResponse:
|
|
50
|
+
status_code = 200
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def raise_for_status():
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def json():
|
|
58
|
+
return {
|
|
59
|
+
"id": "1234567",
|
|
60
|
+
"isrc": "ISRC",
|
|
61
|
+
"upc": "UPC",
|
|
62
|
+
"release_date": "2001-03-12",
|
|
63
|
+
"bpm": 0,
|
|
64
|
+
"genres": {
|
|
65
|
+
"data": [
|
|
66
|
+
{
|
|
67
|
+
"id": 113,
|
|
68
|
+
"name": "Dance",
|
|
69
|
+
"type": "genre",
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@pytest.fixture
|
|
77
|
+
def mock_response(deezer, monkeypatch):
|
|
78
|
+
def mock_get(*args, **kwargs):
|
|
79
|
+
return MockSearchResponse()
|
|
80
|
+
|
|
81
|
+
monkeypatch.setattr(deezer._Deezer__session, "get", mock_get)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_search_valid(deezer, mock_response):
|
|
85
|
+
result = deezer.search("Artist X", "Test Track", normalize_non_english=False)
|
|
86
|
+
assert result is not None
|
|
87
|
+
assert isinstance(result, MusicInfo)
|
|
88
|
+
assert result.title == "Test Track"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_search_invalid(deezer, mock_response):
|
|
92
|
+
result = deezer.search(
|
|
93
|
+
"Nonexistent Artist", "Nonexistent Song", normalize_non_english=False
|
|
94
|
+
)
|
|
95
|
+
assert result is None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_get_upc_isrc_track(deezer, monkeypatch):
|
|
99
|
+
def mock_get(*args, **kwargs):
|
|
100
|
+
return MockResponse()
|
|
101
|
+
|
|
102
|
+
monkeypatch.setattr(deezer._Deezer__session, "get", mock_get)
|
|
103
|
+
|
|
104
|
+
track_id = 1234567
|
|
105
|
+
result = deezer._get_upc_isrc(track_id, "track")
|
|
106
|
+
assert result is not None
|
|
107
|
+
assert "isrc" in result
|
|
108
|
+
assert "release_date" in result
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_get_upc_isrc_album(deezer, monkeypatch):
|
|
112
|
+
|
|
113
|
+
def mock_get(*args, **kwargs):
|
|
114
|
+
return MockResponse()
|
|
115
|
+
|
|
116
|
+
monkeypatch.setattr(deezer._Deezer__session, "get", mock_get)
|
|
117
|
+
|
|
118
|
+
album_id = 1234567
|
|
119
|
+
result = deezer._get_upc_isrc(album_id, "album")
|
|
120
|
+
assert result is not None
|
|
121
|
+
assert "upc" in result
|
|
122
|
+
assert "release_date" in result
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_search_no_results(deezer, mock_response):
|
|
126
|
+
result = deezer.search("Adele", "Nonexistent Song", normalize_non_english=False)
|
|
127
|
+
assert result is None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_close_session(deezer):
|
|
131
|
+
deezer.close_session()
|
|
132
|
+
assert deezer.is_session_closed
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pytest import raises
|
|
3
|
+
|
|
4
|
+
from yutipy.itunes import Itunes
|
|
5
|
+
from yutipy.models import MusicInfo
|
|
6
|
+
from yutipy.exceptions import InvalidValueException
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture
|
|
10
|
+
def itunes():
|
|
11
|
+
return Itunes()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MockResponse:
|
|
15
|
+
status_code = 200
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def raise_for_status():
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def json():
|
|
23
|
+
return {
|
|
24
|
+
"results": [
|
|
25
|
+
{
|
|
26
|
+
"wrapperType": "track",
|
|
27
|
+
"kind": "song",
|
|
28
|
+
"collectionId": 12345678,
|
|
29
|
+
"trackId": 91011123,
|
|
30
|
+
"artistName": "Artist X",
|
|
31
|
+
"collectionName": "Test Album",
|
|
32
|
+
"trackName": "Test Track",
|
|
33
|
+
"collectionViewUrl": "https://itunes.apple.com/12345678",
|
|
34
|
+
"trackViewUrl": "https://itunes.apple.com/91011123",
|
|
35
|
+
"artworkUrl100": "https://example.com/image/12345678",
|
|
36
|
+
"trackCount": 14,
|
|
37
|
+
"releaseDate": "2016-08-11T12:00:00Z",
|
|
38
|
+
"primaryGenreName": "Rock",
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.fixture
|
|
45
|
+
def mock_response(itunes, monkeypatch):
|
|
46
|
+
def mock_get(*args, **kwargs):
|
|
47
|
+
return MockResponse()
|
|
48
|
+
|
|
49
|
+
monkeypatch.setattr(itunes._Itunes__session, "get", mock_get)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_search_valid(itunes, mock_response):
|
|
53
|
+
artist = "Artist X"
|
|
54
|
+
song = "Test Track"
|
|
55
|
+
result = itunes.search(artist, song, normalize_non_english=False)
|
|
56
|
+
assert result is not None
|
|
57
|
+
assert isinstance(result, MusicInfo)
|
|
58
|
+
assert result.artists == artist
|
|
59
|
+
assert result.title == song
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_search_invalid(itunes, mock_response):
|
|
63
|
+
artist = "Nonexistent Artist"
|
|
64
|
+
song = "Nonexistent Song"
|
|
65
|
+
result = itunes.search(artist, song, normalize_non_english=False)
|
|
66
|
+
assert result is None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_search_empty_artist(itunes, mock_response):
|
|
70
|
+
artist = ""
|
|
71
|
+
song = "Test Track"
|
|
72
|
+
|
|
73
|
+
with raises(InvalidValueException):
|
|
74
|
+
itunes.search(artist, song)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_search_empty_song(itunes, mock_response):
|
|
78
|
+
artist = "Artist X"
|
|
79
|
+
song = ""
|
|
80
|
+
|
|
81
|
+
with raises(InvalidValueException):
|
|
82
|
+
itunes.search(artist, song)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_close_session(itunes):
|
|
86
|
+
itunes.close_session()
|
|
87
|
+
assert itunes.is_session_closed
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pytest import raises
|
|
3
|
+
|
|
4
|
+
from yutipy.exceptions import InvalidValueException
|
|
5
|
+
from yutipy.models import MusicInfo
|
|
6
|
+
from yutipy.kkbox import KKBox
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(scope="module")
|
|
10
|
+
def kkbox():
|
|
11
|
+
def mock_get_access_token():
|
|
12
|
+
return {
|
|
13
|
+
"access_token": "test_access_token",
|
|
14
|
+
"expires_in": 3600,
|
|
15
|
+
"requested_at": 1234567890,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
kkbox_instance = KKBox(
|
|
19
|
+
client_id="test_client_id", client_secret="test_client_secret", defer_load=True
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
kkbox_instance._KKBox__get_access_token = mock_get_access_token
|
|
23
|
+
kkbox_instance.load_token_after_init()
|
|
24
|
+
return kkbox_instance
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class MockResponse:
|
|
28
|
+
status_code = 200
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def raise_for_status():
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def json():
|
|
36
|
+
return {
|
|
37
|
+
"tracks": {
|
|
38
|
+
"data": [
|
|
39
|
+
{
|
|
40
|
+
"id": "123456",
|
|
41
|
+
"name": "Test Track",
|
|
42
|
+
"isrc": "ISRC",
|
|
43
|
+
"url": "https://kkbox.com/track/123456",
|
|
44
|
+
"album": {
|
|
45
|
+
"id": "78910",
|
|
46
|
+
"name": "Test Album",
|
|
47
|
+
"url": "https://kkbox.com/album/78910",
|
|
48
|
+
"release_date": "2001-10-12",
|
|
49
|
+
"images": [
|
|
50
|
+
{"url": "https://example.com/image/78910_128"},
|
|
51
|
+
{"url": "https://example.com/image/78910_512"},
|
|
52
|
+
{"url": "https://example.com/image/78910_1000"},
|
|
53
|
+
],
|
|
54
|
+
"artist": {
|
|
55
|
+
"id": "65791",
|
|
56
|
+
"name": "Artist X",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@pytest.fixture
|
|
66
|
+
def mock_response(kkbox, monkeypatch):
|
|
67
|
+
def mock_get(*args, **kwargs):
|
|
68
|
+
return MockResponse()
|
|
69
|
+
|
|
70
|
+
monkeypatch.setattr(kkbox._KKBox__session, "get", mock_get)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_search(kkbox, mock_response):
|
|
74
|
+
artist = "Artist X"
|
|
75
|
+
song = "Test Track"
|
|
76
|
+
result = kkbox.search(artist, song, normalize_non_english=False)
|
|
77
|
+
assert result is not None
|
|
78
|
+
assert isinstance(result, MusicInfo)
|
|
79
|
+
assert result.title == song
|
|
80
|
+
assert artist in result.artists
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_get_html_widget(kkbox):
|
|
84
|
+
html_widget = kkbox.get_html_widget(id="8rceGrek59bDS0HmQH", content_type="song")
|
|
85
|
+
assert html_widget is not None
|
|
86
|
+
assert isinstance(html_widget, str)
|
|
87
|
+
|
|
88
|
+
with raises(InvalidValueException):
|
|
89
|
+
kkbox.get_html_widget(id="8rceGrek59bDS0HmQH", content_type="track")
|
|
90
|
+
|
|
91
|
+
with raises(InvalidValueException):
|
|
92
|
+
kkbox.get_html_widget(
|
|
93
|
+
id="8rceGrek59bDS0HmQH", content_type="song", territory="US"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
with raises(InvalidValueException):
|
|
97
|
+
kkbox.get_html_widget(
|
|
98
|
+
id="8rceGrek59bDS0HmQH", content_type="song", widget_lang="JP"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_close_session(kkbox):
|
|
103
|
+
kkbox.close_session()
|
|
104
|
+
assert kkbox.is_session_closed
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pytest import raises
|
|
3
|
+
from yutipy.musicyt import MusicYT
|
|
4
|
+
from yutipy.models import MusicInfo
|
|
5
|
+
from yutipy.exceptions import InvalidValueException
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@pytest.fixture
|
|
9
|
+
def music_yt():
|
|
10
|
+
return MusicYT()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.fixture
|
|
14
|
+
def mock_ytmusic_search(music_yt, monkeypatch):
|
|
15
|
+
def mock_search(*args, **kwargs):
|
|
16
|
+
return [
|
|
17
|
+
{
|
|
18
|
+
"category": "Songs",
|
|
19
|
+
"resultType": "song",
|
|
20
|
+
"videoId": "ZrOKjDZOtkA",
|
|
21
|
+
"title": "Test Song",
|
|
22
|
+
"artists": [{"name": "Test Artist", "id": "ADlkasoiuUUer34ldb"}],
|
|
23
|
+
"album": {"name": "Test Album", "id": "MIekd34_934"},
|
|
24
|
+
"microformat": {
|
|
25
|
+
"microformatDataRenderer": {"uploadDate": "1969-12-31"}
|
|
26
|
+
},
|
|
27
|
+
"thumbnails": [{"url": "https://example.com/image/ZrOKjDZOtkA"}],
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
def mock_get_watch_playlist(*args, **kwargs):
|
|
32
|
+
return {"lyrics": "MPLYt_HNNclO0Ddoc-17"}
|
|
33
|
+
|
|
34
|
+
def mock_get_lyrics(*args, **kwargs):
|
|
35
|
+
return {"lyrics": "Never Gonna Give You Up!"}
|
|
36
|
+
|
|
37
|
+
# Patch the `search` and other methods of the `YTMusic` class
|
|
38
|
+
monkeypatch.setattr("ytmusicapi.YTMusic.search", mock_search)
|
|
39
|
+
monkeypatch.setattr(
|
|
40
|
+
"ytmusicapi.YTMusic.get_watch_playlist", mock_get_watch_playlist
|
|
41
|
+
)
|
|
42
|
+
monkeypatch.setattr("ytmusicapi.YTMusic.get_lyrics", mock_get_lyrics)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_search_valid(music_yt, mock_ytmusic_search):
|
|
46
|
+
artist = "Test Artist"
|
|
47
|
+
song = "Test Song"
|
|
48
|
+
result = music_yt.search(artist, song, normalize_non_english=False)
|
|
49
|
+
assert result is not None
|
|
50
|
+
assert isinstance(result, MusicInfo)
|
|
51
|
+
assert artist in result.artists
|
|
52
|
+
assert result.title == song
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_search_invalid(music_yt, mock_ytmusic_search):
|
|
56
|
+
artist = ";laksjdflkajsdfj;asdjf"
|
|
57
|
+
song = "jaksjd;fljkas;dfkjasldkjf"
|
|
58
|
+
result = music_yt.search(artist, song)
|
|
59
|
+
assert result is None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_search_partial_match(music_yt, mock_ytmusic_search):
|
|
63
|
+
artist = "Test"
|
|
64
|
+
song = "Test"
|
|
65
|
+
result = music_yt.search(artist, song, normalize_non_english=False)
|
|
66
|
+
assert result is not None
|
|
67
|
+
assert song in result.title
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_search_empty_artist(music_yt, mock_ytmusic_search):
|
|
71
|
+
artist = ""
|
|
72
|
+
song = "Song"
|
|
73
|
+
|
|
74
|
+
with raises(InvalidValueException):
|
|
75
|
+
music_yt.search(artist, song, normalize_non_english=False)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_search_empty_song(music_yt, mock_ytmusic_search):
|
|
79
|
+
artist = "Artist"
|
|
80
|
+
song = ""
|
|
81
|
+
|
|
82
|
+
with raises(InvalidValueException):
|
|
83
|
+
music_yt.search(artist, song, normalize_non_english=False)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def test_close_session(music_yt):
|
|
87
|
+
music_yt.close_session()
|
|
88
|
+
assert music_yt.is_session_closed
|