hornairs-scrobbler 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. data/.gitignore +13 -0
  2. data/.loadpath +5 -0
  3. data/History.txt +5 -0
  4. data/MIT-LICENSE +19 -0
  5. data/Manifest +75 -0
  6. data/README.rdoc +104 -0
  7. data/Rakefile +10 -0
  8. data/VERSION.yml +5 -0
  9. data/examples/album.rb +20 -0
  10. data/examples/artist.rb +13 -0
  11. data/examples/playlist.rb +7 -0
  12. data/examples/scrobble.rb +31 -0
  13. data/examples/tag.rb +11 -0
  14. data/examples/track.rb +12 -0
  15. data/examples/user.rb +15 -0
  16. data/lib/scrobbler.rb +33 -0
  17. data/lib/scrobbler/album.rb +181 -0
  18. data/lib/scrobbler/artist.rb +165 -0
  19. data/lib/scrobbler/auth.rb +47 -0
  20. data/lib/scrobbler/base.rb +105 -0
  21. data/lib/scrobbler/event.rb +105 -0
  22. data/lib/scrobbler/geo.rb +27 -0
  23. data/lib/scrobbler/helper/image.rb +52 -0
  24. data/lib/scrobbler/helper/streamable.rb +40 -0
  25. data/lib/scrobbler/library.rb +112 -0
  26. data/lib/scrobbler/playing.rb +49 -0
  27. data/lib/scrobbler/playlist.rb +87 -0
  28. data/lib/scrobbler/radio.rb +12 -0
  29. data/lib/scrobbler/rest.rb +47 -0
  30. data/lib/scrobbler/scrobble.rb +116 -0
  31. data/lib/scrobbler/session.rb +9 -0
  32. data/lib/scrobbler/shout.rb +21 -0
  33. data/lib/scrobbler/simpleauth.rb +60 -0
  34. data/lib/scrobbler/tag.rb +113 -0
  35. data/lib/scrobbler/track.rb +152 -0
  36. data/lib/scrobbler/user.rb +222 -0
  37. data/lib/scrobbler/venue.rb +67 -0
  38. data/setup.rb +1585 -0
  39. data/tasks/jeweler.rake +15 -0
  40. data/tasks/rdoc.rake +7 -0
  41. data/tasks/tests.rake +13 -0
  42. data/tasks/yardoc.rake +8 -0
  43. data/test/fixtures/xml/album/info.xml +43 -0
  44. data/test/fixtures/xml/artist/fans.xml +52 -0
  45. data/test/fixtures/xml/artist/info.xml +58 -0
  46. data/test/fixtures/xml/artist/similar.xml +1004 -0
  47. data/test/fixtures/xml/artist/topalbums.xml +61 -0
  48. data/test/fixtures/xml/artist/toptags.xml +19 -0
  49. data/test/fixtures/xml/artist/toptracks.xml +62 -0
  50. data/test/fixtures/xml/auth/session.xml +7 -0
  51. data/test/fixtures/xml/auth/token.xml +3 -0
  52. data/test/fixtures/xml/event/attend.xml +3 -0
  53. data/test/fixtures/xml/event/attendees.xml +53 -0
  54. data/test/fixtures/xml/event/event.xml +35 -0
  55. data/test/fixtures/xml/event/shouts.xml +35 -0
  56. data/test/fixtures/xml/geo/events-distance-p1.xml +151 -0
  57. data/test/fixtures/xml/geo/events-lat-long.xml +167 -0
  58. data/test/fixtures/xml/geo/events-p1.xml +152 -0
  59. data/test/fixtures/xml/geo/events-p2.xml +380 -0
  60. data/test/fixtures/xml/geo/events-p3.xml +427 -0
  61. data/test/fixtures/xml/geo/top_artists-p1.xml +76 -0
  62. data/test/fixtures/xml/geo/top_tracks-p1.xml +77 -0
  63. data/test/fixtures/xml/library/albums-f30.xml +454 -0
  64. data/test/fixtures/xml/library/albums-p1.xml +754 -0
  65. data/test/fixtures/xml/library/albums-p2.xml +754 -0
  66. data/test/fixtures/xml/library/albums-p3.xml +754 -0
  67. data/test/fixtures/xml/library/albums-p4.xml +739 -0
  68. data/test/fixtures/xml/library/albums-p5.xml +754 -0
  69. data/test/fixtures/xml/library/albums-p6.xml +754 -0
  70. data/test/fixtures/xml/library/albums-p7.xml +739 -0
  71. data/test/fixtures/xml/library/albums-p8.xml +724 -0
  72. data/test/fixtures/xml/library/artists-f30.xml +334 -0
  73. data/test/fixtures/xml/library/artists-p1.xml +554 -0
  74. data/test/fixtures/xml/library/artists-p2.xml +554 -0
  75. data/test/fixtures/xml/library/artists-p3.xml +554 -0
  76. data/test/fixtures/xml/library/artists-p4.xml +554 -0
  77. data/test/fixtures/xml/library/artists-p5.xml +554 -0
  78. data/test/fixtures/xml/library/artists-p6.xml +554 -0
  79. data/test/fixtures/xml/library/artists-p7.xml +444 -0
  80. data/test/fixtures/xml/library/tracks-f30.xml +472 -0
  81. data/test/fixtures/xml/library/tracks-p1.xml +789 -0
  82. data/test/fixtures/xml/library/tracks-p10.xml +771 -0
  83. data/test/fixtures/xml/library/tracks-p11.xml +792 -0
  84. data/test/fixtures/xml/library/tracks-p12.xml +777 -0
  85. data/test/fixtures/xml/library/tracks-p13.xml +762 -0
  86. data/test/fixtures/xml/library/tracks-p14.xml +759 -0
  87. data/test/fixtures/xml/library/tracks-p15.xml +762 -0
  88. data/test/fixtures/xml/library/tracks-p16.xml +756 -0
  89. data/test/fixtures/xml/library/tracks-p17.xml +780 -0
  90. data/test/fixtures/xml/library/tracks-p18.xml +756 -0
  91. data/test/fixtures/xml/library/tracks-p19.xml +774 -0
  92. data/test/fixtures/xml/library/tracks-p2.xml +765 -0
  93. data/test/fixtures/xml/library/tracks-p20.xml +777 -0
  94. data/test/fixtures/xml/library/tracks-p21.xml +777 -0
  95. data/test/fixtures/xml/library/tracks-p22.xml +771 -0
  96. data/test/fixtures/xml/library/tracks-p23.xml +765 -0
  97. data/test/fixtures/xml/library/tracks-p24.xml +783 -0
  98. data/test/fixtures/xml/library/tracks-p25.xml +777 -0
  99. data/test/fixtures/xml/library/tracks-p26.xml +777 -0
  100. data/test/fixtures/xml/library/tracks-p27.xml +756 -0
  101. data/test/fixtures/xml/library/tracks-p28.xml +771 -0
  102. data/test/fixtures/xml/library/tracks-p29.xml +753 -0
  103. data/test/fixtures/xml/library/tracks-p3.xml +771 -0
  104. data/test/fixtures/xml/library/tracks-p30.xml +780 -0
  105. data/test/fixtures/xml/library/tracks-p31.xml +753 -0
  106. data/test/fixtures/xml/library/tracks-p32.xml +771 -0
  107. data/test/fixtures/xml/library/tracks-p33.xml +762 -0
  108. data/test/fixtures/xml/library/tracks-p34.xml +538 -0
  109. data/test/fixtures/xml/library/tracks-p4.xml +792 -0
  110. data/test/fixtures/xml/library/tracks-p5.xml +780 -0
  111. data/test/fixtures/xml/library/tracks-p6.xml +789 -0
  112. data/test/fixtures/xml/library/tracks-p7.xml +789 -0
  113. data/test/fixtures/xml/library/tracks-p8.xml +780 -0
  114. data/test/fixtures/xml/library/tracks-p9.xml +774 -0
  115. data/test/fixtures/xml/tag/similar.xml +254 -0
  116. data/test/fixtures/xml/tag/topalbums.xml +805 -0
  117. data/test/fixtures/xml/tag/topartists.xml +605 -0
  118. data/test/fixtures/xml/tag/toptags.xml +1254 -0
  119. data/test/fixtures/xml/tag/toptracks.xml +852 -0
  120. data/test/fixtures/xml/track/fans.xml +34 -0
  121. data/test/fixtures/xml/track/info.xml +53 -0
  122. data/test/fixtures/xml/track/toptags.xml +504 -0
  123. data/test/fixtures/xml/user/events.xml +401 -0
  124. data/test/fixtures/xml/user/friends.xml +30 -0
  125. data/test/fixtures/xml/user/lovedtracks.xml +678 -0
  126. data/test/fixtures/xml/user/neighbours.xml +23 -0
  127. data/test/fixtures/xml/user/playlists.xml +61 -0
  128. data/test/fixtures/xml/user/profile.xml +12 -0
  129. data/test/fixtures/xml/user/recentbannedtracks.xml +24 -0
  130. data/test/fixtures/xml/user/recentlovedtracks.xml +24 -0
  131. data/test/fixtures/xml/user/recenttracks.xml +124 -0
  132. data/test/fixtures/xml/user/systemrecs.xml +18 -0
  133. data/test/fixtures/xml/user/topalbums.xml +61 -0
  134. data/test/fixtures/xml/user/topartists.xml +41 -0
  135. data/test/fixtures/xml/user/toptags.xml +44 -0
  136. data/test/fixtures/xml/user/toptracks.xml +65 -0
  137. data/test/fixtures/xml/user/weeklyalbumchart.xml +256 -0
  138. data/test/fixtures/xml/user/weeklyartistchart.xml +220 -0
  139. data/test/fixtures/xml/user/weeklytrackchart.xml +746 -0
  140. data/test/fixtures/xml/venue/events.xml +151 -0
  141. data/test/fixtures/xml/venue/venue.xml +16 -0
  142. data/test/mocks/rest.rb +212 -0
  143. data/test/spec_helper.rb +7 -0
  144. data/test/test_helper.rb +20 -0
  145. data/test/unit/album_spec.rb +52 -0
  146. data/test/unit/artist_spec.rb +130 -0
  147. data/test/unit/auth_spec.rb +36 -0
  148. data/test/unit/event_spec.rb +109 -0
  149. data/test/unit/geo_spec.rb +148 -0
  150. data/test/unit/library_spec.rb +133 -0
  151. data/test/unit/playing_test.rb +53 -0
  152. data/test/unit/playlist_spec.rb +25 -0
  153. data/test/unit/radio_spec.rb +22 -0
  154. data/test/unit/scrobble_spec.rb +55 -0
  155. data/test/unit/scrobble_test.rb +69 -0
  156. data/test/unit/simpleauth_test.rb +45 -0
  157. data/test/unit/tag_spec.rb +101 -0
  158. data/test/unit/track_spec.rb +95 -0
  159. data/test/unit/user_spec.rb +264 -0
  160. data/test/unit/venue_spec.rb +104 -0
  161. metadata +265 -0
