Completed
Push — py36 ( 69001a )
by Hugo
04:52
created

TestPyLastWithLibreFm   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 18
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 18
rs 10
wmc 1

1 Method

Rating   Name   Duplication   Size   Complexity  
A test_libre_fm() 0 14 1
1
#!/usr/bin/env python
2
"""
3
Integration (not unit) tests for pylast.py
4
"""
5
from flaky import flaky
6
import os
7
import pytest
8
from random import choice
9
import time
10
import unittest
11
12
import pylast
13
14
15
def load_secrets():
16
    secrets_file = "test_pylast.yaml"
17
    if os.path.isfile(secrets_file):
18
        import yaml  # pip install pyyaml
19
        with open(secrets_file, "r") as f:  # see example_test_pylast.yaml
20
            doc = yaml.load(f)
21
    else:
22
        doc = {}
23
        try:
24
            doc["username"] = os.environ['PYLAST_USERNAME'].strip()
25
            doc["password_hash"] = os.environ['PYLAST_PASSWORD_HASH'].strip()
26
            doc["api_key"] = os.environ['PYLAST_API_KEY'].strip()
27
            doc["api_secret"] = os.environ['PYLAST_API_SECRET'].strip()
28
        except KeyError:
29
            pytest.skip("Missing environment variables: PYLAST_USERNAME etc.")
30
    return doc
31
32
33
def handle_lastfm_exceptions(f):
34
    """Skip exceptions caused by Last.fm's broken API"""
35
    def wrapper(*args, **kw):
36
        try:
37
            return f(*args, **kw)
38
        except pylast.WSError as e:
39
            if (str(e) == "Invalid Method - "
40
                          "No method with that name in this package"):
41
                msg = "Ignore broken Last.fm API: " + str(e)
42
                print(msg)
43
                pytest.skip(msg)
44
            else:
45
                raise(e)
46
    return wrapper
47
48
49
@flaky(max_runs=5, min_passes=1)
50
class TestPyLast(unittest.TestCase):
51
52
    secrets = None
53
54
    def unix_timestamp(self):
55
        return int(time.time())
56
57
    def setUp(self):
58
        if self.__class__.secrets is None:
59
            self.__class__.secrets = load_secrets()
60
61
        self.username = self.__class__.secrets["username"]
62
        password_hash = self.__class__.secrets["password_hash"]
63
64
        API_KEY = self.__class__.secrets["api_key"]
65
        API_SECRET = self.__class__.secrets["api_secret"]
66
67
        self.network = pylast.LastFMNetwork(
68
            api_key=API_KEY, api_secret=API_SECRET,
69
            username=self.username, password_hash=password_hash)
70
71
    def skip_if_lastfm_api_broken(self, value):
72
        """Skip things not yet restored in Last.fm's broken API"""
73
        if value is None or len(value) == 0:
74
            pytest.skip("Last.fm API is broken.")
75
76
    @handle_lastfm_exceptions
77
    def test_scrobble(self):
78
        # Arrange
79
        artist = "Test Artist"
80
        title = "Test Title"
81
        timestamp = self.unix_timestamp()
82
        lastfm_user = self.network.get_user(self.username)
83
84
        # Act
85
        self.network.scrobble(artist=artist, title=title, timestamp=timestamp)
86
87
        # Assert
88
        # limit=2 to ignore now-playing:
89
        last_scrobble = lastfm_user.get_recent_tracks(limit=2)[0]
90
        self.assertEqual(str(last_scrobble.track.artist), str(artist))
91
        self.assertEqual(str(last_scrobble.track.title),  str(title))
92
        self.assertEqual(str(last_scrobble.timestamp),    str(timestamp))
93
94
    @handle_lastfm_exceptions
95
    def test_unscrobble(self):
96
        # Arrange
97
        artist = "Test Artist 2"
98
        title = "Test Title 2"
99
        timestamp = self.unix_timestamp()
100
        library = pylast.Library(user=self.username, network=self.network)
101
        self.network.scrobble(artist=artist, title=title, timestamp=timestamp)
102
        lastfm_user = self.network.get_user(self.username)
103
104
        # Act
105
        library.remove_scrobble(
106
            artist=artist, title=title, timestamp=timestamp)
107
108
        # Assert
109
        # limit=2 to ignore now-playing:
110
        last_scrobble = lastfm_user.get_recent_tracks(limit=2)[0]
111
        self.assertNotEqual(str(last_scrobble.timestamp), str(timestamp))
112
113
    @handle_lastfm_exceptions
114
    def test_add_album(self):
115
        # Arrange
116
        library = pylast.Library(user=self.username, network=self.network)
117
        album = self.network.get_album("Test Artist", "Test Album")
118
119
        # Act
120
        library.add_album(album)
121
122
        # Assert
123
        my_albums = library.get_albums()
124
        for my_album in my_albums:
125
            value = (album == my_album[0])
126
            if value:
127
                break
128
        self.assertTrue(value)
129
130 View Code Duplication
    @handle_lastfm_exceptions
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
131
    def test_remove_album(self):
132
        # Arrange
133
        library = pylast.Library(user=self.username, network=self.network)
134
        # Pick an artist with plenty of albums
135
        artist = self.network.get_top_artists(limit=1)[0].item
136
        albums = artist.get_top_albums()
137
        # Pick a random one to avoid problems running concurrent tests
138
        album = choice(albums)[0]
139
        library.add_album(album)
140
141
        # Act
142
        library.remove_album(album)
143
144
        # Assert
145
        my_albums = library.get_albums()
146
        for my_album in my_albums:
147
            value = (album == my_album[0])
148
            if value:
149
                break
150
        self.assertFalse(value)
151
152
    @handle_lastfm_exceptions
153
    def test_add_artist(self):
154
        # Arrange
155
        artist = "Test Artist 2"
156
        library = pylast.Library(user=self.username, network=self.network)
157
158
        # Act
159
        library.add_artist(artist)
160
161
        # Assert
162
        artists = library.get_artists()
163
        for artist in artists:
164
            value = (str(artist[0]) == "Test Artist 2")
165
            if value:
166
                break
167
        self.assertTrue(value)
168
169 View Code Duplication
    @handle_lastfm_exceptions
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
170
    def test_remove_artist(self):
171
        # Arrange
172
        # Get plenty of artists
173
        artists = self.network.get_top_artists()
174
        # Pick a random one to avoid problems running concurrent tests
175
        my_artist = choice(artists).item
176
        library = pylast.Library(user=self.username, network=self.network)
177
        library.add_artist(my_artist)
178
179
        # Act
180
        library.remove_artist(my_artist)
181
182
        # Assert
183
        artists = library.get_artists()
184
        for artist in artists:
185
            value = (artist[0] == my_artist)
186
            if value:
187
                break
188
        self.assertFalse(value)
189
190
    @handle_lastfm_exceptions
191
    def test_get_venue(self):
192
        # Arrange
193
        venue_name = "Last.fm Office"
194
        country_name = "United Kingdom"
195
196
        # Act
197
        venue_search = self.network.search_for_venue(venue_name, country_name)
198
        venue = venue_search.get_next_page()[0]
199
200
        # Assert
201
        self.assertEqual(str(venue.id), "8778225")
202
203
    @handle_lastfm_exceptions
204
    def test_get_user_registration(self):
205
        # Arrange
206
        username = "RJ"
207
        user = self.network.get_user(username)
208
209
        # Act
210
        registered = user.get_registered()
211
212
        # Assert
213
        # Last.fm API broken? Should be yyyy-mm-dd not Unix timestamp
214
        if int(registered):
215
            pytest.skip("Last.fm API is broken.")
216
217
        # Just check date because of timezones
218
        self.assertIn(u"2002-11-20 ", registered)
219
220
    @handle_lastfm_exceptions
221
    def test_get_user_unixtime_registration(self):
222
        # Arrange
223
        username = "RJ"
224
        user = self.network.get_user(username)
225
226
        # Act
227
        unixtime_registered = user.get_unixtime_registered()
228
229
        # Assert
230
        # Just check date because of timezones
231
        self.assertEqual(unixtime_registered, u"1037793040")
232
233
    @handle_lastfm_exceptions
234
    def test_get_genderless_user(self):
235
        # Arrange
236
        # Currently test_user has no gender set:
237
        lastfm_user = self.network.get_user("test_user")
238
239
        # Act
240
        gender = lastfm_user.get_gender()
241
242
        # Assert
243
        self.assertIsNone(gender)
244
245
    @handle_lastfm_exceptions
246
    def test_get_countryless_user(self):
247
        # Arrange
248
        # Currently test_user has no country set:
249
        lastfm_user = self.network.get_user("test_user")
250
251
        # Act
252
        country = lastfm_user.get_country()
253
254
        # Assert
255
        self.assertIsNone(country)
256
257
    @handle_lastfm_exceptions
258
    def test_love(self):
259
        # Arrange
260
        artist = "Test Artist"
261
        title = "Test Title"
262
        track = self.network.get_track(artist, title)
263
        lastfm_user = self.network.get_user(self.username)
264
265
        # Act
266
        track.love()
267
268
        # Assert
269
        loved = lastfm_user.get_loved_tracks(limit=1)
270
        self.assertEqual(str(loved[0].track.artist), "Test Artist")
271
        self.assertEqual(str(loved[0].track.title), "Test Title")
272
273
    @handle_lastfm_exceptions
274
    def test_unlove(self):
275
        # Arrange
276
        artist = pylast.Artist("Test Artist", self.network)
277
        title = "Test Title"
278
        track = pylast.Track(artist, title, self.network)
279
        lastfm_user = self.network.get_user(self.username)
280
        track.love()
281
282
        # Act
283
        track.unlove()
284
285
        # Assert
286
        loved = lastfm_user.get_loved_tracks(limit=1)
287
        if len(loved):  # OK to be empty but if not:
288
            self.assertNotEqual(str(loved.track.artist), "Test Artist")
