Completed
Push — skip ( 950c2e )
by Hugo
05:53
created

tests.handle_lastfm_exceptions()   A

Complexity

Conditions 4

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 4
dl 0
loc 13
rs 9.2

1 Method

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