1#!/usr/bin/env python
2"""
3Integration (not unit) tests for pylast.py
4"""
5import pytest
6
7import pylast
8
9from .test_pylast import WRITE_TEST, TestPyLastWithLastFm
10
11
12class TestPyLastArtist(TestPyLastWithLastFm):
13    def test_repr(self):
14        # Arrange
15        artist = pylast.Artist("Test Artist", self.network)
16
17        # Act
18        representation = repr(artist)
19
20        # Assert
21        assert representation.startswith("pylast.Artist('Test Artist',")
22
23    def test_artist_is_hashable(self):
24        # Arrange
25        test_artist = self.network.get_artist("Radiohead")
26        artist = test_artist.get_similar(limit=2)[0].item
27        assert isinstance(artist, pylast.Artist)
28
29        # Act/Assert
30        self.helper_is_thing_hashable(artist)
31
32    def test_bio_published_date(self):
33        # Arrange
34        artist = pylast.Artist("Test Artist", self.network)
35
36        # Act
37        bio = artist.get_bio_published_date()
38
39        # Assert
40        assert bio is not None
41        assert len(bio) >= 1
42
43    def test_bio_content(self):
44        # Arrange
45        artist = pylast.Artist("Test Artist", self.network)
46
47        # Act
48        bio = artist.get_bio_content(language="en")
49
50        # Assert
51        assert bio is not None
52        assert len(bio) >= 1
53
54    def test_bio_content_none(self):
55        # Arrange
56        # An artist with no biography, with "<content/>" in the API XML
57        artist = pylast.Artist("Mr Sizef + Unquote", self.network)
58
59        # Act
60        bio = artist.get_bio_content()
61
62        # Assert
63        assert bio is None
64
65    def test_bio_summary(self):
66        # Arrange
67        artist = pylast.Artist("Test Artist", self.network)
68
69        # Act
70        bio = artist.get_bio_summary(language="en")
71
72        # Assert
73        assert bio is not None
74        assert len(bio) >= 1
75
76    def test_artist_top_tracks(self):
77        # Arrange
78        # Pick an artist with plenty of plays
79        artist = self.network.get_top_artists(limit=1)[0].item
80
81        # Act
82        things = artist.get_top_tracks(limit=2)
83
84        # Assert
85        self.helper_two_different_things_in_top_list(things, pylast.Track)
86
87    def test_artist_top_albums(self):
88        # Arrange
89        # Pick an artist with plenty of plays
90        artist = self.network.get_top_artists(limit=1)[0].item
91
92        # Act
93        things = list(artist.get_top_albums(limit=2))
94
95        # Assert
96        self.helper_two_different_things_in_top_list(things, pylast.Album)
97
98    @pytest.mark.parametrize("test_limit", [1, 50, 100])
99    def test_artist_top_albums_limit(self, test_limit: int) -> None:
100        # Arrange
101        # Pick an artist with plenty of plays
102        artist = self.network.get_top_artists(limit=1)[0].item
103
104        # Act
105        things = artist.get_top_albums(limit=test_limit)
106
107        # Assert
108        assert len(things) == test_limit
109
110    def test_artist_top_albums_limit_default(self):
111        # Arrange
112        # Pick an artist with plenty of plays
113        artist = self.network.get_top_artists(limit=1)[0].item
114
115        # Act
116        things = artist.get_top_albums()
117
118        # Assert
119        assert len(things) == 50
120
121    def test_artist_listener_count(self):
122        # Arrange
123        artist = self.network.get_artist("Test Artist")
124
125        # Act
126        count = artist.get_listener_count()
127
128        # Assert
129        assert isinstance(count, int)
130        assert count > 0
131
132    @pytest.mark.skipif(not WRITE_TEST, reason="Only test once to avoid collisions")
133    def test_tag_artist(self):
134        # Arrange
135        artist = self.network.get_artist("Test Artist")
136        # artist.clear_tags()
137
138        # Act
139        artist.add_tag("testing")
140
141        # Assert
142        tags = artist.get_tags()
143        assert len(tags) > 0
144        found = any(tag.name == "testing" for tag in tags)
145        assert found
146
147    @pytest.mark.skipif(not WRITE_TEST, reason="Only test once to avoid collisions")
148    def test_remove_tag_of_type_text(self):
149        # Arrange
150        tag = "testing"  # text
151        artist = self.network.get_artist("Test Artist")
152        artist.add_tag(tag)
153
154        # Act
155        artist.remove_tag(tag)
156
157        # Assert
158        tags = artist.get_tags()
159        found = any(tag.name == "testing" for tag in tags)
160        assert not found
161
162    @pytest.mark.skipif(not WRITE_TEST, reason="Only test once to avoid collisions")
163    def test_remove_tag_of_type_tag(self):
164        # Arrange
165        tag = pylast.Tag("testing", self.network)  # Tag
166        artist = self.network.get_artist("Test Artist")
167        artist.add_tag(tag)
168
169        # Act
170        artist.remove_tag(tag)
171
172        # Assert
173        tags = artist.get_tags()
174        found = any(tag.name == "testing" for tag in tags)
175        assert not found
176
177    @pytest.mark.skipif(not WRITE_TEST, reason="Only test once to avoid collisions")
178    def test_remove_tags(self):
179        # Arrange
180        tags = ["removetag1", "removetag2"]
181        artist = self.network.get_artist("Test Artist")
182        artist.add_tags(tags)
183        artist.add_tags("1more")
184        tags_before = artist.get_tags()
185
186        # Act
187        artist.remove_tags(tags)
188
189        # Assert
190        tags_after = artist.get_tags()
191        assert len(tags_after) == len(tags_before) - 2
192        found1 = any(tag.name == "removetag1" for tag in tags_after)
193        found2 = any(tag.name == "removetag2" for tag in tags_after)
194        assert not found1
195        assert not found2
196
197    @pytest.mark.skipif(not WRITE_TEST, reason="Only test once to avoid collisions")
198    def test_set_tags(self):
199        # Arrange
200        tags = ["sometag1", "sometag2"]
201        artist = self.network.get_artist("Test Artist 2")
202        artist.add_tags(tags)
203        tags_before = artist.get_tags()
204        new_tags = ["settag1", "settag2"]
205
206        # Act
207        artist.set_tags(new_tags)
208
209        # Assert
210        tags_after = artist.get_tags()
211        assert tags_before != tags_after
212        assert len(tags_after) == 2
213        found1, found2 = False, False
214        for tag in tags_after:
215            if tag.name == "settag1":
216                found1 = True
217            elif tag.name == "settag2":
218                found2 = True
219        assert found1
220        assert found2
221
222    def test_artists(self):
223        # Arrange
224        artist1 = self.network.get_artist("Radiohead")
225        artist2 = self.network.get_artist("Portishead")
226
227        # Act
228        url = artist1.get_url()
229        mbid = artist1.get_mbid()
230
231        playcount = artist1.get_playcount()
232        streamable = artist1.is_streamable()
233        name = artist1.get_name(properly_capitalized=False)
234        name_cap = artist1.get_name(properly_capitalized=True)
235
236        # Assert
237        assert playcount > 1
238        assert artist1 != artist2
239        assert name.lower() == name_cap.lower()
240        assert url == "https://www.last.fm/music/radiohead"
241        assert mbid == "a74b1b7f-71a5-4011-9441-d0b5e4122711"
242        assert isinstance(streamable, bool)
243
244    def test_artist_eq_none_is_false(self):
245        # Arrange
246        artist1 = None
247        artist2 = pylast.Artist("Test Artist", self.network)
248
249        # Act / Assert
250        assert artist1 != artist2
251
252    def test_artist_ne_none_is_true(self):
253        # Arrange
254        artist1 = None
255        artist2 = pylast.Artist("Test Artist", self.network)
256
257        # Act / Assert
258        assert artist1 != artist2
259
260    def test_artist_get_correction(self):
261        # Arrange
262        artist = pylast.Artist("guns and roses", self.network)
263
264        # Act
265        corrected_artist_name = artist.get_correction()
266
267        # Assert
268        assert corrected_artist_name == "Guns N' Roses"
269
270    @pytest.mark.xfail
271    def test_get_userplaycount(self):
272        # Arrange
273        artist = pylast.Artist("John Lennon", self.network, username=self.username)
274
275        # Act
276        playcount = artist.get_userplaycount()
277
278        # Assert
279        assert playcount >= 0  # whilst xfail: # pragma: no cover
280