289
            self.assertNotEqual(str(loved.track.title), "Test Title")
290
291
    @handle_lastfm_exceptions
292
    def test_get_100_albums(self):
293
        # Arrange
294
        library = pylast.Library(user=self.username, network=self.network)
295
296
        # Act
297
        albums = library.get_albums(limit=100)
298
299
        # Assert
300
        self.assertGreaterEqual(len(albums), 0)
301
302
    @handle_lastfm_exceptions
303
    def test_get_limitless_albums(self):
304
        # Arrange
305
        library = pylast.Library(user=self.username, network=self.network)
306
307
        # Act
308
        albums = library.get_albums(limit=None)
309
310
        # Assert
311
        self.assertGreaterEqual(len(albums), 0)
312
313
    @handle_lastfm_exceptions
314
    def test_user_equals_none(self):
315
        # Arrange
316
        lastfm_user = self.network.get_user(self.username)
317
318
        # Act
319
        value = (lastfm_user is None)
320
321
        # Assert
322
        self.assertFalse(value)
323
324
    @handle_lastfm_exceptions
325
    def test_user_not_equal_to_none(self):
326
        # Arrange
327
        lastfm_user = self.network.get_user(self.username)
328
329
        # Act
330
        value = (lastfm_user is not None)
331
332
        # Assert
333
        self.assertTrue(value)
334
335
    @handle_lastfm_exceptions
336
    def test_now_playing_user_with_no_scrobbles(self):
337
        # Arrange
338
        # Currently test-account has no scrobbles:
339
        user = self.network.get_user('test-account')
340
341
        # Act
342
        current_track = user.get_now_playing()
343
344
        # Assert
345
        self.assertIsNone(current_track)
346
347
    @handle_lastfm_exceptions
348
    def test_love_limits(self):
349
        # Arrange
350
        # Currently test-account has at least 23 loved tracks:
351
        user = self.network.get_user("test-user")
352
353
        # Act/Assert
354
        self.assertEqual(len(user.get_loved_tracks(limit=20)), 20)
355
        self.assertLessEqual(len(user.get_loved_tracks(limit=100)), 100)
356
        self.assertGreaterEqual(len(user.get_loved_tracks(limit=None)), 23)
357
        self.assertGreaterEqual(len(user.get_loved_tracks(limit=0)), 23)
358
359
    @handle_lastfm_exceptions
360
    def test_update_now_playing(self):
361
        # Arrange
362
        artist = "Test Artist"
363
        title = "Test Title"
364
        album = "Test Album"
365
        track_number = 1
366
        lastfm_user = self.network.get_user(self.username)
367
368
        # Act
369
        self.network.update_now_playing(
370
            artist=artist, title=title, album=album, track_number=track_number)
371
372
        # Assert
373
        current_track = lastfm_user.get_now_playing()
374
        self.assertIsNotNone(current_track)
375
        self.assertEqual(str(current_track.title), "Test Title")
376
        self.assertEqual(str(current_track.artist), "Test Artist")
377
378
    @handle_lastfm_exceptions
379
    def test_album_tags_are_topitems(self):
380
        # Arrange
381
        albums = self.network.get_user('RJ').get_top_albums()
382
383
        # Act
384
        tags = albums[0].item.get_top_tags(limit=1)
385
386
        # Assert
387
        self.assertGreater(len(tags), 0)
388
        self.assertIsInstance(tags[0], pylast.TopItem)
389
390
    def helper_is_thing_hashable(self, thing):
391
        # Arrange
392
        things = set()
393
394
        # Act
395
        things.add(thing)
396
397
        # Assert
398
        self.assertIsNotNone(thing)
399
        self.assertEqual(len(things), 1)
400
401
    @handle_lastfm_exceptions
402
    def test_album_is_hashable(self):
403
        # Arrange
404
        album = self.network.get_album("Test Artist", "Test Album")
405
406
        # Act/Assert
407
        self.helper_is_thing_hashable(album)
408
409
    @handle_lastfm_exceptions
410
    def test_artist_is_hashable(self):
411
        # Arrange
412
        test_artist = self.network.get_artist("Test Artist")
413
        artist = test_artist.get_similar(limit=2)[0].item
414
        self.assertIsInstance(artist, pylast.Artist)
415
416
        # Act/Assert
417
        self.helper_is_thing_hashable(artist)
418
419
    @handle_lastfm_exceptions
420
    def test_country_is_hashable(self):
421
        # Arrange
422
        country = self.network.get_country("Italy")
423
424
        # Act/Assert
425
        self.helper_is_thing_hashable(country)
426
427
    @handle_lastfm_exceptions
428
    def test_metro_is_hashable(self):
429
        # Arrange
430
        metro = self.network.get_metro("Helsinki", "Finland")
431
432
        # Act/Assert
433
        self.helper_is_thing_hashable(metro)
434
435
    @handle_lastfm_exceptions
436
    def test_event_is_hashable(self):
437
        # Arrange
438
        user = self.network.get_user("RJ")
439
        event = user.get_past_events(limit=1)[0]
440
441
        # Act/Assert
442
        self.helper_is_thing_hashable(event)
443
444
    @handle_lastfm_exceptions
445
    def test_group_is_hashable(self):
446
        # Arrange
447
        group = self.network.get_group("Audioscrobbler Beta")
448
449
        # Act/Assert
450
        self.helper_is_thing_hashable(group)
451
452
    @handle_lastfm_exceptions
453
    def test_library_is_hashable(self):
454
        # Arrange
455
        library = pylast.Library(user=self.username, network=self.network)
456
457
        # Act/Assert
458
        self.helper_is_thing_hashable(library)
459
460
    @handle_lastfm_exceptions
461
    def test_playlist_is_hashable(self):
462
        # Arrange
463
        playlist = pylast.Playlist(
464
            user="RJ", playlist_id="1k1qp_doglist", network=self.network)
465
466
        # Act/Assert
467
        self.helper_is_thing_hashable(playlist)
468
469
    @handle_lastfm_exceptions
470
    def test_tag_is_hashable(self):
471
        # Arrange
472
        tag = self.network.get_top_tags(limit=1)[0]
473
474
        # Act/Assert
475
        self.helper_is_thing_hashable(tag)
476
477
    @handle_lastfm_exceptions
478
    def test_track_is_hashable(self):
479
        # Arrange
480
        artist = self.network.get_artist("Test Artist")
481
        track = artist.get_top_tracks()[0].item
482
        self.assertIsInstance(track, pylast.Track)
483
484
        # Act/Assert
485
        self.helper_is_thing_hashable(track)
486
487
    @handle_lastfm_exceptions
488
    def test_user_is_hashable(self):
489
        # Arrange
490
        artist = self.network.get_artist("Test Artist")
491
        user = artist.get_top_fans(limit=1)[0].item
492
        self.assertIsInstance(user, pylast.User)
493
494
        # Act/Assert
495
        self.helper_is_thing_hashable(user)
496
497
    @handle_lastfm_exceptions
498
    def test_venue_is_hashable(self):
499
        # Arrange
500
        venue_id = "8778225"  # Last.fm office
501
        venue = pylast.Venue(venue_id, self.network)
502
503
        # Act/Assert
504
        self.helper_is_thing_hashable(venue)
505
506
    @handle_lastfm_exceptions
507
    def test_xspf_is_hashable(self):
508
        # Arrange
509
        xspf = pylast.XSPF(
510
            uri="lastfm://playlist/1k1qp_doglist", network=self.network)
511
512
        # Act/Assert
513
        self.helper_is_thing_hashable(xspf)
514
515
    @handle_lastfm_exceptions
516
    def test_invalid_xml(self):
517
        # Arrange
518
        # Currently causes PCDATA invalid Char value 25
519
        artist = "Blind Willie Johnson"
520
        title = "It's nobody's fault but mine"
521
522
        # Act
523
        search = self.network.search_for_track(artist, title)
524
        total = search.get_total_result_count()
525
526
        # Assert
527
        self.skip_if_lastfm_api_broken(total)
528
        self.assertGreaterEqual(int(total), 0)
529
530
    @handle_lastfm_exceptions
531
    def test_user_play_count_in_track_info(self):
532
        # Arrange
533
        artist = "Test Artist"
534
        title = "Test Title"
535
        track = pylast.Track(
536
            artist=artist, title=title,
537
            network=self.network, username=self.username)
538
539
        # Act
540
        count = track.get_userplaycount()
541
542
        # Assert
543
        self.assertGreaterEqual(count, 0)
544
545
    @handle_lastfm_exceptions
546
    def test_user_loved_in_track_info(self):
547
        # Arrange
548
        artist = "Test Artist"
549
        title = "Test Title"
550
        track = pylast.Track(
551
            artist=artist, title=title,
552
            network=self.network, username=self.username)
553
554
        # Act
555
        loved = track.get_userloved()
556
557
        # Assert
558
        self.assertIsNotNone(loved)
559
        self.assertIsInstance(loved, bool)
560
        self.assertNotIsInstance(loved, str)
561
562
    @handle_lastfm_exceptions
563
    def test_album_in_recent_tracks(self):
564
        # Arrange
565
        lastfm_user = self.network.get_user(self.username)
566
567
        # Act
568
        # limit=2 to ignore now-playing:
569
        track = lastfm_user.get_recent_tracks(limit=2)[0]
570
571
        # Assert
572
        self.assertTrue(hasattr(track, 'album'))
573
574
    @handle_lastfm_exceptions
575
    def test_album_in_artist_tracks(self):
576
        # Arrange
577
        lastfm_user = self.network.get_user(self.username)
578
579
        # Act
580
        track = lastfm_user.get_artist_tracks(artist="Test Artist")[0]
581
582
        # Assert
583
        self.assertTrue(hasattr(track, 'album'))
584
585
    @handle_lastfm_exceptions
586
    def test_enable_rate_limiting(self):
587
        # Arrange
