dreamwords-oauth2 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gemtest +0 -0
- data/.gitignore +35 -0
- data/.rspec +2 -0
- data/.travis.yml +13 -0
- data/Gemfile +3 -0
- data/LICENSE.md +20 -0
- data/README.md +135 -0
- data/Rakefile +19 -0
- data/lib/oauth2.rb +10 -0
- data/lib/oauth2/access_token.rb +157 -0
- data/lib/oauth2/client.rb +168 -0
- data/lib/oauth2/error.rb +24 -0
- data/lib/oauth2/response.rb +93 -0
- data/lib/oauth2/strategy/assertion.rb +75 -0
- data/lib/oauth2/strategy/auth_code.rb +33 -0
- data/lib/oauth2/strategy/base.rb +16 -0
- data/lib/oauth2/strategy/client_credentials.rb +28 -0
- data/lib/oauth2/strategy/implicit.rb +29 -0
- data/lib/oauth2/strategy/password.rb +27 -0
- data/lib/oauth2/version.rb +18 -0
- data/oauth2.gemspec +27 -0
- data/spec/helper.rb +16 -0
- data/spec/oauth2/access_token_spec.rb +151 -0
- data/spec/oauth2/client_spec.rb +187 -0
- data/spec/oauth2/response_spec.rb +91 -0
- data/spec/oauth2/strategy/assertion_spec.rb +57 -0
- data/spec/oauth2/strategy/auth_code_spec.rb +88 -0
- data/spec/oauth2/strategy/base_spec.rb +7 -0
- data/spec/oauth2/strategy/client_credentials_spec.rb +70 -0
- data/spec/oauth2/strategy/implicit_spec.rb +28 -0
- data/spec/oauth2/strategy/password_spec.rb +57 -0
- metadata +272 -0
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe OAuth2::Client do
|
4
|
+
let!(:error_value) {'invalid_token'}
|
5
|
+
let!(:error_description_value) {'bad bad token'}
|
6
|
+
|
7
|
+
subject do
|
8
|
+
OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
|
9
|
+
builder.adapter :test do |stub|
|
10
|
+
stub.get('/success') {|env| [200, {'Content-Type' => 'text/awesome'}, 'yay']}
|
11
|
+
stub.get('/reflect') {|env| [200, {}, env[:body]]}
|
12
|
+
stub.post('/reflect') {|env| [200, {}, env[:body]]}
|
13
|
+
stub.get('/unauthorized') {|env| [401, {'Content-Type' => 'application/json'}, MultiJson.encode(:error => error_value, :error_description => error_description_value)]}
|
14
|
+
stub.get('/conflict') {|env| [409, {'Content-Type' => 'text/plain'}, 'not authorized']}
|
15
|
+
stub.get('/redirect') {|env| [302, {'Content-Type' => 'text/plain', 'location' => '/success' }, '']}
|
16
|
+
stub.post('/redirect') {|env| [303, {'Content-Type' => 'text/plain', 'location' => '/reflect' }, '']}
|
17
|
+
stub.get('/error') {|env| [500, {'Content-Type' => 'text/plain'}, 'unknown error']}
|
18
|
+
stub.get('/empty_get') {|env| [204, {}, nil]}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#initialize' do
|
24
|
+
it 'should assign id and secret' do
|
25
|
+
subject.id.should == 'abc'
|
26
|
+
subject.secret.should == 'def'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should assign site from the options hash' do
|
30
|
+
subject.site.should == 'https://api.example.com'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should assign Faraday::Connection#host' do
|
34
|
+
subject.connection.host.should == 'api.example.com'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should leave Faraday::Connection#ssl unset' do
|
38
|
+
subject.connection.ssl.should == {}
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should be able to pass a block to configure the connection" do
|
42
|
+
connection = stub('connection')
|
43
|
+
session = stub('session', :to_ary => nil)
|
44
|
+
builder = stub('builder')
|
45
|
+
connection.stub(:build).and_yield(builder)
|
46
|
+
Faraday::Connection.stub(:new => connection)
|
47
|
+
|
48
|
+
builder.should_receive(:adapter).with(:test)
|
49
|
+
|
50
|
+
OAuth2::Client.new('abc', 'def') do |builder|
|
51
|
+
builder.adapter :test
|
52
|
+
end.connection
|
53
|
+
end
|
54
|
+
|
55
|
+
it "defaults raise_errors to true" do
|
56
|
+
subject.options[:raise_errors].should be_true
|
57
|
+
end
|
58
|
+
|
59
|
+
it "allows true/false for raise_errors option" do
|
60
|
+
client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => false)
|
61
|
+
client.options[:raise_errors].should be_false
|
62
|
+
client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => true)
|
63
|
+
client.options[:raise_errors].should be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it "allows get/post for access_token_method option" do
|
67
|
+
client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :get)
|
68
|
+
client.options[:access_token_method].should == :get
|
69
|
+
client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :post)
|
70
|
+
client.options[:access_token_method].should == :post
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
%w(authorize token).each do |url_type|
|
75
|
+
describe ":#{url_type}_url option" do
|
76
|
+
it "should default to a path of /oauth/#{url_type}" do
|
77
|
+
subject.send("#{url_type}_url").should == "https://api.example.com/oauth/#{url_type}"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be settable via the :#{url_type}_url option" do
|
81
|
+
subject.options[:"#{url_type}_url"] = '/oauth/custom'
|
82
|
+
subject.send("#{url_type}_url").should == 'https://api.example.com/oauth/custom'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "allows a different host than the site" do
|
86
|
+
subject.options[:"#{url_type}_url"] = 'https://api.foo.com/oauth/custom'
|
87
|
+
subject.send("#{url_type}_url").should == 'https://api.foo.com/oauth/custom'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#request" do
|
93
|
+
it "works with a null response body" do
|
94
|
+
subject.request(:get, 'empty_get').body.should == ''
|
95
|
+
end
|
96
|
+
|
97
|
+
it "returns on a successful response" do
|
98
|
+
response = subject.request(:get, '/success')
|
99
|
+
response.body.should == 'yay'
|
100
|
+
response.status.should == 200
|
101
|
+
response.headers.should == {'Content-Type' => 'text/awesome'}
|
102
|
+
end
|
103
|
+
|
104
|
+
it "posts a body" do
|
105
|
+
response = subject.request(:post, '/reflect', :body => 'foo=bar')
|
106
|
+
response.body.should == 'foo=bar'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "follows redirects properly" do
|
110
|
+
response = subject.request(:get, '/redirect')
|
111
|
+
response.body.should == 'yay'
|
112
|
+
response.status.should == 200
|
113
|
+
response.headers.should == {'Content-Type' => 'text/awesome'}
|
114
|
+
end
|
115
|
+
|
116
|
+
it "redirects using GET on a 303" do
|
117
|
+
response = subject.request(:post, '/redirect', :body => 'foo=bar')
|
118
|
+
response.body.should be_empty
|
119
|
+
response.status.should == 200
|
120
|
+
end
|
121
|
+
|
122
|
+
it "obeys the :max_redirects option" do
|
123
|
+
max_redirects = subject.options[:max_redirects]
|
124
|
+
subject.options[:max_redirects] = 0
|
125
|
+
response = subject.request(:get, '/redirect')
|
126
|
+
response.status.should == 302
|
127
|
+
subject.options[:max_redirects] = max_redirects
|
128
|
+
end
|
129
|
+
|
130
|
+
it "returns if raise_errors is false" do
|
131
|
+
subject.options[:raise_errors] = false
|
132
|
+
response = subject.request(:get, '/unauthorized')
|
133
|
+
|
134
|
+
response.status.should == 401
|
135
|
+
response.headers.should == {'Content-Type' => 'application/json'}
|
136
|
+
response.error.should_not be_nil
|
137
|
+
end
|
138
|
+
|
139
|
+
%w(/unauthorized /conflict /error).each do |error_path|
|
140
|
+
it "raises OAuth2::Error on error response to path #{error_path}" do
|
141
|
+
lambda {subject.request(:get, error_path)}.should raise_error(OAuth2::Error)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'parses OAuth2 standard error response' do
|
146
|
+
begin
|
147
|
+
subject.request(:get, '/unauthorized')
|
148
|
+
rescue Exception => e
|
149
|
+
e.code.should == error_value
|
150
|
+
e.description.should == error_description_value
|
151
|
+
e.to_s.should match(/#{error_value}/)
|
152
|
+
e.to_s.should match(/#{error_description_value}/)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it "provides the response in the Exception" do
|
157
|
+
begin
|
158
|
+
subject.request(:get, '/error')
|
159
|
+
rescue Exception => e
|
160
|
+
e.response.should_not be_nil
|
161
|
+
e.to_s.should match(/unknown error/)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
it '#auth_code should instantiate a AuthCode strategy with this client' do
|
167
|
+
subject.auth_code.should be_kind_of(OAuth2::Strategy::AuthCode)
|
168
|
+
end
|
169
|
+
|
170
|
+
it '#implicit should instantiate a Implicit strategy with this client' do
|
171
|
+
subject.implicit.should be_kind_of(OAuth2::Strategy::Implicit)
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'with SSL options' do
|
175
|
+
subject do
|
176
|
+
cli = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :ssl => {:ca_file => 'foo.pem'})
|
177
|
+
cli.connection.build do |b|
|
178
|
+
b.adapter :test
|
179
|
+
end
|
180
|
+
cli
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should pass the SSL options along to Faraday::Connection#ssl' do
|
184
|
+
subject.connection.ssl.should == {:ca_file => 'foo.pem'}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe OAuth2::Response do
|
4
|
+
describe '#initialize' do
|
5
|
+
let(:status) {200}
|
6
|
+
let(:headers) {{'foo' => 'bar'}}
|
7
|
+
let(:body) {'foo'}
|
8
|
+
|
9
|
+
it 'returns the status, headers and body' do
|
10
|
+
response = double('response', :headers => headers,
|
11
|
+
:status => status,
|
12
|
+
:body => body)
|
13
|
+
subject = Response.new(response)
|
14
|
+
subject.headers.should == headers
|
15
|
+
subject.status.should == status
|
16
|
+
subject.body.should == body
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.register_parser' do
|
21
|
+
let(:response) {
|
22
|
+
double('response', :headers => {'Content-Type' => 'application/foo-bar'},
|
23
|
+
:status => 200,
|
24
|
+
:body => 'baz')
|
25
|
+
}
|
26
|
+
before do
|
27
|
+
OAuth2::Response.register_parser(:foobar, 'application/foo-bar') do |body|
|
28
|
+
"foobar #{body}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should add to the content types and parsers' do
|
33
|
+
OAuth2::Response::PARSERS.keys.should be_include(:foobar)
|
34
|
+
OAuth2::Response::CONTENT_TYPES.keys.should be_include('application/foo-bar')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should be able to parse that content type automatically' do
|
38
|
+
OAuth2::Response.new(response).parsed.should == 'foobar baz'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#parsed' do
|
43
|
+
it "parses application/x-www-form-urlencoded body" do
|
44
|
+
headers = {'Content-Type' => 'application/x-www-form-urlencoded'}
|
45
|
+
body = 'foo=bar&answer=42'
|
46
|
+
response = double('response', :headers => headers, :body => body)
|
47
|
+
subject = Response.new(response)
|
48
|
+
subject.parsed.keys.size.should == 2
|
49
|
+
subject.parsed['foo'].should == 'bar'
|
50
|
+
subject.parsed['answer'].should == '42'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "parses application/json body" do
|
54
|
+
headers = {'Content-Type' => 'application/json'}
|
55
|
+
body = MultiJson.encode(:foo => 'bar', :answer => 42)
|
56
|
+
response = double('response', :headers => headers, :body => body)
|
57
|
+
subject = Response.new(response)
|
58
|
+
subject.parsed.keys.size.should == 2
|
59
|
+
subject.parsed['foo'].should == 'bar'
|
60
|
+
subject.parsed['answer'].should == 42
|
61
|
+
end
|
62
|
+
|
63
|
+
it "doesn't try to parse other content-types" do
|
64
|
+
headers = {'Content-Type' => 'text/html'}
|
65
|
+
body = '<!DOCTYPE html><html><head></head><body></body></html>'
|
66
|
+
|
67
|
+
response = double('response', :headers => headers, :body => body)
|
68
|
+
|
69
|
+
MultiJson.should_not_receive(:decode)
|
70
|
+
MultiJson.should_not_receive(:load)
|
71
|
+
Rack::Utils.should_not_receive(:parse_query)
|
72
|
+
|
73
|
+
subject = Response.new(response)
|
74
|
+
subject.parsed.should be_nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'xml parser registration' do
|
79
|
+
it 'should try to load multi_xml and use it' do
|
80
|
+
OAuth2::Response::PARSERS[:xml].should_not be_nil
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should be able to parse xml' do
|
84
|
+
headers = {'Content-Type' => 'text/xml'}
|
85
|
+
body = '<?xml version="1.0" standalone="yes" ?><foo><bar>baz</bar></foo>'
|
86
|
+
|
87
|
+
response = double('response', :headers => headers, :body => body)
|
88
|
+
OAuth2::Response.new(response).parsed.should == {"foo" => {"bar" => "baz"}}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe OAuth2::Strategy::Assertion do
|
4
|
+
let(:client) do
|
5
|
+
cli = OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com')
|
6
|
+
cli.connection.build do |b|
|
7
|
+
b.adapter :test do |stub|
|
8
|
+
stub.post('/oauth/token') do |env|
|
9
|
+
case @mode
|
10
|
+
when "formencoded"
|
11
|
+
[200, {'Content-Type' => 'application/x-www-form-urlencoded'}, 'expires_in=600&access_token=salmon&refresh_token=trout']
|
12
|
+
when "json"
|
13
|
+
[200, {'Content-Type' => 'application/json'}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
cli
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:params) { {:hmac_secret => 'foo'}}
|
22
|
+
|
23
|
+
subject {client.assertion}
|
24
|
+
|
25
|
+
describe "#authorize_url" do
|
26
|
+
it "should raise NotImplementedError" do
|
27
|
+
lambda {subject.authorize_url}.should raise_error(NotImplementedError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
%w(json formencoded).each do |mode|
|
32
|
+
describe "#get_token (#{mode})" do
|
33
|
+
before do
|
34
|
+
@mode = mode
|
35
|
+
@access = subject.get_token(params)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns AccessToken with same Client' do
|
39
|
+
@access.client.should == client
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns AccessToken with #token' do
|
43
|
+
@access.token.should == 'salmon'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns AccessToken with #expires_in' do
|
47
|
+
@access.expires_in.should == 600
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns AccessToken with #expires_at' do
|
51
|
+
@access.expires_at.should_not be_nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe OAuth2::Strategy::AuthCode do
|
4
|
+
let(:code) {'sushi'}
|
5
|
+
let(:kvform_token) {'expires_in=600&access_token=salmon&refresh_token=trout&extra_param=steve'}
|
6
|
+
let(:facebook_token) {kvform_token.gsub('_in', '')}
|
7
|
+
let(:json_token) {MultiJson.encode(:expires_in => 600, :access_token => 'salmon', :refresh_token => 'trout', :extra_param => 'steve')}
|
8
|
+
|
9
|
+
let(:client) do
|
10
|
+
OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') do |builder|
|
11
|
+
builder.adapter :test do |stub|
|
12
|
+
stub.get("/oauth/token?client_id=abc&client_secret=def&code=#{code}&grant_type=authorization_code") do |env|
|
13
|
+
case @mode
|
14
|
+
when "formencoded"
|
15
|
+
[200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]
|
16
|
+
when "json"
|
17
|
+
[200, {'Content-Type' => 'application/json'}, json_token]
|
18
|
+
when "from_facebook"
|
19
|
+
[200, {'Content-Type' => 'application/x-www-form-urlencoded'}, facebook_token]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
stub.post('/oauth/token', {'client_id' => 'abc', 'client_secret' => 'def', 'code' => 'sushi', 'grant_type' => 'authorization_code'}) do |env|
|
23
|
+
case @mode
|
24
|
+
when "formencoded"
|
25
|
+
[200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]
|
26
|
+
when "json"
|
27
|
+
[200, {'Content-Type' => 'application/json'}, json_token]
|
28
|
+
when "from_facebook"
|
29
|
+
[200, {'Content-Type' => 'application/x-www-form-urlencoded'}, facebook_token]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
subject {client.auth_code}
|
37
|
+
|
38
|
+
describe '#authorize_url' do
|
39
|
+
it 'should include the client_id' do
|
40
|
+
subject.authorize_url.should be_include('client_id=abc')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should include the type' do
|
44
|
+
subject.authorize_url.should be_include('response_type=code')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should include passed in options' do
|
48
|
+
cb = 'http://myserver.local/oauth/callback'
|
49
|
+
subject.authorize_url(:redirect_uri => cb).should be_include("redirect_uri=#{Rack::Utils.escape(cb)}")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
%w(json formencoded from_facebook).each do |mode|
|
54
|
+
[:get, :post].each do |verb|
|
55
|
+
describe "#get_token (#{mode}, access_token_method=#{verb}" do
|
56
|
+
before :each do
|
57
|
+
@mode = mode
|
58
|
+
client.options[:token_method] = verb
|
59
|
+
@access = subject.get_token(code)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns AccessToken with same Client' do
|
63
|
+
@access.client.should == client
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'returns AccessToken with #token' do
|
67
|
+
@access.token.should == 'salmon'
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns AccessToken with #refresh_token' do
|
71
|
+
@access.refresh_token.should == 'trout'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'returns AccessToken with #expires_in' do
|
75
|
+
@access.expires_in.should == 600
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns AccessToken with #expires_at' do
|
79
|
+
@access.expires_at.should be_kind_of(Integer)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns AccessToken with params accessible via []' do
|
83
|
+
@access['extra_param'].should == 'steve'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe OAuth2::Strategy::ClientCredentials do
|
4
|
+
let(:kvform_token) { 'expires_in=600&access_token=salmon&refresh_token=trout' }
|
5
|
+
let(:json_token) { '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}' }
|
6
|
+
|
7
|
+
let(:client) do
|
8
|
+
OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') do |builder|
|
9
|
+
builder.adapter :test do |stub|
|
10
|
+
stub.post('/oauth/token', {'grant_type' => 'client_credentials'}) do |env|
|
11
|
+
client_id, client_secret = HTTPAuth::Basic.unpack_authorization(env[:request_headers]['Authorization'])
|
12
|
+
client_id == 'abc' && client_secret == 'def' or raise Faraday::Adapter::Test::Stubs::NotFound.new
|
13
|
+
case @mode
|
14
|
+
when "formencoded"
|
15
|
+
[200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]
|
16
|
+
when "json"
|
17
|
+
[200, {'Content-Type' => 'application/json'}, json_token]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
stub.post('/oauth/token', {'client_id' => 'abc', 'client_secret' => 'def', 'grant_type' => 'client_credentials'}) do |env|
|
21
|
+
case @mode
|
22
|
+
when "formencoded"
|
23
|
+
[200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]
|
24
|
+
when "json"
|
25
|
+
[200, {'Content-Type' => 'application/json'}, json_token]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
subject {client.client_credentials}
|
33
|
+
|
34
|
+
describe "#authorize_url" do
|
35
|
+
it "should raise NotImplementedError" do
|
36
|
+
lambda {subject.authorize_url}.should raise_error(NotImplementedError)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
%w(json formencoded).each do |mode|
|
41
|
+
%w(default basic_auth request_body).each do |auth_scheme|
|
42
|
+
describe "#get_token (#{mode}) (#{auth_scheme})" do
|
43
|
+
before do
|
44
|
+
@mode = mode
|
45
|
+
@access = subject.get_token({}, auth_scheme == 'default' ? {} : {'auth_scheme' => auth_scheme})
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns AccessToken with same Client' do
|
49
|
+
@access.client.should == client
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'returns AccessToken with #token' do
|
53
|
+
@access.token.should == 'salmon'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'returns AccessToken without #refresh_token' do
|
57
|
+
@access.refresh_token.should be_nil
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns AccessToken with #expires_in' do
|
61
|
+
@access.expires_in.should == 600
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns AccessToken with #expires_at' do
|
65
|
+
@access.expires_at.should_not be_nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|