From 8a7db9cb900253a9cd5b7cdbfc103dd13a627d42 Mon Sep 17 00:00:00 2001 From: youpy Date: Mon, 11 Jan 2010 15:08:17 +0900 Subject: [PATCH] add Lastfm::MethodCategory#request_for_authentication, Lastfm::MethodCategory#request_with_authentication --- lib/lastfm.rb | 22 ++++++--- lib/lastfm/method_category.rb | 8 +++ lib/lastfm/method_category/auth.rb | 4 +- lib/lastfm/method_category/track.rb | 5 +- spec/lastfm_spec.rb | 75 ++++++++++++++++++++++++++--- 5 files changed, 93 insertions(+), 21 deletions(-) diff --git a/lib/lastfm.rb b/lib/lastfm.rb index 44fa84c..bd67a22 100644 --- a/lib/lastfm.rb +++ b/lib/lastfm.rb @@ -32,26 +32,32 @@ def track Track.new(self) end - def request(method, params = {}, http_method = :get) + def request(method, params = {}, http_method = :get, with_signature = false, with_session = false) params[:method] = method params[:api_key] = @api_key # http://www.lastfm.jp/group/Last.fm+Web+Services/forum/21604/_/497978 #params[:format] = format - sig = params.to_a.sort_by do |param| - param.first.to_s - end.inject('') do |result, param| - result + param.join('') - end + @api_secret + params.update(:sk => @session) if with_session + params.update(:api_sig => Digest::MD5.hexdigest(build_method_signature(params))) if with_signature + params.update(:format => 'json') - params.update(:api_sig => Digest::MD5.hexdigest(sig), :format => 'json') response = Response.new(self.class.send(http_method, '/', (http_method == :post ? :body : :query) => params).body) - unless response.success? raise ApiError.new(response.message) end response end + + private + + def build_method_signature(params) + params.to_a.sort_by do |param| + param.first.to_s + end.inject('') do |result, param| + result + param.join('') + end + @api_secret + end end diff --git a/lib/lastfm/method_category.rb b/lib/lastfm/method_category.rb index 7c7aa00..ad9b614 100644 --- a/lib/lastfm/method_category.rb +++ b/lib/lastfm/method_category.rb @@ -4,6 +4,14 @@ def initialize(lastfm) @lastfm = lastfm end + def request_with_authentication(method, params = {}) + request(method, params, :post, true, true) + end + + def request_for_authentication(method, params = {}) + request(method, params, :get, true) + end + def request(*args) method, *rest = args method = [self.class.name.split(/::/).last.downcase, method].join('.') diff --git a/lib/lastfm/method_category/auth.rb b/lib/lastfm/method_category/auth.rb index 2fcb8e7..be868c7 100644 --- a/lib/lastfm/method_category/auth.rb +++ b/lib/lastfm/method_category/auth.rb @@ -1,11 +1,11 @@ class Lastfm class Auth < MethodCategory def get_token - request('getToken')['token'] + request_for_authentication('getToken')['token'] end def get_session(token) - request('getSession', { :token => token })['session']['key'] + request_for_authentication('getSession', { :token => token })['session']['key'] end end end diff --git a/lib/lastfm/method_category/track.rb b/lib/lastfm/method_category/track.rb index 811fd65..ae5dfd9 100644 --- a/lib/lastfm/method_category/track.rb +++ b/lib/lastfm/method_category/track.rb @@ -1,11 +1,10 @@ class Lastfm class Track < MethodCategory def love(artist, track) - request('love', { + request_with_authentication('love', { :artist => artist, :track => track, - :sk => @lastfm.session - }, :post) + }) end end end diff --git a/spec/lastfm_spec.rb b/spec/lastfm_spec.rb index 11a4f63..561db60 100644 --- a/spec/lastfm_spec.rb +++ b/spec/lastfm_spec.rb @@ -16,7 +16,19 @@ end describe '#request' do - it 'should do post request' do + it 'should post' do + mock_response = mock(HTTParty::Response) + @lastfm.class.should_receive(:post).with('/', :body => { + :foo => 'bar', + :method => 'xxx.yyy', + :api_key => 'xxx', + :format => 'json' + }).and_return(mock_response) + mock_response.should_receive(:body).and_return('{ "bar": "baz" }') + @lastfm.request('xxx.yyy', { :foo => 'bar' }, :post, false, false)['bar'].should eql('baz') + end + + it 'should post with signature' do mock_response = mock(HTTParty::Response) @lastfm.class.should_receive(:post).with('/', :body => { :foo => 'bar', @@ -26,10 +38,39 @@ :format => 'json' }).and_return(mock_response) mock_response.should_receive(:body).and_return('{ "bar": "baz" }') - @lastfm.request('xxx.yyy', { :foo => 'bar' }, :post)['bar'].should eql('baz') + @lastfm.request('xxx.yyy', { :foo => 'bar' }, :post, true, false)['bar'].should eql('baz') + end + + it 'should post with signature and session (request with authentication)' do + mock_response = mock(HTTParty::Response) + @lastfm.session = 'abcdef' + @lastfm.class.should_receive(:post).with('/', :body => { + :foo => 'bar', + :method => 'xxx.yyy', + :api_key => 'xxx', + :api_sig => Digest::MD5.hexdigest('api_keyxxxfoobarmethodxxx.yyyskabcdefyyy'), + :sk => 'abcdef', + :format => 'json' + }).and_return(mock_response) + mock_response.should_receive(:body).and_return('{ "bar": "baz" }') + + @lastfm.request('xxx.yyy', { :foo => 'bar' }, :post, true, true)['bar'].should eql('baz') end - it 'should do get request' do + it 'should get' do + mock_response = mock(HTTParty::Response) + @lastfm.class.should_receive(:get).with('/', :query => { + :foo => 'bar', + :method => 'xxx.yyy', + :api_key => 'xxx', + :format => 'json' + }).and_return(mock_response) + mock_response.should_receive(:body).and_return('{ "bar": "baz" }') + + @lastfm.request('xxx.yyy', { :foo => 'bar' }, :get, false, false)['bar'].should eql('baz') + end + + it 'should get with signature (request for authentication)' do mock_response = mock(HTTParty::Response) @lastfm.class.should_receive(:get).with('/', :query => { :foo => 'bar', @@ -39,7 +80,24 @@ :format => 'json' }).and_return(mock_response) mock_response.should_receive(:body).and_return('{ "bar": "baz" }') - @lastfm.request('xxx.yyy', { :foo => 'bar' }, :get)['bar'].should eql('baz') + + @lastfm.request('xxx.yyy', { :foo => 'bar' }, :get, true, false)['bar'].should eql('baz') + end + + it 'should get with signature and session' do + mock_response = mock(HTTParty::Response) + @lastfm.session = 'abcdef' + @lastfm.class.should_receive(:get).with('/', :query => { + :foo => 'bar', + :method => 'xxx.yyy', + :api_key => 'xxx', + :api_sig => Digest::MD5.hexdigest('api_keyxxxfoobarmethodxxx.yyyskabcdefyyy'), + :sk => 'abcdef', + :format => 'json' + }).and_return(mock_response) + mock_response.should_receive(:body).and_return('{ "bar": "baz" }') + + @lastfm.request('xxx.yyy', { :foo => 'bar' }, :get, true, true)['bar'].should eql('baz') end it 'should raise an error if an api error is ocuured' do @@ -59,13 +117,15 @@ end it 'should get token' do - @lastfm.should_receive(:request).with('auth.getToken').and_return({ 'token' => 'xxxyyyzzz' }) + @lastfm.should_receive(:request). + with('auth.getToken', {}, :get, true). + and_return({ 'token' => 'xxxyyyzzz' }) @lastfm.auth.get_token.should eql('xxxyyyzzz') end it 'should get session' do @lastfm.should_receive(:request). - with('auth.getSession', { :token => 'xxxyyyzzz' }). + with('auth.getSession', { :token => 'xxxyyyzzz' }, :get, true). and_return({ 'session' => { 'key' => 'zzzyyyxxx' }}) @lastfm.auth.get_session('xxxyyyzzz').should eql('zzzyyyxxx') end @@ -81,8 +141,7 @@ @lastfm.should_receive(:request).with('track.love', { :artist => 'foo artist', :track => 'foo track', - :sk => 'abcdef' - }, :post).and_return({ 'status' => 'ok' }) + }, :post, true, true).and_return({}) @lastfm.track.love('foo artist', 'foo track') end