588
        self.assertFalse(self.network.is_rate_limited())
589
590
        # Act
591
        self.network.enable_rate_limit()
592
        then = time.time()
593
        # Make some network call, limit not applied first time
594
        self.network.get_user(self.username)
595
        # Make a second network call, limiting should be applied
596
        self.network.get_top_artists()
597
        now = time.time()
598
599
        # Assert
600
        self.assertTrue(self.network.is_rate_limited())
601
        self.assertGreaterEqual(now - then, 0.2)
602
603
    @handle_lastfm_exceptions
604
    def test_disable_rate_limiting(self):
605
        # Arrange
606
        self.network.enable_rate_limit()
607
        self.assertTrue(self.network.is_rate_limited())
608
609
        # Act
610
        self.network.disable_rate_limit()
611
        # Make some network call, limit not applied first time
612
        self.network.get_user(self.username)
613
        # Make a second network call, limiting should be applied
614
        self.network.get_top_artists()
615
616
        # Assert
617
        self.assertFalse(self.network.is_rate_limited())
618
619
    # Commented out because (a) it'll take a long time and (b) it strangely
620
    # fails due Last.fm's complaining of hitting the rate limit, even when
621
    # limited to one call per second. The ToS allows 5 calls per second.
622
    # def test_get_all_scrobbles(self):
623
        # # Arrange
624
        # lastfm_user = self.network.get_user("RJ")
625
        # self.network.enable_rate_limit() # this is going to be slow...
626
627
        # # Act
628
        # tracks = lastfm_user.get_recent_tracks(limit=None)
629
630
        # # Assert
631
        # self.assertGreaterEqual(len(tracks), 0)
632
633
    def helper_past_events_have_valid_ids(self, thing):
634
        # Act
635
        events = thing.get_past_events()
636
637
        # Assert
638
        self.helper_assert_events_have_valid_ids(events)
639
640
    def helper_upcoming_events_have_valid_ids(self, thing):
641
        # Act
642
        events = thing.get_upcoming_events()
643
644
        # Assert
645
        self.helper_assert_events_have_valid_ids(events)
646
647
    def helper_assert_events_have_valid_ids(self, events):
648
        # Assert
649
        # If fails, add past/future event for user/Test Artist:
650
        self.assertGreaterEqual(len(events), 1)
651
        for event in events[:2]:  # checking first two should be enough
652
            self.assertIsInstance(event.get_headliner(), pylast.Artist)
653
654
    @handle_lastfm_exceptions
655
    def test_artist_upcoming_events_returns_valid_ids(self):
656
        # Arrange
657
        artist = pylast.Artist("Test Artist", self.network)
658
659
        # Act/Assert
660
        self.helper_upcoming_events_have_valid_ids(artist)
661
662
    @handle_lastfm_exceptions
663
    def test_user_past_events_returns_valid_ids(self):
664
        # Arrange
665
        lastfm_user = self.network.get_user(self.username)
666
667
        # Act/Assert
668
        self.helper_past_events_have_valid_ids(lastfm_user)
669
670
    @handle_lastfm_exceptions
671
    def test_user_recommended_events_returns_valid_ids(self):
672
        # Arrange
673
        lastfm_user = self.network.get_user(self.username)
674
675
        # Act
676
        events = lastfm_user.get_upcoming_events()
677
678
        # Assert
679
        self.helper_assert_events_have_valid_ids(events)
680
681
    @handle_lastfm_exceptions
682
    def test_user_upcoming_events_returns_valid_ids(self):
683
        # Arrange
684
        lastfm_user = self.network.get_user(self.username)
685
686
        # Act/Assert
687
        self.helper_upcoming_events_have_valid_ids(lastfm_user)
688
689
    @handle_lastfm_exceptions
690
    def test_venue_past_events_returns_valid_ids(self):
691
        # Arrange
692
        venue_id = "8778225"  # Last.fm office
693
        venue = pylast.Venue(venue_id, self.network)
694
695
        # Act/Assert
696
        self.helper_past_events_have_valid_ids(venue)
697
698
    @handle_lastfm_exceptions
699
    def test_venue_upcoming_events_returns_valid_ids(self):
700
        # Arrange
701
        venue_id = "8778225"  # Last.fm office
702
        venue = pylast.Venue(venue_id, self.network)
703
704
        # Act/Assert
705
        self.helper_upcoming_events_have_valid_ids(venue)
706
707
    @handle_lastfm_exceptions
708
    def test_pickle(self):
709
        # Arrange
710
        import pickle
711
        lastfm_user = self.network.get_user(self.username)
712
        filename = str(self.unix_timestamp()) + ".pkl"
713
714
        # Act
715
        with open(filename, "wb") as f:
716
            pickle.dump(lastfm_user, f)
717
        with open(filename, "rb") as f:
718
            loaded_user = pickle.load(f)
719
        os.remove(filename)
720
721
        # Assert
722
        self.assertEqual(lastfm_user, loaded_user)
723
724
    @handle_lastfm_exceptions
725
    def test_bio_published_date(self):
726
        # Arrange
727
        artist = pylast.Artist("Test Artist", self.network)
728
729
        # Act
730
        bio = artist.get_bio_published_date()
731
732
        # Assert
733
        self.assertIsNotNone(bio)
734
        self.assertGreaterEqual(len(bio), 1)
735
736
    @handle_lastfm_exceptions
737
    def test_bio_content(self):
738
        # Arrange
739
        artist = pylast.Artist("Test Artist", self.network)
740
741
        # Act
742
        bio = artist.get_bio_content(language="en")
743
744
        # Assert
745
        self.assertIsNotNone(bio)
746
        self.assertGreaterEqual(len(bio), 1)
747
748
    @handle_lastfm_exceptions
749
    def test_bio_summary(self):
750
        # Arrange
751
        artist = pylast.Artist("Test Artist", self.network)
752
753
        # Act
754
        bio = artist.get_bio_summary(language="en")
755
756
        # Assert
757
        self.assertIsNotNone(bio)
758
        self.assertGreaterEqual(len(bio), 1)
759
760
    @handle_lastfm_exceptions
761
    def test_album_wiki_content(self):
762
        # Arrange
763
        album = pylast.Album("Test Artist", "Test Album", self.network)
764
765
        # Act
766
        wiki = album.get_wiki_content()
767
768
        # Assert
769
        self.assertIsNotNone(wiki)
770
        self.assertGreaterEqual(len(wiki), 1)
771
772
    @handle_lastfm_exceptions
773
    def test_album_wiki_published_date(self):
774
        # Arrange
775
        album = pylast.Album("Test Artist", "Test Album", self.network)
776
777
        # Act
778
        wiki = album.get_wiki_published_date()
779
780
        # Assert
781
        self.assertIsNotNone(wiki)
782
        self.assertGreaterEqual(len(wiki), 1)
783
784
    @handle_lastfm_exceptions
785
    def test_album_wiki_summary(self):
786
        # Arrange
787
        album = pylast.Album("Test Artist", "Test Album", self.network)
788
789
        # Act
790
        wiki = album.get_wiki_summary()
791
792
        # Assert
793
        self.assertIsNotNone(wiki)
794
        self.assertGreaterEqual(len(wiki), 1)
795
796
    @handle_lastfm_exceptions
797
    def test_track_wiki_content(self):
798
        # Arrange
799
        track = pylast.Track("Test Artist", "Test Title", self.network)
800
801
        # Act
802
        wiki = track.get_wiki_content()
803
804
        # Assert
805
        self.assertIsNotNone(wiki)
806
        self.assertGreaterEqual(len(wiki), 1)
807
808
    @handle_lastfm_exceptions
809
    def test_track_wiki_summary(self):
810
        # Arrange
811
        track = pylast.Track("Test Artist", "Test Title", self.network)
812
813
        # Act
814
        wiki = track.get_wiki_summary()
815
816
        # Assert
817
        self.assertIsNotNone(wiki)
818
        self.assertGreaterEqual(len(wiki), 1)
819
820
    @handle_lastfm_exceptions
821
    def test_lastfm_network_name(self):
822
        # Act
823
        name = str(self.network)
824
825
        # Assert
826
        self.assertEqual(name, "Last.fm Network")
827
828
    def helper_validate_results(self, a, b, c):
829
        # Assert
830
        self.assertIsNotNone(a)
831
        self.assertIsNotNone(b)
832
        self.assertIsNotNone(c)
833
        self.assertGreaterEqual(len(a), 0)
834
        self.assertGreaterEqual(len(b), 0)
835
        self.assertGreaterEqual(len(c), 0)
836
        self.assertEqual(a, b)
837
        self.assertEqual(b, c)
838
839
    def helper_validate_cacheable(self, thing, function_name):
840
        # Arrange
841
        # get thing.function_name()
842
        func = getattr(thing, function_name, None)
843
844
        # Act
845
        result1 = func(limit=1, cacheable=False)
846
        result2 = func(limit=1, cacheable=True)
847
        result3 = func(limit=1)
848
849
        # Assert
850
        self.helper_validate_results(result1, result2, result3)
851
852
    @handle_lastfm_exceptions
853
    def test_cacheable_artist_get_shouts(self):
854
        # Arrange
855
        artist = self.network.get_artist("Test Artist")
856
857
        # Act/Assert
858
        self.helper_validate_cacheable(artist, "get_shouts")
859
860
    @handle_lastfm_exceptions
861
    def test_cacheable_event_get_shouts(self):
862
        # Arrange
863
        user = self.network.get_user("RJ")
864
        event = user.get_past_events(limit=1)[0]
865
866
        # Act/Assert
867
        self.helper_validate_cacheable(event, "get_shouts")
868
869
    @handle_lastfm_exceptions
870
    def test_cacheable_track_get_shouts(self):
871
        # Arrange
872
        track = self.network.get_top_tracks()[0].item
873
874
        # Act/Assert
875
        self.helper_validate_cacheable(track, "get_shouts")
