twitter-auth-with-mongo-mapper 0.0.9
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/CHANGELOG.markdown +11 -0
- data/README.markdown +5 -0
- data/Rakefile +31 -0
- data/VERSION.yml +4 -0
- data/app/controllers/sessions_controller.rb +81 -0
- data/app/models/twitter_auth/basic_user.rb +64 -0
- data/app/models/twitter_auth/generic_user.rb +135 -0
- data/app/models/twitter_auth/oauth_user.rb +50 -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 +49 -0
- data/generators/twitter_auth/templates/twitter_auth.yml +47 -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 +100 -0
- data/lib/twitter_auth/controller_extensions.rb +82 -0
- data/lib/twitter_auth/cryptify.rb +31 -0
- data/lib/twitter_auth/dispatcher/basic.rb +46 -0
- data/lib/twitter_auth/dispatcher/oauth.rb +27 -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 +20 -0
- data/spec/fixtures/fakeweb.rb +18 -0
- data/spec/fixtures/twitter.rb +5 -0
- data/spec/models/twitter_auth/basic_user_spec.rb +138 -0
- data/spec/models/twitter_auth/generic_user_spec.rb +146 -0
- data/spec/models/twitter_auth/oauth_user_spec.rb +100 -0
- data/spec/schema.rb +42 -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 +160 -0
- metadata +151 -0
@@ -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, :twitter_id => '123')
|
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, :twitter_id => '123')
|
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,20 @@
|
|
1
|
+
require 'factory_girl'
|
2
|
+
|
3
|
+
Factory.define(:twitter_oauth_user, :class => User) do |u|
|
4
|
+
u.twitter_id { User.count + 1 }
|
5
|
+
u.login 'twitterman'
|
6
|
+
u.access_token 'fakeaccesstoken'
|
7
|
+
u.access_secret 'fakeaccesstokensecret'
|
8
|
+
|
9
|
+
u.name 'Twitter Man'
|
10
|
+
u.description 'Saving the world for all Twitter kind.'
|
11
|
+
end
|
12
|
+
|
13
|
+
Factory.define(:twitter_basic_user, :class => User) do |u|
|
14
|
+
u.twitter_id { User.count + 1 }
|
15
|
+
u.login 'twitterman'
|
16
|
+
u.password 'test'
|
17
|
+
|
18
|
+
u.name 'Twitter Man'
|
19
|
+
u.description 'Saving the world for all Twitter kind.'
|
20
|
+
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\":123,\"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,138 @@
|
|
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, :twitter_id => '123')
|
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, :twitter_id => '123')
|
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\":123,\"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, :twitter_id => '123')
|
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({'id' => '123', '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({'id' => 123, '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({'id' => '123', '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({'id' => 124, '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({'id' => 124, 'screen_name' => 'dude', 'name' => "Lebowski"}, 'test')
|
103
|
+
user.twitter_id.should == '124'
|
104
|
+
user.login.should == 'dude'
|
105
|
+
user.name.should == 'Lebowski'
|
106
|
+
user.password.should == 'test'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#twitter' do
|
111
|
+
before do
|
112
|
+
@user = Factory.create(:twitter_basic_user, :twitter_id => '123')
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should be an instance of TwitterAuth::Dispatcher::Basic' do
|
116
|
+
@user.twitter.class.should == TwitterAuth::Dispatcher::Basic
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should have the correct user set' do
|
120
|
+
@user.twitter.user.should == @user
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'changing usernames' do
|
125
|
+
before do
|
126
|
+
@user = Factory.create(:twitter_basic_user, :twitter_id => '123')
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should not create a new record when a screen_name has changed' do
|
130
|
+
lambda{User.identify_or_create_from_twitter_hash_and_password({'id' => '123', 'screen_name' => 'dude'},'awesome')}.should_not change(User,:count)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should update the record with the new screen name' do
|
134
|
+
User.identify_or_create_from_twitter_hash_and_password({'id' => '123', 'screen_name' => 'dude'},'awesome').should == @user.reload
|
135
|
+
@user.login.should == 'dude'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe TwitterAuth::GenericUser do
|
4
|
+
should_validate_presence_of :login, :twitter_id
|
5
|
+
should_validate_format_of :login, 'some_guy', 'awesome', 'cool_man'
|
6
|
+
should_not_validate_format_of :login, 'with-dashes', 'with.periods', 'with spaces'
|
7
|
+
should_validate_length_of :login, :in => 1..15
|
8
|
+
|
9
|
+
it 'should validate uniqueness of login' do
|
10
|
+
Factory.create(:twitter_oauth_user)
|
11
|
+
Factory.build(:twitter_oauth_user).should have_at_least(1).errors_on(:login)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should validate uniqueness of remember_token' do
|
15
|
+
Factory.create(:twitter_oauth_user, :remember_token => 'abc')
|
16
|
+
Factory.build(:twitter_oauth_user, :remember_token => 'abc').should have_at_least(1).errors_on(:remember_token)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should allow capital letters in the username' do
|
20
|
+
Factory.build(:twitter_oauth_user, :login => 'TwitterMan').should have(:no).errors_on(:login)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should not allow the same login with different capitalization' do
|
24
|
+
Factory.create(:twitter_oauth_user, :login => 'twitterman')
|
25
|
+
Factory.build(:twitter_oauth_user, :login => 'TwitterMan').should have_at_least(1).errors_on(:login)
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '.new_from_twitter_hash' do
|
29
|
+
it 'should raise an argument error if the hash does not have a screen_name attribute' do
|
30
|
+
lambda{User.new_from_twitter_hash({'id' => '123'})}.should raise_error(ArgumentError, 'Invalid hash: must include screen_name.')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should raise an argument error if the hash does not have an id attribute' do
|
34
|
+
lambda{User.new_from_twitter_hash({'screen_name' => 'abc123'})}.should raise_error(ArgumentError, 'Invalid hash: must include id.')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should return a user' do
|
38
|
+
User.new_from_twitter_hash({'id' => '123', 'screen_name' => 'twitterman'}).should be_a(User)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should assign login to the screen_name' do
|
42
|
+
User.new_from_twitter_hash({'id' => '123', 'screen_name' => 'twitterman'}).login.should == 'twitterman'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should assign twitter attributes that are provided' do
|
46
|
+
u = User.new_from_twitter_hash({'id' => '4566', 'screen_name' => 'twitterman', 'name' => 'Twitter Man', 'description' => 'Saving the world for all Tweet kind.'})
|
47
|
+
u.name.should == 'Twitter Man'
|
48
|
+
u.description.should == 'Saving the world for all Tweet kind.'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#update_twitter_attributes' do
|
53
|
+
it 'should assign values to the user' do
|
54
|
+
user = Factory.create(:twitter_oauth_user, :name => "Dude", :description => "Awesome, man.")
|
55
|
+
user.update_twitter_attributes({'name' => 'Twitter Man', 'description' => 'Works.'})
|
56
|
+
user.reload
|
57
|
+
user.name.should == 'Twitter Man'
|
58
|
+
user.description.should == 'Works.'
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should not throw an error with extraneous info' do
|
62
|
+
user = Factory.create(:twitter_oauth_user, :name => "Dude", :description => "Awesome, man.")
|
63
|
+
lambda{user.update_twitter_attributes({'name' => 'Twitter Man', 'description' => 'Works.', 'whoopsy' => 'noworks.'})}.should_not raise_error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#remember_me' do
|
68
|
+
before do
|
69
|
+
@user = Factory(:twitter_oauth_user)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should check for the remember_token column' do
|
73
|
+
@user.should_receive(:respond_to?).with(:remember_token).and_return(false)
|
74
|
+
@user.remember_me
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should return nil if there is no remember_token column' do
|
78
|
+
@user.should_receive(:respond_to?).with(:remember_token).and_return(false)
|
79
|
+
@user.remember_me.should be_false
|
80
|
+
end
|
81
|
+
|
82
|
+
describe ' with proper columns' do
|
83
|
+
it 'should generate a secure random token' do
|
84
|
+
ActiveSupport::SecureRandom.should_receive(:hex).with(10).and_return('abcdef')
|
85
|
+
@user.remember_me
|
86
|
+
@user.remember_token.should == 'abcdef'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should set the expiration to the current time plus the remember_for period' do
|
90
|
+
TwitterAuth.stub!(:remember_for).and_return(10)
|
91
|
+
time = Time.now
|
92
|
+
Time.stub!(:now).and_return(time)
|
93
|
+
|
94
|
+
@user.remember_me
|
95
|
+
|
96
|
+
@user.remember_token_expires_at.should == Time.now + 10.days
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should return a hash with a :value and :expires key' do
|
100
|
+
result = @user.remember_me
|
101
|
+
result.should be_a(Hash)
|
102
|
+
result.key?(:value).should be_true
|
103
|
+
result.key?(:expires).should be_true
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should return a hash with appropriate values' do
|
107
|
+
TwitterAuth.stub!(:remember_for).and_return(10)
|
108
|
+
time = Time.now
|
109
|
+
Time.stub!(:now).and_return(time)
|
110
|
+
ActiveSupport::SecureRandom.stub!(:hex).and_return('abcdef')
|
111
|
+
|
112
|
+
@user.remember_me.should == {:value => 'abcdef', :expires => (Time.now + 10.days)}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#forget_me' do
|
118
|
+
it 'should reset remember_token and remember_token_expires_at' do
|
119
|
+
@user = Factory(:twitter_oauth_user, :remember_token => "abcdef", :remember_token_expires_at => Time.now + 10.days)
|
120
|
+
@user.forget_me
|
121
|
+
@user.reload
|
122
|
+
@user.remember_token.should be_nil
|
123
|
+
@user.remember_token_expires_at.should be_nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '.from_remember_token' do
|
128
|
+
before do
|
129
|
+
@user = Factory(:twitter_oauth_user, :remember_token => 'abcdef', :remember_token_expires_at => (Time.now + 10.days))
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should find the user with the specified remember_token' do
|
133
|
+
User.from_remember_token('abcdef').should == @user
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should not find a user with an expired token' do
|
137
|
+
user2 = Factory(:twitter_oauth_user, :login => 'walker', :remember_token => 'ghijkl', :remember_token_expires_at => (Time.now - 10.days))
|
138
|
+
User.from_remember_token('ghijkl').should be_nil
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should not find a user with a nil token and an expiration' do
|
142
|
+
user = Factory(:twitter_oauth_user, :login => 'stranger', :remember_token => nil, :remember_token_expires_at => (Time.now + 10.days))
|
143
|
+
User.from_remember_token(nil).should be_nil
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|