millsb-twitter-auth 0.1.16
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/README.markdown +96 -0
- data/Rakefile +31 -0
- data/VERSION.yml +4 -0
- data/app/controllers/sessions_controller.rb +64 -0
- data/app/models/twitter_auth/basic_user.rb +63 -0
- data/app/models/twitter_auth/generic_user.rb +93 -0
- data/app/models/twitter_auth/oauth_user.rb +43 -0
- data/app/views/sessions/_login_form.html.erb +17 -0
- data/app/views/sessions/new.html.erb +5 -0
- data/config/routes.rb +6 -0
- data/generators/twitter_auth/USAGE +12 -0
- data/generators/twitter_auth/templates/migration.rb +48 -0
- data/generators/twitter_auth/templates/twitter_auth.yml +44 -0
- data/generators/twitter_auth/templates/user.rb +5 -0
- data/generators/twitter_auth/twitter_auth_generator.rb +34 -0
- data/lib/twitter_auth.rb +87 -0
- data/lib/twitter_auth/controller_extensions.rb +65 -0
- data/lib/twitter_auth/cryptify.rb +30 -0
- data/lib/twitter_auth/dispatcher/basic.rb +46 -0
- data/lib/twitter_auth/dispatcher/oauth.rb +26 -0
- data/lib/twitter_auth/dispatcher/shared.rb +40 -0
- data/rails/init.rb +8 -0
- data/spec/controllers/controller_extensions_spec.rb +162 -0
- data/spec/controllers/sessions_controller_spec.rb +221 -0
- data/spec/fixtures/config/twitter_auth.yml +17 -0
- data/spec/fixtures/factories.rb +18 -0
- data/spec/fixtures/fakeweb.rb +18 -0
- data/spec/fixtures/twitter.rb +5 -0
- data/spec/models/twitter_auth/basic_user_spec.rb +122 -0
- data/spec/models/twitter_auth/generic_user_spec.rb +142 -0
- data/spec/models/twitter_auth/oauth_user_spec.rb +94 -0
- data/spec/schema.rb +41 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/twitter_auth/cryptify_spec.rb +51 -0
- data/spec/twitter_auth/dispatcher/basic_spec.rb +83 -0
- data/spec/twitter_auth/dispatcher/oauth_spec.rb +72 -0
- data/spec/twitter_auth/dispatcher/shared_spec.rb +26 -0
- data/spec/twitter_auth_spec.rb +154 -0
- metadata +127 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
ActionController::Routing::Routes.draw do |map|
|
4
|
+
map.connect ':controller/:action/:id'
|
5
|
+
end
|
6
|
+
|
7
|
+
class TwitterAuthTestController < ApplicationController
|
8
|
+
before_filter :login_required, :only => [:login_required_action]
|
9
|
+
|
10
|
+
def login_required_action
|
11
|
+
render :text => "You are logged in!"
|
12
|
+
end
|
13
|
+
|
14
|
+
def fail_auth
|
15
|
+
authentication_failed('Auth FAIL.')
|
16
|
+
end
|
17
|
+
|
18
|
+
def pass_auth
|
19
|
+
if params[:message]
|
20
|
+
authentication_succeeded(params[:message])
|
21
|
+
else
|
22
|
+
authentication_succeeded
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def access_denied_action
|
27
|
+
access_denied
|
28
|
+
end
|
29
|
+
|
30
|
+
def redirect_back_action
|
31
|
+
redirect_back_or_default(params[:to] || '/')
|
32
|
+
end
|
33
|
+
|
34
|
+
def logout_keeping_session_action
|
35
|
+
logout_keeping_session!
|
36
|
+
redirect_back_or_default('/')
|
37
|
+
end
|
38
|
+
|
39
|
+
def current_user_action
|
40
|
+
@user = current_user
|
41
|
+
render :nothing => true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe TwitterAuthTestController do
|
46
|
+
before do
|
47
|
+
controller.stub!(:cookies).and_return({})
|
48
|
+
end
|
49
|
+
|
50
|
+
%w(authentication_failed authentication_succeeded current_user authorized? login_required access_denied store_location redirect_back_or_default logout_keeping_session!).each do |m|
|
51
|
+
it "should respond to the extension method '#{m}'" do
|
52
|
+
controller.should respond_to(m)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#authentication_failed" do
|
57
|
+
it 'should set the flash[:error] to the message passed in' do
|
58
|
+
get :fail_auth
|
59
|
+
flash[:error].should == 'Auth FAIL.'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should redirect to the root' do
|
63
|
+
get :fail_auth
|
64
|
+
should redirect_to('/')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#authentication_succeeded" do
|
69
|
+
it 'should set the flash[:notice] to a default success message' do
|
70
|
+
get :pass_auth
|
71
|
+
flash[:notice].should == 'You have logged in successfully.'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should be able ot receive a custom message' do
|
75
|
+
get :pass_auth, :message => 'Eat at Joes.'
|
76
|
+
flash[:notice].should == 'Eat at Joes.'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#current_user' do
|
81
|
+
it 'should find the user based on the session user_id' do
|
82
|
+
user = Factory.create(:twitter_oauth_user)
|
83
|
+
request.session[:user_id] = user.id
|
84
|
+
get(:current_user_action)
|
85
|
+
assigns[:user].should == user
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should log the user in through a cookie' do
|
89
|
+
user = Factory(:twitter_oauth_user, :remember_token => 'abc', :remember_token_expires_at => (Time.now + 10.days))
|
90
|
+
controller.stub!(:cookies).and_return({:remember_token => 'abc'})
|
91
|
+
get :current_user_action
|
92
|
+
assigns[:user].should == user
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should return nil if there is no user matching that id' do
|
96
|
+
request.session[:user_id] = 2345
|
97
|
+
get :current_user_action
|
98
|
+
assigns[:user].should be_nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#authorized?" do
|
103
|
+
it 'should be true if there is a current_user' do
|
104
|
+
user = Factory.create(:twitter_oauth_user)
|
105
|
+
controller.stub!(:current_user).and_return(user)
|
106
|
+
controller.send(:authorized?).should be_true
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should be false if there is not current_user' do
|
110
|
+
controller.stub!(:current_user).and_return(nil)
|
111
|
+
controller.send(:authorized?).should be_false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#access_denied' do
|
116
|
+
it 'should redirect to the login path' do
|
117
|
+
get :access_denied_action
|
118
|
+
should redirect_to(login_path)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should store the location first' do
|
122
|
+
controller.should_receive(:store_location).once
|
123
|
+
get :access_denied_action
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '#redirect_back_or_default' do
|
128
|
+
it 'should redirect if there is a session[:return_to]' do
|
129
|
+
request.session[:return_to] = '/'
|
130
|
+
get :redirect_back_action, :to => '/notroot'
|
131
|
+
should redirect_to('/')
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should redirect to the default provided otherwise' do
|
135
|
+
get :redirect_back_action, :to => '/someurl'
|
136
|
+
should redirect_to('/someurl')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'logout_keeping_session!' do
|
141
|
+
before do
|
142
|
+
@user = Factory.create(:twitter_oauth_user)
|
143
|
+
request.session[:user_id] = @user.id
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should unset session[:user_id]' do
|
147
|
+
get :logout_keeping_session_action
|
148
|
+
request.session[:user_id].should be_nil
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should unset current_user' do
|
152
|
+
controller.send(:current_user).should == @user
|
153
|
+
get :logout_keeping_session_action
|
154
|
+
controller.send(:current_user).should be_nil
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should unset the cookie' do
|
158
|
+
controller.send(:cookies).should_receive(:delete).with(:remember_token)
|
159
|
+
get :logout_keeping_session_action
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe SessionsController do
|
4
|
+
integrate_views
|
5
|
+
|
6
|
+
describe 'routes' do
|
7
|
+
it 'should route /session/new to SessionsController#new' do
|
8
|
+
params_from(:get, '/session/new').should == {:controller => 'sessions', :action => 'new'}
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should route /login to SessionsController#new' do
|
12
|
+
params_from(:get, '/login').should == {:controller => 'sessions', :action => 'new'}
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should route /logout to SessionsController#destroy' do
|
16
|
+
params_from(:get, '/logout').should == {:controller => 'sessions', :action => 'destroy'}
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should route DELETE /session to SessionsController#destroy' do
|
20
|
+
params_from(:delete, '/session').should == {:controller => 'sessions', :action => 'destroy'}
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should route /oauth_callback to SessionsController#oauth_callback' do
|
24
|
+
params_from(:get, '/oauth_callback').should == {:controller => 'sessions', :action => 'oauth_callback'}
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should route POST /session to SessionsController#create' do
|
28
|
+
params_from(:post, '/session').should == {:controller => 'sessions', :action => 'create'}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'with OAuth strategy' do
|
33
|
+
before do
|
34
|
+
stub_oauth!
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#new' do
|
38
|
+
it 'should retrieve a request token' do
|
39
|
+
get :new
|
40
|
+
assigns[:request_token].token.should == 'faketoken'
|
41
|
+
assigns[:request_token].secret.should == 'faketokensecret'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should set session variables for the request token' do
|
45
|
+
get :new
|
46
|
+
session[:request_token].should == 'faketoken'
|
47
|
+
session[:request_token_secret].should == 'faketokensecret'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should redirect to the oauth authorization url' do
|
51
|
+
get :new
|
52
|
+
response.should redirect_to('https://twitter.com/oauth/authorize?oauth_token=faketoken')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should redirect to the oauth_callback if one is specified' do
|
56
|
+
TwitterAuth.stub!(:oauth_callback).and_return('http://localhost:3000/development')
|
57
|
+
TwitterAuth.stub!(:oauth_callback?).and_return(true)
|
58
|
+
|
59
|
+
get :new
|
60
|
+
response.should redirect_to('https://twitter.com/oauth/authorize?oauth_token=faketoken&oauth_callback=' + CGI.escape(TwitterAuth.oauth_callback))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#oauth_callback' do
|
65
|
+
describe 'with no session info' do
|
66
|
+
it 'should set the flash[:error]' do
|
67
|
+
get :oauth_callback, :oauth_token => 'faketoken'
|
68
|
+
flash[:error].should == 'No authentication information was found in the session. Please try again.'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should redirect to "/" by default' do
|
72
|
+
get :oauth_callback, :oauth_token => 'faketoken'
|
73
|
+
response.should redirect_to('/')
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should call authentication_failed' do
|
77
|
+
controller.should_receive(:authentication_failed).any_number_of_times
|
78
|
+
get :oauth_callback, :oauth_token => 'faketoken'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'with proper info' do
|
83
|
+
before do
|
84
|
+
@user = Factory.create(:twitter_oauth_user)
|
85
|
+
@time = Time.now
|
86
|
+
@remember_token = ActiveSupport::SecureRandom.hex(10)
|
87
|
+
|
88
|
+
Time.stub!(:now).and_return(@time)
|
89
|
+
ActiveSupport::SecureRandom.stub!(:hex).and_return(@remember_token)
|
90
|
+
|
91
|
+
request.session[:request_token] = 'faketoken'
|
92
|
+
request.session[:request_token_secret] = 'faketokensecret'
|
93
|
+
get :oauth_callback, :oauth_token => 'faketoken'
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'building the access token' do
|
97
|
+
it 'should rebuild the request token' do
|
98
|
+
correct_token = OAuth::RequestToken.new(TwitterAuth.consumer,'faketoken','faketokensecret')
|
99
|
+
|
100
|
+
%w(token secret).each do |att|
|
101
|
+
assigns[:request_token].send(att).should == correct_token.send(att)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should exchange the request token for an access token' do
|
106
|
+
assigns[:access_token].should be_a(OAuth::AccessToken)
|
107
|
+
assigns[:access_token].token.should == 'fakeaccesstoken'
|
108
|
+
assigns[:access_token].secret.should == 'fakeaccesstokensecret'
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should wipe the request token after exchange' do
|
112
|
+
session[:request_token].should be_nil
|
113
|
+
session[:request_token_secret].should be_nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe 'identifying the user' do
|
118
|
+
it "should find the user" do
|
119
|
+
assigns[:user].should == @user
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should assign the user id to the session" do
|
123
|
+
session[:user_id].should == @user.id
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should call remember me" do
|
127
|
+
@user.reload
|
128
|
+
@user.remember_token.should == @remember_token
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should set a cookie" do
|
132
|
+
cookies[:remember_token].should == @remember_token
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "when OAuth doesn't work" do
|
137
|
+
before do
|
138
|
+
request.session[:request_token] = 'faketoken'
|
139
|
+
request.session[:request_token_secret] = 'faketokensecret'
|
140
|
+
@request_token = OAuth::RequestToken.new(TwitterAuth.consumer, session[:request_token], session[:request_token_secret])
|
141
|
+
OAuth::RequestToken.stub!(:new).and_return(@request_token)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should call authentication_failed when it gets a 401 from OAuth' do
|
145
|
+
@request_token.stub!(:get_access_token).and_raise(Net::HTTPServerException.new('401 "Unauthorized"', '401 "Unauthorized"'))
|
146
|
+
controller.should_receive(:authentication_failed).with('This authentication request is no longer valid. Please try again.')
|
147
|
+
# the should raise_error is hacky because of the expectation
|
148
|
+
# stubbing the proper behavior :-(
|
149
|
+
lambda{get :oauth_callback, :oauth_token => 'faketoken'}.should raise_error(ActionView::MissingTemplate)
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should call authentication_failed when it gets a different HTTPServerException' do
|
153
|
+
@request_token.stub!(:get_access_token).and_raise(Net::HTTPServerException.new('404 "Not Found"', '404 "Not Found"'))
|
154
|
+
controller.should_receive(:authentication_failed).with('There was a problem trying to authenticate you. Please try again.')
|
155
|
+
lambda{get :oauth_callback, :oauth_token => 'faketoken'}.should raise_error(ActionView::MissingTemplate)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe 'with Basic strategy' do
|
163
|
+
before do
|
164
|
+
stub_basic!
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '#new' do
|
168
|
+
it 'should render the new action' do
|
169
|
+
get :new
|
170
|
+
response.should render_template('sessions/new')
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should render the login form' do
|
174
|
+
get :new
|
175
|
+
response.should have_tag('form[action=/session][id=login_form][method=post]')
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '#create' do
|
179
|
+
before do
|
180
|
+
@user = Factory.create(:twitter_basic_user)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should call logout_keeping_session! to remove session info' do
|
184
|
+
controller.should_receive(:logout_keeping_session!)
|
185
|
+
post :create
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should try to authenticate the user' do
|
189
|
+
User.should_receive(:authenticate)
|
190
|
+
post :create
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should call authentication_failed on authenticate failure' do
|
194
|
+
User.should_receive(:authenticate).and_return(nil)
|
195
|
+
post :create, :login => 'wrong', :password => 'false'
|
196
|
+
response.should redirect_to('/login')
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should call authentication_succeeded on authentication success' do
|
200
|
+
User.should_receive(:authenticate).and_return(@user)
|
201
|
+
post :create, :login => 'twitterman', :password => 'cool'
|
202
|
+
response.should redirect_to('/')
|
203
|
+
flash[:notice].should_not be_blank
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
describe '#destroy' do
|
211
|
+
it 'should call logout_keeping_session!' do
|
212
|
+
controller.should_receive(:logout_keeping_session!).once
|
213
|
+
get :destroy
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should redirect to the root' do
|
217
|
+
get :destroy
|
218
|
+
response.should redirect_to('/')
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
development:
|
2
|
+
strategy: oauth
|
3
|
+
base_url: "https://twitter.com"
|
4
|
+
oauth_consumer_key: devkey
|
5
|
+
oauth_consumer_secret: devsecret
|
6
|
+
oauth_callback: "http://localhost:3000"
|
7
|
+
test:
|
8
|
+
strategy: oauth
|
9
|
+
base_url: "https://twitter.com"
|
10
|
+
oauth_consumer_key: testkey
|
11
|
+
oauth_consumer_secret: testsecret
|
12
|
+
production:
|
13
|
+
strategy: oauth
|
14
|
+
base_url: "https://twitter.com"
|
15
|
+
oauth_consumer_key: prodkey
|
16
|
+
oauth_consumer_secret: prodsecret
|
17
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'factory_girl'
|
2
|
+
|
3
|
+
Factory.define(:twitter_oauth_user, :class => User) do |u|
|
4
|
+
u.login 'twitterman'
|
5
|
+
u.access_token 'fakeaccesstoken'
|
6
|
+
u.access_secret 'fakeaccesstokensecret'
|
7
|
+
|
8
|
+
u.name 'Twitter Man'
|
9
|
+
u.description 'Saving the world for all Twitter kind.'
|
10
|
+
end
|
11
|
+
|
12
|
+
Factory.define(:twitter_basic_user, :class => User) do |u|
|
13
|
+
u.login 'twitterman'
|
14
|
+
u.password 'test'
|
15
|
+
|
16
|
+
u.name 'Twitter Man'
|
17
|
+
u.description 'Saving the world for all Twitter kind.'
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# This is where we fake out all of the URLs that we
|
2
|
+
# will be calling as a part of this spec suite.
|
3
|
+
# You must have the 'fakeweb' gem in order to run
|
4
|
+
# the tests for TwitterAuth.
|
5
|
+
#
|
6
|
+
# gem install 'mbleigh-fakeweb'
|
7
|
+
|
8
|
+
require 'fake_web'
|
9
|
+
|
10
|
+
FakeWeb.allow_net_connect = false
|
11
|
+
|
12
|
+
FakeWeb.register_uri(:post, 'https://twitter.com:443/oauth/request_token', :string => 'oauth_token=faketoken&oauth_token_secret=faketokensecret')
|
13
|
+
|
14
|
+
FakeWeb.register_uri(:post, 'https://twitter.com:443/oauth/access_token', :string => 'oauth_token=fakeaccesstoken&oauth_token_secret=fakeaccesstokensecret')
|
15
|
+
|
16
|
+
FakeWeb.register_uri(:get, 'https://twitter.com:443/account/verify_credentials.json', :string => "{\"profile_image_url\":\"http:\\/\\/static.twitter.com\\/images\\/default_profile_normal.png\",\"description\":\"Saving the world for all Twitter kind.\",\"utc_offset\":null,\"favourites_count\":0,\"profile_sidebar_fill_color\":\"e0ff92\",\"screen_name\":\"twitterman\",\"statuses_count\":0,\"profile_background_tile\":false,\"profile_sidebar_border_color\":\"87bc44\",\"friends_count\":2,\"url\":null,\"name\":\"Twitter Man\",\"time_zone\":null,\"protected\":false,\"profile_background_image_url\":\"http:\\/\\/static.twitter.com\\/images\\/themes\\/theme1\\/bg.gif\",\"profile_background_color\":\"9ae4e8\",\"created_at\":\"Fri Feb 06 18:10:32 +0000 2009\",\"profile_text_color\":\"000000\",\"followers_count\":2,\"location\":null,\"id\":20256865,\"profile_link_color\":\"0000ff\"}")
|
17
|
+
|
18
|
+
#FakeWeb.register_uri(:get, 'https://twitter.com:443/)
|
@@ -0,0 +1,5 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
TWITTER_JSON = {
|
4
|
+
:verify_credentials => "{\"profile_image_url\":\"http:\\/\\/static.twitter.com\\/images\\/default_profile_normal.png\",\"description\":\"Saving the world for all Twitter kind.\",\"utc_offset\":null,\"favourites_count\":0,\"profile_sidebar_fill_color\":\"e0ff92\",\"screen_name\":\"twitterman\",\"statuses_count\":0,\"profile_background_tile\":false,\"profile_sidebar_border_color\":\"87bc44\",\"friends_count\":2,\"url\":null,\"name\":\"Twitter Man\",\"time_zone\":null,\"protected\":false,\"profile_background_image_url\":\"http:\\/\\/static.twitter.com\\/images\\/themes\\/theme1\\/bg.gif\",\"profile_background_color\":\"9ae4e8\",\"created_at\":\"Fri Feb 06 18:10:32 +0000 2009\",\"profile_text_color\":\"000000\",\"followers_count\":2,\"location\":null,\"id\":20256865,\"profile_link_color\":\"0000ff\"}"
|
5
|
+
}
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe TwitterAuth::BasicUser do
|
4
|
+
before do
|
5
|
+
stub_basic!
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#password=' do
|
9
|
+
before do
|
10
|
+
@user = Factory.build(:twitter_basic_user)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should change the value of crypted_password' do
|
14
|
+
lambda{@user.password = 'newpass'}.should change(@user, :crypted_password)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should change the value of salt' do
|
18
|
+
lambda{@user.password = 'newpass'}.should change(@user, :salt)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should not store the plaintext password' do
|
22
|
+
@user.password = 'newpass'
|
23
|
+
@user.crypted_password.should_not == 'newpass'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#password' do
|
28
|
+
before do
|
29
|
+
@user = Factory.build(:twitter_basic_user, :password => 'monkey')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should return the password' do
|
33
|
+
@user.password.should == 'monkey'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should not be a database attribute' do
|
37
|
+
@user['password'].should_not == 'monkey'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '.verify_credentials' do
|
42
|
+
before do
|
43
|
+
@user = Factory.create(:twitter_basic_user)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should return a JSON hash of the user when successful' do
|
47
|
+
hash = User.verify_credentials('twitterman','test')
|
48
|
+
hash.should be_a(Hash)
|
49
|
+
hash['screen_name'].should == 'twitterman'
|
50
|
+
hash['name'].should == 'Twitter Man'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should return false when a 401 unauthorized happens' do
|
54
|
+
FakeWeb.register_uri(:get, 'https://twitter.com:443/account/verify_credentials.json', :string => '401 "Unauthorized"', :status => ['401',' Unauthorized'])
|
55
|
+
User.verify_credentials('twitterman','wrong').should be_false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '.authenticate' do
|
60
|
+
before do
|
61
|
+
@user = Factory.create(:twitter_basic_user)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should make a call to verify_credentials' do
|
65
|
+
User.should_receive(:verify_credentials).with('twitterman','test')
|
66
|
+
User.authenticate('twitterman','test')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should return nil if verify_credentials returns false' do
|
70
|
+
User.stub!(:verify_credentials).and_return(false)
|
71
|
+
User.authenticate('twitterman','test').should be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should return the user if verify_credentials succeeds' do
|
75
|
+
User.stub!(:verify_credentials).and_return(JSON.parse("{\"profile_image_url\":\"http:\\/\\/static.twitter.com\\/images\\/default_profile_normal.png\",\"description\":\"Saving the world for all Twitter kind.\",\"utc_offset\":null,\"favourites_count\":0,\"profile_sidebar_fill_color\":\"e0ff92\",\"screen_name\":\"twitterman\",\"statuses_count\":0,\"profile_background_tile\":false,\"profile_sidebar_border_color\":\"87bc44\",\"friends_count\":2,\"url\":null,\"name\":\"Twitter Man\",\"time_zone\":null,\"protected\":false,\"profile_background_image_url\":\"http:\\/\\/static.twitter.com\\/images\\/themes\\/theme1\\/bg.gif\",\"profile_background_color\":\"9ae4e8\",\"created_at\":\"Fri Feb 06 18:10:32 +0000 2009\",\"profile_text_color\":\"000000\",\"followers_count\":2,\"location\":null,\"id\":20256865,\"profile_link_color\":\"0000ff\"}"))
|
76
|
+
User.authenticate('twitterman','test').should == @user
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '.find_or_create_by_twitter_hash_and_password' do
|
81
|
+
before do
|
82
|
+
@user = Factory.create(:twitter_basic_user)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should return the existing user if there is one' do
|
86
|
+
User.identify_or_create_from_twitter_hash_and_password({'screen_name' => 'twitterman'},'test').should == @user
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should update the attributes from the hash' do
|
90
|
+
User.identify_or_create_from_twitter_hash_and_password({'screen_name' => 'twitterman', 'name' => 'New Name'}, 'test').name.should == 'New Name'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should update the password from the argument' do
|
94
|
+
User.identify_or_create_from_twitter_hash_and_password({'screen_name' => 'twitterman', 'name' => 'New Name'}, 'test2').password.should == 'test2'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should create a user if one does not exist' do
|
98
|
+
lambda{User.identify_or_create_from_twitter_hash_and_password({'screen_name' => 'dude', 'name' => "Lebowski"}, 'test')}.should change(User, :count).by(1)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should assign the attributes from the hash to a created user' do
|
102
|
+
user = User.identify_or_create_from_twitter_hash_and_password({'screen_name' => 'dude', 'name' => "Lebowski"}, 'test')
|
103
|
+
user.login.should == 'dude'
|
104
|
+
user.name.should == 'Lebowski'
|
105
|
+
user.password.should == 'test'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#twitter' do
|
110
|
+
before do
|
111
|
+
@user = Factory.create(:twitter_basic_user)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should be an instance of TwitterAuth::Dispatcher::Basic' do
|
115
|
+
@user.twitter.class.should == TwitterAuth::Dispatcher::Basic
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should have the correct user set' do
|
119
|
+
@user.twitter.user.should == @user
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|