876
877
    @handle_lastfm_exceptions
878
    def test_cacheable_group_get_members(self):
879
        # Arrange
880
        group = self.network.get_group("Audioscrobbler Beta")
881
882
        # Act/Assert
883
        self.helper_validate_cacheable(group, "get_members")
884
885
    @handle_lastfm_exceptions
886
    def test_cacheable_library(self):
887
        # Arrange
888
        library = pylast.Library(self.username, self.network)
889
890
        # Act/Assert
891
        self.helper_validate_cacheable(library, "get_albums")
892
        self.helper_validate_cacheable(library, "get_artists")
893
        self.helper_validate_cacheable(library, "get_tracks")
894
895
    @handle_lastfm_exceptions
896
    def test_cacheable_user_artist_tracks(self):
897
        # Arrange
898
        lastfm_user = self.network.get_authenticated_user()
899
900
        # Act
901
        result1 = lastfm_user.get_artist_tracks("Test Artist", cacheable=False)
902
        result2 = lastfm_user.get_artist_tracks("Test Artist", cacheable=True)
903
        result3 = lastfm_user.get_artist_tracks("Test Artist")
904
905
        # Assert
906
        self.helper_validate_results(result1, result2, result3)
907
908
    @handle_lastfm_exceptions
909
    def test_cacheable_user(self):
910
        # Arrange
911
        lastfm_user = self.network.get_authenticated_user()
912
913
        # Act/Assert
914
        # Skip the first one because Last.fm API is broken
915
        # self.helper_validate_cacheable(lastfm_user, "get_friends")
916
        self.helper_validate_cacheable(lastfm_user, "get_loved_tracks")
917
        self.helper_validate_cacheable(lastfm_user, "get_neighbours")
918
        self.helper_validate_cacheable(lastfm_user, "get_past_events")
919
        self.helper_validate_cacheable(lastfm_user, "get_recent_tracks")
920
        self.helper_validate_cacheable(lastfm_user, "get_recommended_artists")
921
        self.helper_validate_cacheable(lastfm_user, "get_recommended_events")
922
        self.helper_validate_cacheable(lastfm_user, "get_shouts")
923
924
    @handle_lastfm_exceptions
925
    def test_geo_get_events_in_location(self):
926
        # Arrange
927
        # Act
928
        events = self.network.get_geo_events(
929
            location="London", tag="blues", limit=1)
930
931
        # Assert
932
        self.assertEqual(len(events), 1)
933
        event = events[0]
934
        self.assertIsInstance(event, pylast.Event)
935
        self.assertIn(event.get_venue().location['city'],
936
                      ["London", "Camden"])
937
938
    @handle_lastfm_exceptions
939
    def test_geo_get_events_in_latlong(self):
940
        # Arrange
941
        # Act
942
        events = self.network.get_geo_events(
943
            latitude=53.466667, longitude=-2.233333, distance=5, limit=1)
944
945
        # Assert
946
        self.assertEqual(len(events), 1)
947
        event = events[0]
948
        self.assertIsInstance(event, pylast.Event)
949
        self.assertEqual(event.get_venue().location['city'], "Manchester")
950
951
    @handle_lastfm_exceptions
952
    def test_geo_get_events_festival(self):
953
        # Arrange
954
        # Act
955
        events = self.network.get_geo_events(
956
            location="Reading", festivalsonly=True, limit=1)
957
958
        # Assert
959
        self.assertEqual(len(events), 1)
960
        event = events[0]
961
        self.assertIsInstance(event, pylast.Event)
962
        self.assertEqual(event.get_venue().location['city'], "Reading")
963
964
    def helper_dates_valid(self, dates):
965
        # Assert
966
        self.assertGreaterEqual(len(dates), 1)
967
        self.assertIsInstance(dates[0], tuple)
968
        (start, end) = dates[0]
969
        self.assertLess(start, end)
970
971
    @handle_lastfm_exceptions
972
    def test_get_metro_weekly_chart_dates(self):
973
        # Arrange
974
        # Act
975
        dates = self.network.get_metro_weekly_chart_dates()
976
977
        # Assert
978
        self.helper_dates_valid(dates)
979
980
    def helper_geo_chart(self, function_name, expected_type=pylast.Artist):
981
        # Arrange
982
        metro = self.network.get_metro("Madrid", "Spain")
983
        dates = self.network.get_metro_weekly_chart_dates()
984
        (from_date, to_date) = dates[0]
985
986
        # get metro.function_name()
987
        func = getattr(metro, function_name, None)
988
989
        # Act
990
        chart = func(from_date=from_date, to_date=to_date, limit=1)
991
992
        # Assert
993
        self.assertEqual(len(chart), 1)
994
        self.assertIsInstance(chart[0], pylast.TopItem)
995
        self.assertIsInstance(chart[0].item, expected_type)
996
997
    @handle_lastfm_exceptions
998
    def test_get_metro_artist_chart(self):
999
        # Arrange/Act/Assert
1000
        self.helper_geo_chart("get_artist_chart")
1001
1002
    @handle_lastfm_exceptions
1003
    def test_get_metro_hype_artist_chart(self):
1004
        # Arrange/Act/Assert
1005
        self.helper_geo_chart("get_hype_artist_chart")
1006
1007
    @handle_lastfm_exceptions
1008
    def test_get_metro_unique_artist_chart(self):
1009
        # Arrange/Act/Assert
1010
        self.helper_geo_chart("get_unique_artist_chart")
1011
1012
    @handle_lastfm_exceptions
1013
    def test_get_metro_track_chart(self):
1014
        # Arrange/Act/Assert
1015
        self.helper_geo_chart("get_track_chart", expected_type=pylast.Track)
1016
1017
    @handle_lastfm_exceptions
1018
    def test_get_metro_hype_track_chart(self):
1019
        # Arrange/Act/Assert
1020
        self.helper_geo_chart(
1021
            "get_hype_track_chart", expected_type=pylast.Track)
1022
1023
    @handle_lastfm_exceptions
1024
    def test_get_metro_unique_track_chart(self):
1025
        # Arrange/Act/Assert
1026
        self.helper_geo_chart(
1027
            "get_unique_track_chart", expected_type=pylast.Track)
1028
1029
    @handle_lastfm_exceptions
1030
    def test_geo_get_metros(self):
1031
        # Arrange
1032
        # Act
1033
        metros = self.network.get_metros(country="Poland")
1034
1035
        # Assert
1036
        self.assertGreaterEqual(len(metros), 1)
1037
        self.assertIsInstance(metros[0], pylast.Metro)
1038
        self.assertEqual(metros[0].get_country(), "Poland")
1039
1040
    @handle_lastfm_exceptions
1041
    def test_geo_get_top_artists(self):
1042
        # Arrange
1043
        # Act
1044
        artists = self.network.get_geo_top_artists(
1045
            country="United Kingdom", limit=1)
1046
1047
        # Assert
1048
        self.assertEqual(len(artists), 1)
1049
        self.assertIsInstance(artists[0], pylast.TopItem)
1050
        self.assertIsInstance(artists[0].item, pylast.Artist)
1051
1052
    @handle_lastfm_exceptions
1053
    def test_geo_get_top_tracks(self):
1054
        # Arrange
1055
        # Act
1056
        tracks = self.network.get_geo_top_tracks(
1057
            country="United Kingdom", location="Manchester", limit=1)
1058
1059
        # Assert
1060
        self.assertEqual(len(tracks), 1)
1061
        self.assertIsInstance(tracks[0], pylast.TopItem)
1062
        self.assertIsInstance(tracks[0].item, pylast.Track)
1063
1064
    @handle_lastfm_exceptions
1065
    def test_metro_class(self):
1066
        # Arrange
1067
        # Act
1068
        metro = self.network.get_metro("Bergen", "Norway")
1069
1070
        # Assert
1071
        self.assertEqual(metro.get_name(), "Bergen")
1072
        self.assertEqual(metro.get_country(), "Norway")
1073
        self.assertEqual(str(metro), "Bergen, Norway")
1074
        self.assertEqual(metro, pylast.Metro("Bergen", "Norway", self.network))
1075
        self.assertNotEqual(
1076
            metro,
1077
            pylast.Metro("Wellington", "New Zealand", self.network))
1078
1079
    @handle_lastfm_exceptions
1080
    def test_get_album_play_links(self):
1081
        # Arrange
1082
        album1 = self.network.get_album("Portishead", "Dummy")
1083
        album2 = self.network.get_album("Radiohead", "OK Computer")
1084
        albums = [album1, album2]
1085
1086
        # Act
1087
        links = self.network.get_album_play_links(albums)
1088
1089
        # Assert
1090
        self.assertIsInstance(links, list)
1091
        self.assertEqual(len(links), 2)
1092
        self.assertIn("spotify:album:", links[0])
1093
        self.assertIn("spotify:album:", links[1])
1094
1095
    @handle_lastfm_exceptions
1096
    def test_get_artist_play_links(self):
1097
        # Arrange
1098
        artists = ["Portishead", "Radiohead"]
1099
        # Act
1100
        links = self.network.get_artist_play_links(artists)
1101
1102
        # Assert
1103
        self.assertIsInstance(links, list)
1104
        self.assertEqual(len(links), 2)
1105
        self.assertIn("spotify:artist:", links[0])
1106
        self.assertIn("spotify:artist:", links[1])
1107
1108
    @handle_lastfm_exceptions
1109
    def test_get_track_play_links(self):
1110
        # Arrange
1111
        track1 = self.network.get_track(artist="Portishead", title="Mysterons")
1112
        track2 = self.network.get_track(artist="Radiohead", title="Creep")
1113
        tracks = [track1, track2]
1114
1115
        # Act
1116
        links = self.network.get_track_play_links(tracks)
1117
1118
        # Assert
1119
        self.assertIsInstance(links, list)
1120
        self.assertEqual(len(links), 2)
