Completed
Push — develop ( 6ecba6...597386 )
by Hugo
10:17
created

tests.wrapper()   A

Complexity

Conditions 3

Size

Total Lines 11

Duplication

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