@@ -0,0 +1,151 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <lfm status="ok">
3
+ <events venue="Postbahnhof" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
4
+ <event status="2">
5
+ <id>875740</id>
6
+ <title>Kilians</title>
7
+ <artists>
8
+ <artist>Kilians</artist>
9
+ <artist>Miyagi</artist>
10
+ <headliner>Kilians</headliner>
11
+ </artists>
12
+ <venue>
13
+ <id>8927785</id>
14
+ <name>Postbahnhof</name>
15
+ <location>
16
+ <city>Berlin</city>
17
+ <country>Germany</country>
18
+ <street>Straße der Pariser Kommune 8</street>
19
+ <postalcode>10243</postalcode>
20
+ <geo:point>
21
+ <geo:lat>52.508693</geo:lat>
22
+ <geo:long>13.435056</geo:long>
23
+ </geo:point>
24
+ </location>
25
+ <url>http://www.last.fm/venue/8927785</url>
26
+ </venue>
27
+ <startDate>Wed, 03 Jun 2009 15:47:01</startDate>
28
+ <description></description>
29
+ <image size="small">http://userserve-ak.last.fm/serve/34/420392.jpg</image>
30
+ <image size="medium">http://userserve-ak.last.fm/serve/64/420392.jpg</image>
31
+ <image size="large">http://userserve-ak.last.fm/serve/126/420392.jpg</image>
32
+ <attendance>77</attendance>
33
+ <reviews>0</reviews>
34
+ <tag>lastfm:event=875740</tag>
35
+ <url>http://www.last.fm/event/875740</url>
36
+ <website>http://popula.de/the-kilians-tour-2009</website>
37
+ <tickets>
38
+ </tickets>
39
+ </event>
40
+ <event status="2">
41
+ <id>950267</id>
42
+ <title>Convention of the Universe - International Depeche Mode Fan Event</title>
43
+ <artists>
44
+ <artist>De/Vision</artist>
45
+ <artist>Nitzer Ebb</artist>
46
+ <artist>Frozen Plasma</artist>
47
+ <headliner>De/Vision</headliner>
48
+ </artists>
49
+ <venue>
50
+ <id>8927785</id>
51
+ <name>Postbahnhof</name>
52
+ <location>
53
+ <city>Berlin</city>
54
+ <country>Germany</country>
55
+ <street>Straße der Pariser Kommune 8</street>
56
+ <postalcode>10243</postalcode>
57
+ <geo:point>
58
+ <geo:lat>52.508693</geo:lat>
59
+ <geo:long>13.435056</geo:long>
60
+ </geo:point>
61
+ </location>
62
+ <url>http://www.last.fm/venue/8927785</url>
63
+ </venue>
64
+ <startDate>Tue, 09 Jun 2009 20:00:00</startDate>
65
+ <description><![CDATA[<div class="bbcode">[youtube]<a href="http://www.youtube.com/watch?v=jHbTI9ZkMxg&amp;feature=player_embedded" rel="nofollow">http://www.youtube.com/watch?v=jHbTI9ZkMxg&amp;feature=player_embedded</a>[/youtube]</div>]]>
66
+ </description>
67
+ <image size="small">http://userserve-ak.last.fm/serve/34/134107.jpg</image>
68
+ <image size="medium">http://userserve-ak.last.fm/serve/64/134107.jpg</image>
69
+ <image size="large">http://userserve-ak.last.fm/serve/126/134107.jpg</image>
70
+ <attendance>61</attendance>
71
+ <reviews>0</reviews>
72
+ <tag>lastfm:event=950267</tag>
73
+ <url>http://www.last.fm/event/950267</url>
74
+ <website>http://ww.blackswarm.de</website>
75
+ <tickets>
76
+ </tickets>
77
+ </event>
78
+ <event status="2">
79
+ <id>1082373</id>
80
+ <title>The Get Up Kids</title>
81
+ <artists>
82
+ <artist>The Get Up Kids</artist>
83
+ <headliner>The Get Up Kids</headliner>
84
+ </artists>
85
+ <venue>
86
+ <id>8927785</id>
87
+ <name>Postbahnhof</name>
88
+ <location>
89
+ <city>Berlin</city>
90
+ <country>Germany</country>
91
+ <street>Straße der Pariser Kommune 8</street>
92
+ <postalcode>10243</postalcode>
93
+ <geo:point>
94
+ <geo:lat>52.508693</geo:lat>
95
+ <geo:long>13.435056</geo:long>
96
+ </geo:point>
97
+ </location>
98
+ <url>http://www.last.fm/venue/8927785</url>
99
+ </venue>
100
+ <startDate>Tue, 25 Aug 2009 09:23:01</startDate>
101
+ <description><![CDATA[<div class="bbcode">VVK 18,00 €<br />
102
+ zzgl. Gebühren</div>]]>
103
+ </description>
104
+ <image size="small">http://userserve-ak.last.fm/serve/34/219315.jpg</image>
105
+ <image size="medium">http://userserve-ak.last.fm/serve/64/219315.jpg</image>
106
+ <image size="large">http://userserve-ak.last.fm/serve/126/219315.jpg</image>
107
+ <attendance>36</attendance>
108
+ <reviews>0</reviews>
109
+ <tag>lastfm:event=1082373</tag>
110
+ <url>http://www.last.fm/event/1082373</url>
111
+ <website></website>
112
+ <tickets>
113
+ </tickets>
114
+ </event>
115
+ <event status="2">
116
+ <id>1059277</id>
117
+ <title>Philipp Poisel</title>
118
+ <artists>
119
+ <artist>Philipp Poisel</artist>
120
+ <headliner>Philipp Poisel</headliner>
121
+ </artists>
122
+ <venue>
123
+ <id>8927785</id>
124
+ <name>Postbahnhof</name>
125
+ <location>
126
+ <city>Berlin</city>
127
+ <country>Germany</country>
128
+ <street>Straße der Pariser Kommune 8</street>
129
+ <postalcode>10243</postalcode>
130
+ <geo:point>
131
+ <geo:lat>52.508693</geo:lat>
132
+ <geo:long>13.435056</geo:long>
133
+ </geo:point>
134
+ </location>
135
+ <url>http://www.last.fm/venue/8927785</url>
136
+ </venue>
137
+ <startDate>Sat, 12 Sep 2009 15:53:01</startDate>
138
+ <description></description>
139
+ <image size="small">http://userserve-ak.last.fm/serve/34/12542985.jpg</image>
140
+ <image size="medium">http://userserve-ak.last.fm/serve/64/12542985.jpg</image>
141
+ <image size="large">http://userserve-ak.last.fm/serve/126/12542985.jpg</image>
142
+ <attendance>23</attendance>
143
+ <reviews>0</reviews>
144
+ <tag>lastfm:event=1059277</tag>
145
+ <url>http://www.last.fm/event/1059277</url>
146
+ <website></website>
147
+ <tickets>
148
+ </tickets>
149
+ </event>
150
+ </events>
151
+ </lfm>
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <venue xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
3
+ <name>Karrera Klub</name>
4
+ <location>
5
+ <city>Berlin</city>
6
+ <country>Germany</country>
7
+ <street>Neue Promenade 10</street>
8
+ <postalcode>10178</postalcode>
9
+ <geo:point>
10
+ <geo:lat>52.532019</geo:lat>
11
+ <geo:long>13.427965</geo:long>
12
+ </geo:point>
13
+ <timezone>CET</timezone>
14
+ </location>
15
+ <url>http://www.last.fm/venue/9027137</url>
16
+ </venue>
@@ -0,0 +1,212 @@
1
+ require File.dirname(__FILE__) + '/../../lib/scrobbler/rest'
2
+ require 'rubygems'
3
+ require 'fakeweb'
4
+ require 'digest/md5'
5
+
6
+ FIXTURES_BASE = File.join([File.dirname(__FILE__), '..', 'fixtures', 'xml'])
7
+ FakeWeb.allow_net_connect = false
8
+
9
+ ## Library
10
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&force=false&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'albums-p1.xml']))
11
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&force=false&page=2&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'albums-p2.xml']))
12
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&force=false&page=3&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'albums-p3.xml']))
13
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&force=false&page=4&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'albums-p4.xml']))
14
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&force=false&page=5&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'albums-p5.xml']))
15
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&force=false&page=6&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'albums-p6.xml']))
16
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&force=false&page=7&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'albums-p7.xml']))
17
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&force=false&page=8&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'albums-p8.xml']))
18
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getalbums&limit=30&force=false&api_key=foo123&user=xhochy&all=false', :body => File.join([FIXTURES_BASE, 'library', 'albums-f30.xml']))
19
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getartists&force=false&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'artists-p1.xml']))
20
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getartists&force=false&page=2&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'artists-p2.xml']))
21
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getartists&force=false&page=3&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'artists-p3.xml']))
22
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getartists&force=false&page=4&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'artists-p4.xml']))
23
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getartists&force=false&page=5&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'artists-p5.xml']))
24
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getartists&force=false&page=6&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'artists-p6.xml']))
25
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getartists&force=false&page=7&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'artists-p7.xml']))
26
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.getartists&limit=30&force=false&api_key=foo123&user=xhochy&all=false', :body => File.join([FIXTURES_BASE, 'library', 'artists-f30.xml']))
27
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p1.xml']))
28
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=2&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p2.xml']))
29
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=3&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p3.xml']))
30
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=4&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p4.xml']))
31
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=5&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p5.xml']))
32
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=6&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p6.xml']))
33
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=7&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p7.xml']))
34
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=8&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p8.xml']))
35
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=9&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p9.xml']))
36
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=10&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p10.xml']))
37
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=11&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p11.xml']))
38
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=12&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p12.xml']))
39
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=13&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p13.xml']))
40
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=14&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p14.xml']))
41
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=15&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p15.xml']))
42
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=16&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p16.xml']))
43
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=17&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p17.xml']))
44
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=18&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p18.xml']))
45
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=19&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p19.xml']))
46
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=20&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p20.xml']))
47
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=21&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p21.xml']))
48
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=22&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p22.xml']))
49
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=23&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p23.xml']))
50
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=24&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p24.xml']))
51
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=25&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p25.xml']))
52
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=26&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p26.xml']))
53
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=27&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p27.xml']))
54
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=28&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p28.xml']))
55
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=29&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p29.xml']))
56
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=30&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p30.xml']))
57
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=31&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p31.xml']))
58
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=32&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p32.xml']))
59
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=33&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p33.xml']))
60
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&force=false&page=34&api_key=foo123&user=xhochy&all=true', :body => File.join([FIXTURES_BASE, 'library', 'tracks-p34.xml']))
61
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=library.gettracks&limit=30&force=false&api_key=foo123&user=xhochy&all=false', :body => File.join([FIXTURES_BASE, 'library', 'tracks-f30.xml']))
62
+
63
+ ## Event
64
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=event.getattendees&event=328799&api_key=foo123', :body => File.join([FIXTURES_BASE, 'event', 'attendees.xml']))
65
+ FakeWeb.register_uri(:post, 'http://ws.audioscrobbler.com:80/2.0/?api_key=foo123&event=328799&method=event.attend&sk=d580d57f32848f5dcf574d1ce18d78b2&status=1&api_sig=c476ec753082205327b0f6ef922d82c8', :body => File.join([FIXTURES_BASE, 'event', 'attend.xml']))
66
+
67
+
68
+ ## Tag
69
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=tag.gettoptags&api_key=foo123', :body => File.join([FIXTURES_BASE, 'tag', 'toptags.xml']))
70
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=tag.getsimilar&tag=rock&api_key=foo123', :body => File.join([FIXTURES_BASE, 'tag', 'similar.xml']))
71
+
72
+ ## Venue
73
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=venue.getevents&api_key=foo123&venue=9027137', :body => File.join([FIXTURES_BASE, 'venue', 'events.xml']))
74
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=venue.getpastevents&api_key=foo123&venue=9027137', :body => File.join([FIXTURES_BASE, 'venue', 'events.xml']))
75
+
76
+ ## Auth
77
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?api_key=foo123&method=auth.gettoken&api_sig=d062b3b3fa109d048732819d27d04689', :body => File.join([FIXTURES_BASE, 'auth', 'token.xml']))
78
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?api_key=foo123&method=auth.getsession&token=test123token&api_sig=f4a839c10a010368bd1058725c253dfb', :body => File.join([FIXTURES_BASE, 'auth', 'session.xml']))
79
+
80
+ ## Artist
81
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?artist=Metallica&method=artist.getinfo&api_key=foo123', :body => File.join([FIXTURES_BASE, 'artist', 'info.xml']))
82
+
83
+ ## Track
84
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?api_key=foo123&method=track.getinfo&artist=Carrie%20Underwood&track=Before%20He%20Cheats', :body => File.join([FIXTURES_BASE, 'track', 'info.xml']))
85
+
86
+
87
+ ## Geo
88
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=geo.getevents&api_key=foo123&page=1&force=false&location=Manchester', :body => File.join([FIXTURES_BASE, 'geo', 'events-p1.xml']))
89
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=geo.getevents&api_key=foo123&page=2&force=false&location=Manchester', :body => File.join([FIXTURES_BASE, 'geo', 'events-p2.xml']))
90
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=geo.getevents&api_key=foo123&page=3&force=false&location=Manchester', :body => File.join([FIXTURES_BASE, 'geo', 'events-p3.xml']))
91
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?distance=15&method=geo.getevents&api_key=foo123&page=1&force=false', :body => File.join([FIXTURES_BASE, 'geo', 'events-distance-p1.xml']))
92
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?long=-74.00639&method=geo.getevents&api_key=foo123&page=1&lat=40.71417&force=false', :body => File.join([FIXTURES_BASE, 'geo', 'events-lat-long.xml']))
93
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=geo.gettopartists&api_key=foo123&page=1&force=false&location=Spain', :body => File.join([FIXTURES_BASE, 'geo', 'top_artists-p1.xml']))
94
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=geo.gettoptracks&api_key=foo123&page=1&force=false&location=Germany', :body => File.join([FIXTURES_BASE, 'geo', 'top_tracks-p1.xml']))
95
+
96
+ # User
97
+ FakeWeb.register_uri(:get, 'http://ws.audioscrobbler.com:80/2.0/?method=user.getplaylists&api_key=foo123&user=jnunemaker', :body => File.join([FIXTURES_BASE, 'user', 'playlists.xml']))
98
+
99
+
100
+
101
+ module Scrobbler
102
+ module REST
103
+ class Connection
104
+ alias :old_request :request
105
+ # reads xml fixture file instead of hitting up the internets
106
+ def request(resource, method = "get", args = nil)
107
+
108
+ @now_playing_url = 'http://62.216.251.203:80/nowplaying'
109
+ @submission_url = 'http://62.216.251.205:80/protocol_1.2'
110
+ @session_id = '17E61E13454CDD8B68E8D7DEEEDF6170'
111
+
112
+ if @base_url == Scrobbler::API_URL
113
+ pieces = resource.split('/')
114
+ pieces.shift
115
+ api_version = pieces.shift
116
+ if api_version == "1.0"
117
+ folder = pieces.shift
118
+ file = pieces.last[0, pieces.last.index('.xml')]
119
+ base_pieces = pieces.last.split('?')
120
+
121
+ file = if base_pieces.size > 1
122
+ # if query string params are in resource they are underscore separated for filenames
123
+ base_pieces.last.split('&').inject("#{file}_") { |str, pair| str << pair.split('=').join('_') + '_'; str }.chop!
124
+ else
125
+ file
126
+ end
127
+
128
+ File.read(File.dirname(__FILE__) + "/../fixtures/xml/#{folder}/#{file}.xml")
129
+ elsif api_version == "2.0"
130
+ method_pieces = pieces.last.split('&')
131
+ api_method = method_pieces.shift
132
+ if api_method == '?method=artist.search'
133
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/search/artist.xml")
134
+ elsif api_method == '?method=album.search'
135
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/search/album.xml")
136
+ elsif api_method == '?method=track.search'
137
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/search/track.xml")
138
+ elsif pieces.last =~ /[?&]method=album\.getinfo/
139
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/album/info.xml")
140
+ elsif pieces.last =~ /[?&]method=artist\.gettoptags/
141
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/artist/toptags.xml")
142
+ elsif pieces.last =~ /[?&]method=artist\.gettopfans/
143
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/artist/fans.xml")
144
+ elsif pieces.last =~ /[?&]method=artist\.gettoptracks/
145
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/artist/toptracks.xml")
146
+ elsif pieces.last =~ /[?&]method=artist\.gettopalbums/
147
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/artist/topalbums.xml")
148
+ elsif pieces.last =~ /[?&]method=artist\.getsimilar/
149
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/artist/similar.xml")
150
+ elsif pieces.last =~ /[?&]method=tag\.gettoptracks/
151
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/tag/toptracks.xml")
152
+ elsif pieces.last =~ /[?&]method=tag\.gettopartists/
153
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/tag/topartists.xml")
154
+ elsif pieces.last =~ /[?&]method=tag\.gettopalbums/
155
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/tag/topalbums.xml")
156
+ elsif pieces.last =~ /[?&]method=track\.gettoptags/
157
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/track/toptags.xml")
158
+ elsif pieces.last =~ /[?&]method=track\.gettopfans/
159
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/track/fans.xml")
160
+ elsif pieces.last =~ /[?&]method=user\.getlovedtracks/
161
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/lovedtracks.xml")
162
+ elsif pieces.last =~ /[?&]method=user\.gettopartists/
163
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/topartists.xml")
164
+ elsif pieces.last =~ /[?&]method=user\.gettopalbums/
165
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/topalbums.xml")
166
+ elsif pieces.last =~ /[?&]method=user\.gettoptracks/
167
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/toptracks.xml")
168
+ elsif pieces.last =~ /[?&]method=user\.getfriends/
169
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/friends.xml")
170
+ elsif pieces.last =~ /[?&]method=user\.gettoptags/
171
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/toptags.xml")
172
+ elsif pieces.last =~ /[?&]method=user\.getneighbours/
173
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/neighbours.xml")
174
+ elsif pieces.last =~ /[?&]method=user\.getrecenttracks/
175
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/recenttracks.xml")
176
+ elsif pieces.last =~ /[?&]method=event\.getinfo/
177
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/event/event.xml")
178
+ elsif pieces.last =~ /[?&]method=event\.getshouts/
179
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/event/shouts.xml")
180
+ elsif pieces.last =~ /[?&]method=user\.getweeklyalbumchart/
181
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/weeklyalbumchart.xml")
182
+ elsif pieces.last =~ /[?&]method=user\.getweeklyartistchart/
183
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/weeklyartistchart.xml")
184
+ elsif pieces.last =~ /[?&]method=user\.getweeklytrackchart/
185
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/weeklytrackchart.xml")
186
+ elsif pieces.last =~ /[?&]method=user\.getevents/
187
+ return File.read(File.dirname(__FILE__) + "/../fixtures/xml/user/events.xml")
188
+ else
189
+ old_request(resource, method, args)
190
+ end
191
+ end
192
+ elsif @base_url == Scrobbler::AUTH_URL
193
+ if args[:hs] == "true" && args[:p] == Scrobbler::AUTH_VER.to_s && args[:c] == 'rbs' &&
194
+ args[:v] == '0.2.13' && args[:u] == 'chunky' && !args[:t].blank? &&
195
+ args[:a] == Digest::MD5.hexdigest('7813258ef8c6b632dde8cc80f6bda62f' + args[:t])
196
+
197
+ "OK\n#{@session_id}\n#{@now_playing_url}\n#{@submission_url}"
198
+ end
199
+ elsif @base_url == @now_playing_url
200
+ if args[:s] == @session_id && ![args[:a], args[:t], args[:b], args[:n]].any?(&:blank?)
201
+ 'OK'
202
+ end
203
+ elsif @base_url == @submission_url
204
+ if args[:s] == @session_id &&
205
+ ![args['a[0]'], args['t[0]'], args['i[0]'], args['o[0]'], args['l[0]'], args['b[0]']].any?(&:blank?)
206
+ 'OK'
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/../lib/scrobbler'
2
+ require File.dirname(__FILE__) + '/mocks/rest'
3
+
4
+ # To test the 2.0 API, we do not need a valid key but one must be set
5
+ Scrobbler::Base.api_key = 'foo123'
6
+ Scrobbler::Base.secret = 'bar456'
7
+
@@ -0,0 +1,20 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/scrobbler'
3
+ require File.dirname(__FILE__) + '/mocks/rest'
4
+
5
+ # To test the 2.0 API, we do not need a valid key
6
+ Scrobbler::Base.api_key = 'foo123'
7
+
8
+ class << Test::Unit::TestCase
9
+ def test(name, &block)
10
+ test_name = :"test_#{name.gsub(' ','_')}"
11
+ raise ArgumentError, "#{test_name} is already defined" if self.instance_methods.include? test_name.to_s
12
+ define_method test_name, &block
13
+ end
14
+
15
+ def expect(expected_value, &block)
16
+ define_method :"test_#{caller.first.split("/").last}" do
17
+ assert_equal expected_value, instance_eval(&block)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,52 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe Scrobbler::Album do
4
+
5
+ before(:each) do
6
+ @album = Scrobbler::Album.new('Some Hearts', :artist=>'Carrie Underwood')
7
+ end
8
+
9
+ it 'should know the artist' do
10
+ @album.artist.should eql('Carrie Underwood')
11
+ end
12
+
13
+ it "should know it's name" do
14
+ @album.name.should eql('Some Hearts')
15
+ end
16
+
17
+ it "should implement all methods from the Last.fm 2.0 API" do
18
+ @album.should respond_to(:add_tags)
19
+ @album.should respond_to(:load_album_info)
20
+ @album.should respond_to(:load_track_info)
21
+ @album.should respond_to(:tags)
22
+ @album.should respond_to(:remove_tag)
23
+ @album.should respond_to(:search)
24
+ end
25
+
26
+ it 'should be able to add tags'
27
+
28
+ it 'should be able to load album info' do
29
+ @album.load_album_info
30
+
31
+ @album.mbid.should eql('a33b9822-9f09-4e19-9d6e-e05af85c727b')
32
+ @album.url.should eql('http://www.last.fm/music/Carrie+Underwood/Some+Hearts')
33
+ @album.release_date.should eql(Time.mktime(2005, 11, 15, 00, 00, 00))
34
+ @album.image(:small).should eql('http://userserve-ak.last.fm/serve/34s/19874169.jpg')
35
+ @album.image(:medium).should eql('http://userserve-ak.last.fm/serve/64s/19874169.jpg')
36
+ @album.image(:large).should eql('http://userserve-ak.last.fm/serve/174s/19874169.jpg')
37
+ @album.image(:extralarge).should eql('http://userserve-ak.last.fm/serve/300x300/19874169.jpg')
38
+ @album.listeners.should eql(131312)
39
+ @album.playcount.should eql(2096260)
40
+ @album.top_tags.should be_kind_of(Array)
41
+ @album.should have(5).top_tags
42
+ @album.top_tags.first.should be_kind_of(Scrobbler::Tag)
43
+ @album.top_tags.first.name.should eql('country')
44
+ @album.top_tags.first.url.should eql('http://www.last.fm/tag/country')
45
+ end
46
+
47
+ it 'should be able to get the user\'s tags for this album'
48
+
49
+ it 'should be able to remove tags'
50
+
51
+ it 'should be able to search for albums'
52
+ end