1121
        self.assertIn("spotify:track:", links[0])
1122
        self.assertIn("spotify:track:", links[1])
1123
1124
    def helper_at_least_one_thing_in_top_list(self, things, expected_type):
1125
        # Assert
1126
        self.assertGreater(len(things), 1)
1127
        self.assertIsInstance(things, list)
1128
        self.assertIsInstance(things[0], pylast.TopItem)
1129
        self.assertIsInstance(things[0].item, expected_type)
1130
1131
    def helper_only_one_thing_in_top_list(self, things, expected_type):
1132
        # Assert
1133
        self.assertEqual(len(things), 1)
1134
        self.assertIsInstance(things, list)
1135
        self.assertIsInstance(things[0], pylast.TopItem)
1136
        self.assertIsInstance(things[0].item, expected_type)
1137
1138
    def helper_only_one_thing_in_list(self, things, expected_type):
1139
        # Assert
1140
        self.assertEqual(len(things), 1)
1141
        self.assertIsInstance(things, list)
1142
        self.assertIsInstance(things[0], expected_type)
1143
1144
    def helper_two_different_things_in_top_list(self, things, expected_type):
1145
        # Assert
1146
        self.assertEqual(len(things), 2)
1147
        thing1 = things[0]
1148
        thing2 = things[1]
1149
        self.assertIsInstance(thing1, pylast.TopItem)
1150
        self.assertIsInstance(thing2, pylast.TopItem)
1151
        self.assertIsInstance(thing1.item, expected_type)
1152
        self.assertIsInstance(thing2.item, expected_type)
1153
        self.assertNotEqual(thing1, thing2)
1154
1155
    def helper_two_things_in_list(self, things, expected_type):
1156
        # Assert
1157
        self.assertEqual(len(things), 2)
1158
        self.assertIsInstance(things, list)
1159
        thing1 = things[0]
1160
        thing2 = things[1]
1161
        self.assertIsInstance(thing1, expected_type)
1162
        self.assertIsInstance(thing2, expected_type)
1163
1164
    @handle_lastfm_exceptions
1165
    def test_user_get_top_tags_with_limit(self):
1166
        # Arrange
1167
        user = self.network.get_user("RJ")
1168
1169
        # Act
1170
        tags = user.get_top_tags(limit=1)
1171
1172
        # Assert
1173
        self.skip_if_lastfm_api_broken(tags)
1174
        self.helper_only_one_thing_in_top_list(tags, pylast.Tag)
1175
1176
    @handle_lastfm_exceptions
1177
    def test_network_get_top_artists_with_limit(self):
1178
        # Arrange
1179
        # Act
1180
        artists = self.network.get_top_artists(limit=1)
1181
1182
        # Assert
1183
        self.helper_only_one_thing_in_top_list(artists, pylast.Artist)
1184
1185
    @handle_lastfm_exceptions
1186
    def test_network_get_top_tags_with_limit(self):
1187
        # Arrange
1188
        # Act
1189
        tags = self.network.get_top_tags(limit=1)
1190
1191
        # Assert
1192
        self.helper_only_one_thing_in_top_list(tags, pylast.Tag)
1193
1194
    @handle_lastfm_exceptions
1195
    def test_network_get_top_tags_with_no_limit(self):
1196
        # Arrange
1197
        # Act
1198
        tags = self.network.get_top_tags()
1199
1200
        # Assert
1201
        self.helper_at_least_one_thing_in_top_list(tags, pylast.Tag)
1202
1203
    @handle_lastfm_exceptions
1204
    def test_network_get_top_tracks_with_limit(self):
1205
        # Arrange
1206
        # Act
1207
        tracks = self.network.get_top_tracks(limit=1)
1208
1209
        # Assert
1210
        self.helper_only_one_thing_in_top_list(tracks, pylast.Track)
1211
1212
    @handle_lastfm_exceptions
1213
    def test_artist_top_tracks(self):
1214
        # Arrange
1215
        # Pick an artist with plenty of plays
1216
        artist = self.network.get_top_artists(limit=1)[0].item
1217
1218
        # Act
1219
        things = artist.get_top_tracks(limit=2)
1220
1221
        # Assert
1222
        self.helper_two_different_things_in_top_list(things, pylast.Track)
1223
1224
    @handle_lastfm_exceptions
1225
    def test_artist_top_albums(self):
1226
        # Arrange
1227
        # Pick an artist with plenty of plays
1228
        artist = self.network.get_top_artists(limit=1)[0].item
1229
1230
        # Act
1231
        things = artist.get_top_albums(limit=2)
1232
1233
        # Assert
1234
        self.helper_two_different_things_in_top_list(things, pylast.Album)
1235
1236
    @handle_lastfm_exceptions
1237
    def test_artist_top_fans(self):
1238
        # Arrange
1239
        # Pick an artist with plenty of plays
1240
        artist = self.network.get_top_artists(limit=1)[0].item
1241
1242
        # Act
1243
        things = artist.get_top_fans(limit=2)
1244
1245
        # Assert
1246
        self.helper_two_different_things_in_top_list(things, pylast.User)
1247
1248
    @handle_lastfm_exceptions
1249
    def test_country_top_tracks(self):
1250
        # Arrange
1251
        country = self.network.get_country("Croatia")
1252
1253
        # Act
1254
        things = country.get_top_tracks(limit=2)
1255
1256
        # Assert
1257
        self.helper_two_different_things_in_top_list(things, pylast.Track)
1258
1259
    @handle_lastfm_exceptions
1260
    def test_country_network_top_tracks(self):
1261
        # Arrange
1262
        # Act
1263
        things = self.network.get_geo_top_tracks("Croatia", limit=2)
1264
1265
        # Assert
1266
        self.helper_two_different_things_in_top_list(things, pylast.Track)
1267
1268
    @handle_lastfm_exceptions
1269
    def test_tag_top_tracks(self):
1270
        # Arrange
1271
        tag = self.network.get_tag("blues")
1272
1273
        # Act
1274
        things = tag.get_top_tracks(limit=2)
1275
1276
        # Assert
1277
        self.helper_two_different_things_in_top_list(things, pylast.Track)
1278
1279
    @handle_lastfm_exceptions
1280
    def test_user_top_tracks(self):
1281
        # Arrange
1282
        lastfm_user = self.network.get_user(self.username)
1283
1284
        # Act
1285
        things = lastfm_user.get_top_tracks(limit=2)
1286
1287
        # Assert
1288
        self.helper_two_different_things_in_top_list(things, pylast.Track)
1289
1290
    def helper_assert_chart(self, chart, expected_type):
1291
        # Assert
1292
        self.assertIsNotNone(chart)
1293
        self.assertGreater(len(chart), 0)
1294
        self.assertIsInstance(chart[0], pylast.TopItem)
1295
        self.assertIsInstance(chart[0].item, expected_type)
1296
1297
    def helper_get_assert_charts(self, thing, date):
1298
        # Arrange
1299
        (from_date, to_date) = date
1300
1301
        # Act
1302
        artist_chart = thing.get_weekly_artist_charts(from_date, to_date)
1303
        if type(thing) is not pylast.Tag:
1304
            album_chart = thing.get_weekly_album_charts(from_date, to_date)
1305
            track_chart = thing.get_weekly_track_charts(from_date, to_date)
1306
1307
        # Assert
1308
        self.helper_assert_chart(artist_chart, pylast.Artist)
1309
        if type(thing) is not pylast.Tag:
1310
            self.helper_assert_chart(album_chart, pylast.Album)
1311
            self.helper_assert_chart(track_chart, pylast.Track)
1312
1313
    @handle_lastfm_exceptions
1314
    def test_group_charts(self):
1315
        # Arrange
1316
        group = self.network.get_group("mnml")
1317
        dates = group.get_weekly_chart_dates()
1318
        self.helper_dates_valid(dates)
1319
1320
        # Act/Assert
1321
        self.helper_get_assert_charts(group, dates[-2])
1322
1323
    @handle_lastfm_exceptions
1324
    def test_tag_charts(self):
1325
        # Arrange
1326
        tag = self.network.get_tag("rock")
1327
        dates = tag.get_weekly_chart_dates()
1328
        self.helper_dates_valid(dates)
1329
1330
        # Act/Assert
1331
        self.helper_get_assert_charts(tag, dates[-2])
1332
1333
    @handle_lastfm_exceptions
1334
    def test_user_charts(self):
1335
        # Arrange
1336
        lastfm_user = self.network.get_user("RJ")
1337
        dates = lastfm_user.get_weekly_chart_dates()
1338
        self.helper_dates_valid(dates)
1339
1340
        # Act/Assert
1341
        self.helper_get_assert_charts(lastfm_user, dates[0])
1342
1343
    @handle_lastfm_exceptions
1344
    def test_track_top_fans(self):
1345
        # Arrange
1346
        track = self.network.get_track("The Cinematic Orchestra", "Postlude")
1347
1348
        # Act
1349
        fans = track.get_top_fans()
1350
1351
        # Assert
1352
        self.helper_at_least_one_thing_in_top_list(fans, pylast.User)
1353
1354
    # Commented out to avoid spamming
1355
    # def test_share_spam(self):
1356
        # # Arrange
1357
        # users_to_spam = [TODO_ENTER_SPAMEES_HERE]
1358
        # spam_message = "Dig the krazee sound!"
1359
        # artist = self.network.get_top_artists(limit=1)[0].item
1360
        # track = artist.get_top_tracks(limit=1)[0].item
1361
        # event = artist.get_upcoming_events()[0]
1362
1363
        # # Act
1364
        # artist.share(users_to_spam, spam_message)
1365
        # track.share(users_to_spam, spam_message)
1366
        # event.share(users_to_spam, spam_message)
1367
1368
        # Assert
1369
        # Check inbox for spam!
1370
1371
        # album/artist/event/track/user
1372
1373
    @handle_lastfm_exceptions
1374
    def test_album_shouts(self):
1375
        # Arrange
1376
        # Pick an artist with plenty of plays
1377
        artist = self.network.get_top_artists(limit=1)[0].item
1378
        album = artist.get_top_albums(limit=1)[0].item
1379
1380
        # Act
1381
        shouts = album.get_shouts(limit=2)
1382
1383
        # Assert
1384
        self.helper_two_things_in_list(shouts, pylast.Shout)
1385
1386
    @handle_lastfm_exceptions
1387
    def test_artist_shouts(self):
1388
        # Arrange
1389
        # Pick an artist with plenty of plays
1390
        artist = self.network.get_top_artists(limit=1)[0].item
1391
1392
        # Act
1393
        shouts = artist.get_shouts(limit=2)
1394
1395
        # Assert
1396
        self.helper_two_things_in_list(shouts, pylast.Shout)
1397
1398
    @handle_lastfm_exceptions
1399
    def test_event_shouts(self):
1400
        # Arrange
1401
        event_id = 3478520  # Glasto 2014
1402
        event = pylast.Event(event_id, self.network)
1403
1404
        # Act
1405
        shouts = event.get_shouts(limit=2)
1406
1407
        # Assert
1408
        self.helper_two_things_in_list(shouts, pylast.Shout)
1409
1410
    @handle_lastfm_exceptions
1411
    def test_track_shouts(self):
1412
        # Arrange
1413
        track = self.network.get_track("The Cinematic Orchestra", "Postlude")
1414
1415
        # Act
1416
        shouts = track.get_shouts(limit=2)
1417
1418
        # Assert
1419
        self.helper_two_things_in_list(shouts, pylast.Shout)
1420
1421
    @handle_lastfm_exceptions
1422
    def test_user_shouts(self):
1423
        # Arrange
1424
        user = self.network.get_user("RJ")
1425
1426
        # Act
1427
        shouts = user.get_shouts(limit=2)
1428
1429
        # Assert
1430
        self.helper_two_things_in_list(shouts, pylast.Shout)
1431
1432 View Code Duplication
    @handle_lastfm_exceptions
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1433
    def test_album_data(self):
1434
        # Arrange
1435
        thing = self.network.get_album("Test Artist", "Test Album")
1436
1437
        # Act
1438
        stringed = str(thing)
1439
        repr = thing.__repr__()
1440
        title = thing.get_title()
1441
        name = thing.get_name()
1442
        playcount = thing.get_playcount()
1443
        url = thing.get_url()
1444
1445
        # Assert
1446
        self.assertEqual(stringed, "Test Artist - Test Album")
1447
        self.assertIn("pylast.Album('Test Artist', 'Test Album',", repr)
1448
        self.assertEqual(title, name)
1449
        self.assertIsInstance(playcount, int)
1450
        self.assertGreater(playcount, 1)
1451
        self.assertEqual(
1452
            "http://www.last.fm/music/test%2bartist/test%2balbum", url)
1453
1454 View Code Duplication
    @handle_lastfm_exceptions
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1455
    def test_track_data(self):
1456
        # Arrange
1457
        thing = self.network.get_track("Test Artist", "Test Title")
1458
1459
        # Act
1460
        stringed = str(thing)
1461
        repr = thing.__repr__()
1462
        title = thing.get_title()
1463
        name = thing.get_name()
1464
        playcount = thing.get_playcount()
1465
        url = thing.get_url(pylast.DOMAIN_FRENCH)
1466
1467
        # Assert
1468
        self.assertEqual(stringed, "Test Artist - Test Title")
1469
        self.assertIn("pylast.Track('Test Artist', 'Test Title',", repr)
1470
        self.assertEqual(title, "Test Title")
1471
        self.assertEqual(title, name)
1472
        self.assertIsInstance(playcount, int)
1473
        self.assertGreater(playcount, 1)
1474
        self.assertEqual(
1475
            "http://www.lastfm.fr/music/test%2bartist/_/test%2btitle", url)
1476
1477
    @handle_lastfm_exceptions
1478
    def test_tag_top_artists(self):
1479
        # Arrange
1480
        tag = self.network.get_tag("blues")
1481
1482
        # Act
1483
        artists = tag.get_top_artists(limit=1)
1484
1485
        # Assert
1486
        self.helper_only_one_thing_in_top_list(artists, pylast.Artist)
1487
1488
    @handle_lastfm_exceptions
1489
    def test_country_top_artists(self):
1490
        # Arrange
1491
        country = self.network.get_country("Ukraine")
1492
1493
        # Act
1494
        artists = country.get_top_artists(limit=1)
1495
1496
        # Assert
1497
        self.helper_only_one_thing_in_top_list(artists, pylast.Artist)
1498
1499
    @handle_lastfm_exceptions
1500
    def test_user_top_artists(self):
1501
        # Arrange
1502
        lastfm_user = self.network.get_user(self.username)
1503
1504
        # Act
1505
        artists = lastfm_user.get_top_artists(limit=1)
1506
1507
        # Assert
1508
        self.helper_only_one_thing_in_top_list(artists, pylast.Artist)
1509
1510
    @handle_lastfm_exceptions
1511
    def test_tag_top_albums(self):
1512
        # Arrange
1513
        tag = self.network.get_tag("blues")
1514
1515
        # Act
1516
        albums = tag.get_top_albums(limit=1)
1517
1518
        # Assert
1519
        self.helper_only_one_thing_in_top_list(albums, pylast.Album)
1520
1521
    @handle_lastfm_exceptions
1522
    def test_user_top_albums(self):
1523
        # Arrange
1524
        user = self.network.get_user("RJ")
1525
1526
        # Act
1527
        albums = user.get_top_albums(limit=1)
1528
1529
        # Assert
1530
        self.helper_only_one_thing_in_top_list(albums, pylast.Album)
1531
1532
    @handle_lastfm_exceptions
1533
    def test_user_tagged_artists(self):
1534
        # Arrange
1535
        lastfm_user = self.network.get_user(self.username)
1536
        tags = ["artisttagola"]
1537
        artist = self.network.get_artist("Test Artist")
1538
        artist.add_tags(tags)
1539
1540
        # Act
1541
        artists = lastfm_user.get_tagged_artists('artisttagola', limit=1)
1542
1543
        # Assert
1544
        self.helper_only_one_thing_in_list(artists, pylast.Artist)
1545
1546
    @handle_lastfm_exceptions
1547
    def test_user_tagged_albums(self):
1548
        # Arrange
1549
        lastfm_user = self.network.get_user(self.username)
1550
        tags = ["albumtagola"]
1551
        album = self.network.get_album("Test Artist", "Test Album")
1552
        album.add_tags(tags)
1553
1554
        # Act
1555
        albums = lastfm_user.get_tagged_albums('albumtagola', limit=1)
1556
1557
        # Assert
1558
        self.helper_only_one_thing_in_list(albums, pylast.Album)
1559
1560
    @handle_lastfm_exceptions
1561
    def test_user_tagged_tracks(self):
1562
        # Arrange
1563
        lastfm_user = self.network.get_user(self.username)
1564
        tags = ["tracktagola"]
1565
        track = self.network.get_track("Test Artist", "Test Title")
1566
        track.add_tags(tags)
1567
        # Act
1568
        tracks = lastfm_user.get_tagged_tracks('tracktagola', limit=1)
1569
1570
        # Assert
1571
        self.helper_only_one_thing_in_list(tracks, pylast.Track)
1572
1573
    @handle_lastfm_exceptions
1574
    def test_caching(self):
1575
        # Arrange
1576
        user = self.network.get_user("RJ")
1577
1578
        # Act
1579
        self.network.enable_caching()
1580
        shouts1 = user.get_shouts(limit=1, cacheable=True)
1581
        shouts2 = user.get_shouts(limit=1, cacheable=True)
1582
1583
        # Assert
1584
        self.assertTrue(self.network.is_caching_enabled())
1585
        self.assertEqual(shouts1, shouts2)
1586
        self.network.disable_caching()
1587
        self.assertFalse(self.network.is_caching_enabled())
1588
1589
    @handle_lastfm_exceptions
1590
    def test_create_playlist(self):
1591
        # Arrange
1592
        title = "Test playlist"
1593
        description = "Testing"
1594
        lastfm_user = self.network.get_user(self.username)
1595
1596
        # Act
1597
        playlist = self.network.create_new_playlist(title, description)
1598
1599
        # Assert
1600
        self.assertIsInstance(playlist, pylast.Playlist)
1601
        self.assertEqual(playlist.get_title(), "Test playlist")
1602
        self.assertEqual(playlist.get_description(), "Testing")
1603
        self.assertEqual(playlist.get_user(), lastfm_user)
1604
1605
    @handle_lastfm_exceptions
1606
    def test_empty_playlist_unstreamable(self):
1607
        # Arrange
1608
        title = "Empty playlist"
1609
        description = "Unstreamable"
1610
1611
        # Act
1612
        playlist = self.network.create_new_playlist(title, description)
1613
1614
        # Assert
1615
        self.assertEqual(playlist.get_size(), 0)
1616
        self.assertEqual(playlist.get_duration(), 0)
1617
        self.assertFalse(playlist.is_streamable())
1618
1619
    @handle_lastfm_exceptions
1620
    def test_big_playlist_is_streamable(self):
1621
        # Arrange
1622
        # Find a big playlist on Last.fm, eg "top 100 classick rock songs"
1623
        user = "kaxior"
1624
        id = 10417943
1625
        playlist = pylast.Playlist(user, id, self.network)
1626
        self.assertEqual(
1627
            playlist.get_url(),
1628
            "http://www.last.fm/user/kaxior/library/"
1629
            "playlists/67ajb_top_100_classick_rock_songs")
1630
1631
        # Act
1632
        # Nothing
1633
1634
        # Assert
1635
        self.assertIsInstance(playlist, pylast.Playlist)
1636
        self.assertGreaterEqual(playlist.get_size(), 45)
1637
        self.assertGreater(playlist.get_duration(), 0)
1638
        self.assertTrue(playlist.is_streamable())
1639
1640
    @handle_lastfm_exceptions
1641
    def test_add_track_to_playlist(self):
1642
        # Arrange
1643
        title = "One track playlist"
1644
        description = "Testing"
1645
        playlist = self.network.create_new_playlist(title, description)
1646
        track = pylast.Track("Test Artist", "Test Title", self.network)
1647
1648
        # Act
1649
        playlist.add_track(track)
1650
1651
        # Assert
1652
        self.assertEqual(playlist.get_size(), 1)
1653
        self.assertEqual(len(playlist.get_tracks()), 1)
1654
        self.assertTrue(playlist.has_track(track))
1655
1656
    @handle_lastfm_exceptions
1657
    def test_album_mbid(self):
1658
        # Arrange
1659
        mbid = "a6a265bf-9f81-4055-8224-f7ac0aa6b937"
1660
1661
        # Act
1662
        album = self.network.get_album_by_mbid(mbid)
1663
        album_mbid = album.get_mbid()
1664
1665
        # Assert
1666
        self.assertIsInstance(album, pylast.Album)
1667
        self.assertEqual(album.title.lower(), "test")
1668
        self.assertEqual(album_mbid, mbid)
1669
1670
    @handle_lastfm_exceptions
1671
    def test_artist_mbid(self):
1672
        # Arrange
1673
        mbid = "7e84f845-ac16-41fe-9ff8-df12eb32af55"
1674
1675
        # Act
1676
        artist = self.network.get_artist_by_mbid(mbid)
1677
1678
        # Assert
1679
        self.assertIsInstance(artist, pylast.Artist)
1680
        self.assertEqual(artist.name, "MusicBrainz Test Artist")
1681
1682
    @handle_lastfm_exceptions
1683
    def test_track_mbid(self):
1684
        # Arrange
1685
        mbid = "ebc037b1-cc9c-44f2-a21f-83c219f0e1e0"
1686
1687
        # Act
1688
        track = self.network.get_track_by_mbid(mbid)
1689
        track_mbid = track.get_mbid()
1690
1691
        # Assert
1692
        self.assertIsInstance(track, pylast.Track)
1693
        self.assertEqual(track.title, "first")
1694
        self.assertEqual(track_mbid, mbid)
1695
1696
    @handle_lastfm_exceptions
1697
    def test_artist_listener_count(self):
1698
        # Arrange
1699
        artist = self.network.get_artist("Test Artist")
1700
1701
        # Act
1702
        count = artist.get_listener_count()
1703
1704
        # Assert
1705
        self.assertIsInstance(count, int)
1706
        self.assertGreater(count, 0)
1707
1708
    @handle_lastfm_exceptions
1709
    def test_event_attendees(self):
1710
        # Arrange
1711
        user = self.network.get_user("RJ")
1712
        event = user.get_past_events(limit=1)[0]
1713
1714
        # Act
1715
        users = event.get_attendees()
1716
1717
        # Assert
1718
        self.assertIsInstance(users, list)
1719
        self.assertIsInstance(users[0], pylast.User)
1720
1721
    @handle_lastfm_exceptions
1722
    def test_tag_artist(self):
1723
        # Arrange
1724
        artist = self.network.get_artist("Test Artist")
1725
#         artist.clear_tags()
1726
1727
        # Act
1728
        artist.add_tag("testing")
1729
1730
        # Assert
1731
        tags = artist.get_tags()
1732
        self.assertGreater(len(tags), 0)
1733
        found = False
1734
        for tag in tags:
1735
            if tag.name == "testing":
1736
                found = True
1737
                break
1738
        self.assertTrue(found)
1739
1740
    @handle_lastfm_exceptions
1741
    def test_remove_tag_of_type_text(self):
1742
        # Arrange
1743
        tag = "testing"  # text
1744
        artist = self.network.get_artist("Test Artist")
1745
        artist.add_tag(tag)
1746
1747
        # Act
1748
        artist.remove_tag(tag)
1749
1750
        # Assert
1751
        tags = artist.get_tags()
1752
        found = False
1753
        for tag in tags:
1754
            if tag.name == "testing":
1755
                found = True
1756
                break
1757
        self.assertFalse(found)
1758
1759
    @handle_lastfm_exceptions
1760
    def test_remove_tag_of_type_tag(self):
1761
        # Arrange
1762
        tag = pylast.Tag("testing", self.network)  # Tag
1763
        artist = self.network.get_artist("Test Artist")
1764
        artist.add_tag(tag)
1765
1766
        # Act
1767
        artist.remove_tag(tag)
1768
1769
        # Assert
1770
        tags = artist.get_tags()
1771
        found = False
1772
        for tag in tags:
1773
            if tag.name == "testing":
1774
                found = True
1775
                break
1776
        self.assertFalse(found)
1777
1778 View Code Duplication
    @handle_lastfm_exceptions
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1779
    def test_remove_tags(self):
1780
        # Arrange
1781
        tags = ["removetag1", "removetag2"]
1782
        artist = self.network.get_artist("Test Artist")
1783
        artist.add_tags(tags)
1784
        artist.add_tags("1more")
1785
        tags_before = artist.get_tags()
1786
1787
        # Act
1788
        artist.remove_tags(tags)
1789
1790
        # Assert
1791
        tags_after = artist.get_tags()
1792
        self.assertEqual(len(tags_after), len(tags_before) - 2)
1793
        found1, found2 = False, False
1794
        for tag in tags_after:
1795
            if tag.name == "removetag1":
1796
                found1 = True
1797
            elif tag.name == "removetag2":
1798
                found2 = True
1799
        self.assertFalse(found1)
1800
        self.assertFalse(found2)
1801
1802 View Code Duplication
    @handle_lastfm_exceptions
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1803
    def test_set_tags(self):
1804
        # Arrange
1805
        tags = ["sometag1", "sometag2"]
1806
        artist = self.network.get_artist("Test Artist")
1807
        artist.add_tags(tags)
1808
        tags_before = artist.get_tags()
1809
        new_tags = ["settag1", "settag2"]
1810
1811
        # Act
1812
        artist.set_tags(new_tags)
1813
1814
        # Assert
1815
        tags_after = artist.get_tags()
1816
        self.assertNotEqual(tags_before, tags_after)
1817
        self.assertEqual(len(tags_after), 2)
1818
        found1, found2 = False, False
1819
        for tag in tags_after:
1820
            if tag.name == "settag1":
1821
                found1 = True
1822
            elif tag.name == "settag2":
1823
                found2 = True
1824
        self.assertTrue(found1)
1825
        self.assertTrue(found2)
1826
1827
    @handle_lastfm_exceptions
1828
    def test_tracks_notequal(self):
1829
        # Arrange
1830
        track1 = pylast.Track("Test Artist", "Test Title", self.network)
1831
        track2 = pylast.Track("Test Artist", "Test Track", self.network)
1832
1833
        # Act
1834
        # Assert
1835
        self.assertNotEqual(track1, track2)
1836
1837
    @handle_lastfm_exceptions
1838
    def test_track_id(self):
1839
        # Arrange
1840
        track = pylast.Track("Test Artist", "Test Title", self.network)
1841
1842
        # Act
1843
        id = track.get_id()
1844
1845
        # Assert
1846
        self.skip_if_lastfm_api_broken(id)
1847
        self.assertEqual(id, "14053327")
1848
1849
    @handle_lastfm_exceptions
1850
    def test_track_title_prop_caps(self):
1851
        # Arrange
1852
        track = pylast.Track("test artist", "test title", self.network)
1853
1854
        # Act
1855
        title = track.get_title(properly_capitalized=True)
1856
1857
        # Assert
1858
        self.assertEqual(title, "Test Title")
1859
1860
    @handle_lastfm_exceptions
1861
    def test_track_listener_count(self):
1862
        # Arrange
1863
        track = pylast.Track("test artist", "test title", self.network)
1864
1865
        # Act
1866
        count = track.get_listener_count()
1867
1868
        # Assert
1869
        self.assertGreater(count, 21)
1870
1871
    @handle_lastfm_exceptions
1872
    def test_album_rel_date(self):
1873
        # Arrange
1874
        album = pylast.Album("Test Artist", "Test Release", self.network)
1875
1876
        # Act
1877
        date = album.get_release_date()
1878
1879
        # Assert
1880
        self.skip_if_lastfm_api_broken(date)
1881
        self.assertIn("2011", date)
1882
1883
    @handle_lastfm_exceptions
1884
    def test_album_tracks(self):
1885
        # Arrange
1886
        album = pylast.Album("Test Artist", "Test Release", self.network)
1887
1888
        # Act
1889
        tracks = album.get_tracks()
1890
1891
        # Assert
1892
        self.assertIsInstance(tracks, list)
1893
        self.assertIsInstance(tracks[0], pylast.Track)
1894
        self.assertEqual(len(tracks), 4)
1895
1896 View Code Duplication
    @handle_lastfm_exceptions
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1897
    def test_tags(self):
1898
        # Arrange
1899
        tag1 = self.network.get_tag("blues")
1900
        tag2 = self.network.get_tag("rock")
1901
1902
        # Act
1903
        tag_repr = repr(tag1)
1904
        tag_str = str(tag1)
1905
        name = tag1.get_name(properly_capitalized=True)
1906
        url = tag1.get_url()
1907
1908
        # Assert
1909
        self.assertEqual("blues", tag_str)
1910
        self.assertIn("pylast.Tag", tag_repr)
1911
        self.assertIn("blues", tag_repr)
1912
        self.assertEqual("blues", name)
1913
        self.assertTrue(tag1 == tag1)
1914
        self.assertTrue(tag1 != tag2)
1915
        self.assertEqual(url, "http://www.last.fm/tag/blues")
1916
1917
    @handle_lastfm_exceptions
1918
    def test_tags_similar(self):
1919
        # Arrange
1920
        tag = self.network.get_tag("blues")
1921
1922
        # Act
1923
        similar = tag.get_similar()
1924
1925
        # Assert
1926
        self.skip_if_lastfm_api_broken(similar)
1927
        found = False
1928
        for tag in similar:
1929
            if tag.name == "delta blues":
1930
                found = True
1931
                break
1932
        self.assertTrue(found)
1933
1934
    @handle_lastfm_exceptions
1935
    def test_artists(self):
1936
        # Arrange
1937
        artist1 = self.network.get_artist("Radiohead")
1938
        artist2 = self.network.get_artist("Portishead")
1939
1940
        # Act
1941
        url = artist1.get_url()
1942
        mbid = artist1.get_mbid()
1943
        image = artist1.get_cover_image()
1944
        playcount = artist1.get_playcount()
1945
        streamable = artist1.is_streamable()
1946
        name = artist1.get_name(properly_capitalized=False)
1947
        name_cap = artist1.get_name(properly_capitalized=True)
1948
1949
        # Assert
1950
        self.assertIn("http", image)
1951
        self.assertGreater(playcount, 1)
1952
        self.assertTrue(artist1 != artist2)
1953
        self.assertEqual(name.lower(), name_cap.lower())
1954
        self.assertEqual(url, "http://www.last.fm/music/radiohead")
1955
        self.assertEqual(mbid, "a74b1b7f-71a5-4011-9441-d0b5e4122711")
1956
        self.assertIsInstance(streamable, bool)
1957
1958
    @handle_lastfm_exceptions
1959
    def test_events(self):
1960
        # Arrange
1961
        event_id_1 = 3162700  # Glasto 2013
1962
        event_id_2 = 3478520  # Glasto 2014
1963
        event1 = pylast.Event(event_id_1, self.network)
1964
        event2 = pylast.Event(event_id_2, self.network)
1965
1966
        # Act
1967
        text = str(event1)
1968
        rep = repr(event1)
1969
        title = event1.get_title()
1970
        artists = event1.get_artists()
1971
        start = event1.get_start_date()
1972
        description = event1.get_description()
1973
        review_count = event1.get_review_count()
1974
        attendance_count = event1.get_attendance_count()
1975
1976
        # Assert
1977
        self.assertIn("3162700", rep)
1978
        self.assertIn("pylast.Event", rep)
1979
        self.assertEqual(text, "Event #3162700")
1980
        self.assertTrue(event1 != event2)
1981
        self.assertIn("Glastonbury", title)
1982
        found = False
1983
        for artist in artists:
1984
            if artist.name == "The Rolling Stones":
1985
                found = True
1986
                break
1987
        self.assertTrue(found)
1988
        self.assertIn("Wed, 26 Jun 2013", start)
1989
        self.assertIn("astonishing bundle", description)
1990
        self.assertGreater(review_count, 0)
1991
        self.assertGreater(attendance_count, 100)
1992
1993 View Code Duplication
    @handle_lastfm_exceptions
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1994
    def test_countries(self):
1995
        # Arrange
1996
        country1 = pylast.Country("Italy", self.network)
1997
        country2 = pylast.Country("Finland", self.network)
1998
1999
        # Act
2000
        text = str(country1)
2001
        rep = repr(country1)
2002
        url = country1.get_url()
2003
2004
        # Assert
2005
        self.assertIn("Italy", rep)
2006
        self.assertIn("pylast.Country", rep)
2007
        self.assertEqual(text, "Italy")
2008
        self.assertTrue(country1 == country1)
2009
        self.assertTrue(country1 != country2)
2010
        self.assertEqual(url, "http://www.last.fm/place/italy")
2011
2012
    @handle_lastfm_exceptions
2013
    def test_track_eq_none_is_false(self):
2014
        # Arrange
2015
        track1 = None
2016
        track2 = pylast.Track("Test Artist", "Test Title", self.network)
2017
2018
        # Act / Assert
2019
        self.assertFalse(track1 == track2)
2020
2021
    @handle_lastfm_exceptions
2022
    def test_track_ne_none_is_true(self):
2023
        # Arrange
2024
        track1 = None
2025
        track2 = pylast.Track("Test Artist", "Test Title", self.network)
2026
2027
        # Act / Assert
2028
        self.assertTrue(track1 != track2)
2029
2030
    @handle_lastfm_exceptions
2031
    def test_artist_eq_none_is_false(self):
2032
        # Arrange
2033
        artist1 = None
2034
        artist2 = pylast.Artist("Test Artist", self.network)
2035
2036
        # Act / Assert
2037
        self.assertFalse(artist1 == artist2)
2038
2039
    @handle_lastfm_exceptions
2040
    def test_artist_ne_none_is_true(self):
2041
        # Arrange
2042
        artist1 = None
2043
        artist2 = pylast.Artist("Test Artist", self.network)
2044
2045
        # Act / Assert
2046
        self.assertTrue(artist1 != artist2)
2047
2048
    @handle_lastfm_exceptions
2049
    def test_album_eq_none_is_false(self):
2050
        # Arrange
2051
        album1 = None
2052
        album2 = pylast.Album("Test Artist", "Test Album", self.network)
2053
2054
        # Act / Assert
2055
        self.assertFalse(album1 == album2)
2056
2057
    @handle_lastfm_exceptions
2058
    def test_album_ne_none_is_true(self):
2059
        # Arrange
2060
        album1 = None
2061
        album2 = pylast.Album("Test Artist", "Test Album", self.network)
2062
2063
        # Act / Assert
2064
        self.assertTrue(album1 != album2)
2065
2066
    @handle_lastfm_exceptions
2067
    def test_event_eq_none_is_false(self):
2068
        # Arrange
2069
        event1 = None
2070
        event_id = 3478520  # Glasto 2014
2071
        event2 = pylast.Event(event_id, self.network)
2072
2073
        # Act / Assert
2074
        self.assertFalse(event1 == event2)
2075
2076
    @handle_lastfm_exceptions
2077
    def test_event_ne_none_is_true(self):
2078
        # Arrange
2079
        event1 = None
2080
        event_id = 3478520  # Glasto 2014
2081
        event2 = pylast.Event(event_id, self.network)
2082
2083
        # Act / Assert
2084
        self.assertTrue(event1 != event2)
2085
2086
    @handle_lastfm_exceptions
2087
    def test_band_members(self):
2088
        # Arrange
2089
        artist = pylast.Artist("The Beatles", self.network)
2090
2091
        # Act
2092
        band_members = artist.get_band_members()
2093
2094
        # Assert
2095
        self.skip_if_lastfm_api_broken(band_members)
2096
        self.assertGreaterEqual(len(band_members), 4)
2097
2098
    @handle_lastfm_exceptions
2099
    def test_no_band_members(self):
2100
        # Arrange
2101
        artist = pylast.Artist("John Lennon", self.network)
2102
2103
        # Act
2104
        band_members = artist.get_band_members()
2105
2106
        # Assert
2107
        self.assertIsNone(band_members)
2108
2109
    @handle_lastfm_exceptions
2110
    def test_get_recent_tracks_from_to(self):
2111
        # Arrange
2112
        lastfm_user = self.network.get_user("RJ")
2113
2114
        from datetime import datetime
2115
        start = datetime(2011, 7, 21, 15, 10)
2116
        end = datetime(2011, 7, 21, 15, 15)
2117
        import calendar
2118
        utc_start = calendar.timegm(start.utctimetuple())
2119
        utc_end = calendar.timegm(end.utctimetuple())
2120
2121
        # Act
2122
        tracks = lastfm_user.get_recent_tracks(time_from=utc_start,
2123
                                               time_to=utc_end)
2124
2125
        # Assert
2126
        self.assertEqual(len(tracks), 1)
2127
        self.assertEqual(str(tracks[0].track.artist), "Johnny Cash")
2128
        self.assertEqual(str(tracks[0].track.title), "Ring of Fire")
2129
2130
    @handle_lastfm_exceptions
2131
    def test_artist_get_correction(self):
2132
        # Arrange
2133
        artist = pylast.Artist("guns and roses", self.network)
2134
2135
        # Act
2136
        corrected_artist_name = artist.get_correction()
2137
2138
        # Assert
2139
        self.assertEqual(corrected_artist_name, "Guns N' Roses")
2140
2141
    @handle_lastfm_exceptions
2142
    def test_track_get_correction(self):
2143
        # Arrange
2144
        track = pylast.Track("Guns N' Roses", "mrbrownstone", self.network)
2145
2146
        # Act
2147
        corrected_track_name = track.get_correction()
2148
2149
        # Assert
2150
        self.assertEqual(corrected_track_name, "Mr. Brownstone")
2151
2152
    @handle_lastfm_exceptions
2153
    def test_track_with_no_mbid(self):
2154
        # Arrange
2155
        track = pylast.Track("Static-X", "Set It Off", self.network)
2156
2157
        # Act
2158
        mbid = track.get_mbid()
2159
2160
        # Assert
2161
        self.assertEqual(mbid, None)
2162
2163
2164
@flaky(max_runs=5, min_passes=1)
2165
class TestPyLastWithLibreFm(unittest.TestCase):
2166
    """Own class for Libre.fm because we don't need the Last.fm setUp"""
2167
2168
    def test_libre_fm(self):
2169
        # Arrange
2170
        secrets = load_secrets()
2171
        username = secrets["username"]
2172
        password_hash = secrets["password_hash"]
2173
2174
        # Act
2175
        network = pylast.LibreFMNetwork(
2176
            password_hash=password_hash, username=username)
2177
        artist = network.get_artist("Radiohead")
2178
        name = artist.get_name()
2179
2180
        # Assert
2181
        self.assertEqual(name, "Radiohead")
2182
2183
2184
if __name__ == '__main__':
2185
    unittest.main(failfast=True)
2186