stocktwits 1.0.0
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/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README +0 -0
- data/README.rdoc +17 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/app/controllers/sessions_controller.rb +68 -0
- data/app/models/stocktwits/basic_user.rb +64 -0
- data/app/models/stocktwits/generic_user.rb +123 -0
- data/app/models/stocktwits/oauth_user.rb +46 -0
- data/app/models/stocktwits/plain_user.rb +53 -0
- data/app/views/sessions/_login.html.erb +18 -0
- data/app/views/sessions/new.html.erb +5 -0
- data/config/routes.rb +6 -0
- data/generators/stocktwits/USAGE +12 -0
- data/generators/stocktwits/stocktwits_generator.rb +42 -0
- data/generators/stocktwits/templates/migration.rb +20 -0
- data/generators/stocktwits/templates/stocktwits.yml +66 -0
- data/generators/stocktwits/templates/user.rb +5 -0
- data/lib/stocktwits.rb +103 -0
- data/lib/stocktwits/controller_extensions.rb +72 -0
- data/lib/stocktwits/cryptify.rb +30 -0
- data/lib/stocktwits/dispatcher/basic.rb +46 -0
- data/lib/stocktwits/dispatcher/oauth.rb +26 -0
- data/lib/stocktwits/dispatcher/plain.rb +44 -0
- data/lib/stocktwits/dispatcher/shared.rb +42 -0
- data/rails/init.rb +6 -0
- data/spec/application.rb +1 -0
- data/spec/controllers/controller_extensions_spec.rb +162 -0
- data/spec/controllers/sessions_controller_spec.rb +221 -0
- data/spec/debug.log +397 -0
- data/spec/fixtures/config/twitter_auth.yml +17 -0
- data/spec/fixtures/factories.rb +28 -0
- data/spec/fixtures/fakeweb.rb +18 -0
- data/spec/fixtures/stocktwits.rb +5 -0
- data/spec/models/stocktwits/basic_user_spec.rb +138 -0
- data/spec/models/stocktwits/generic_user_spec.rb +146 -0
- data/spec/models/stocktwits/oauth_user_spec.rb +100 -0
- data/spec/schema.rb +25 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +107 -0
- data/spec/stocktwits/cryptify_spec.rb +51 -0
- data/spec/stocktwits/dispatcher/basic_spec.rb +83 -0
- data/spec/stocktwits/dispatcher/oauth_spec.rb +72 -0
- data/spec/stocktwits/dispatcher/shared_spec.rb +26 -0
- data/spec/stocktwits_spec.rb +173 -0
- data/stocktwits.gemspec +116 -0
- metadata +158 -0
@@ -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 Stocktwits::BasicUser do
|
4
|
+
before do
|
5
|
+
stub_basic!
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#password=' do
|
9
|
+
before do
|
10
|
+
@user = Factory.build(:stocktwits_basic_user, :stocktwits_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(:stocktwits_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(:stocktwits_basic_user)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should return a JSON hash of the user when successful' do
|
47
|
+
hash = User.verify_credentials('stocktwitsman','test')
|
48
|
+
hash.should be_a(Hash)
|
49
|
+
hash['screen_name'].should == 'stocktwitsman'
|
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://stocktwits.com:443/account/verify_credentials.json', :string => '401 "Unauthorized"', :status => ['401',' Unauthorized'])
|
55
|
+
User.verify_credentials('stocktwitsman','wrong').should be_false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '.authenticate' do
|
60
|
+
before do
|
61
|
+
@user = Factory.create(:stocktwits_basic_user, :stocktwits_id => '123')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should make a call to verify_credentials' do
|
65
|
+
User.should_receive(:verify_credentials).with('stocktwitsman','test')
|
66
|
+
User.authenticate('stocktwitsman','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('stocktwitsman','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.stocktwits.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\":\"stocktwitsman\",\"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.stocktwits.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('stocktwitsman','test').should == @user
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '.find_or_create_by_stocktwits_hash_and_password' do
|
81
|
+
before do
|
82
|
+
@user = Factory.create(:stocktwits_basic_user, :stocktwits_id => '123')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should return the existing user if there is one' do
|
86
|
+
User.identify_or_create_from_stocktwits_hash_and_password({'id' => '123', 'screen_name' => 'stocktwitsman'},'test').should == @user
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should update the attributes from the hash' do
|
90
|
+
User.identify_or_create_from_stocktwits_hash_and_password({'id' => 123, 'screen_name' => 'stocktwitsman', '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_stocktwits_hash_and_password({'id' => '123', 'screen_name' => 'stocktwitsman', '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_stocktwits_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_stocktwits_hash_and_password({'id' => 124, 'screen_name' => 'dude', 'name' => "Lebowski"}, 'test')
|
103
|
+
user.stocktwits_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 '#stocktwits' do
|
111
|
+
before do
|
112
|
+
@user = Factory.create(:stocktwits_basic_user, :stocktwits_id => '123')
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should be an instance of Stocktwits::Dispatcher::Basic' do
|
116
|
+
@user.stocktwits.class.should == Stocktwits::Dispatcher::Basic
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should have the correct user set' do
|
120
|
+
@user.stocktwits.user.should == @user
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'changing usernames' do
|
125
|
+
before do
|
126
|
+
@user = Factory.create(:stocktwits_basic_user, :stocktwits_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_stocktwits_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_stocktwits_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 Stocktwits::GenericUser do
|
4
|
+
should_validate_presence_of :login, :stocktwits_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(:stocktwits_oauth_user)
|
11
|
+
Factory.build(:stocktwits_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(:stocktwits_oauth_user, :remember_token => 'abc')
|
16
|
+
Factory.build(:stocktwits_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(:stocktwits_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(:stocktwits_oauth_user, :login => 'stocktwitsman')
|
25
|
+
Factory.build(:stocktwits_oauth_user, :login => 'TwitterMan').should have_at_least(1).errors_on(:login)
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '.new_from_stocktwits_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_stocktwits_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_stocktwits_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_stocktwits_hash({'id' => '123', 'screen_name' => 'stocktwitsman'}).should be_a(User)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should assign login to the screen_name' do
|
42
|
+
User.new_from_stocktwits_hash({'id' => '123', 'screen_name' => 'stocktwitsman'}).login.should == 'stocktwitsman'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should assign stocktwits attributes that are provided' do
|
46
|
+
u = User.new_from_stocktwits_hash({'id' => '4566', 'screen_name' => 'stocktwitsman', '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_stocktwits_attributes' do
|
53
|
+
it 'should assign values to the user' do
|
54
|
+
user = Factory.create(:stocktwits_oauth_user, :name => "Dude", :description => "Awesome, man.")
|
55
|
+
user.update_stocktwits_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(:stocktwits_oauth_user, :name => "Dude", :description => "Awesome, man.")
|
63
|
+
lambda{user.update_stocktwits_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(:stocktwits_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
|
+
Stocktwits.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
|
+
Stocktwits.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(:stocktwits_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(:stocktwits_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(:stocktwits_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(:stocktwits_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
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Stocktwits::OauthUser do
|
4
|
+
before do
|
5
|
+
stub_oauth!
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '.identify_or_create_from_access_token' do
|
9
|
+
before do
|
10
|
+
@token = OAuth::AccessToken.new(Stocktwits.consumer, 'faketoken', 'fakesecret')
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should accept an OAuth::AccessToken' do
|
14
|
+
lambda{ User.identify_or_create_from_access_token(@token) }.should_not raise_error(ArgumentError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should change the login when the screen_name changes' do
|
18
|
+
@user = Factory(:stocktwits_oauth_user, :stocktwits_id => '123')
|
19
|
+
User.stub!(:handle_response).and_return({'id' => 123, 'screen_name' => 'dude'})
|
20
|
+
User.identify_or_create_from_access_token(@token).should == @user.reload
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should accept two strings' do
|
24
|
+
lambda{ User.identify_or_create_from_access_token('faketoken', 'fakesecret') }.should_not raise_error(ArgumentError)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should not accept one string' do
|
28
|
+
lambda{ User.identify_or_create_from_access_token('faketoken') }.should raise_error(ArgumentError, 'Must authenticate with an OAuth::AccessToken or the string access token and secret.')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should make a call to verify_credentials' do
|
32
|
+
# this is in the before, just making it explicit
|
33
|
+
User.identify_or_create_from_access_token(@token)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should try to find the user with that id' do
|
37
|
+
User.should_receive(:find_by_stocktwits_id).once.with('123')
|
38
|
+
User.identify_or_create_from_access_token(@token)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should return the user if he/she exists' do
|
42
|
+
user = Factory.create(:stocktwits_oauth_user, :stocktwits_id => '123', :login => 'stocktwitsman')
|
43
|
+
user.reload
|
44
|
+
User.identify_or_create_from_access_token(@token).should == user
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should update the access_token and access_secret for the user if he/she exists' do
|
48
|
+
user = Factory.create(:stocktwits_oauth_user, :stocktwits_id => '123', :login => 'stocktwitsman', :access_token => 'someothertoken', :access_secret => 'someothersecret')
|
49
|
+
User.identify_or_create_from_access_token(@token)
|
50
|
+
user.reload
|
51
|
+
user.access_token.should == @token.token
|
52
|
+
user.access_secret.should == @token.secret
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should update the user\'s attributes based on the stocktwits info' do
|
56
|
+
user = Factory.create(:stocktwits_oauth_user, :login => 'stocktwitsman', :name => 'Not Twitter Man')
|
57
|
+
User.identify_or_create_from_access_token(@token).name.should == 'Twitter Man'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should create a user if one does not exist' do
|
61
|
+
lambda{User.identify_or_create_from_access_token(@token)}.should change(User, :count).by(1)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should assign the oauth access token and secret' do
|
65
|
+
user = User.identify_or_create_from_access_token(@token)
|
66
|
+
user.access_token.should == @token.token
|
67
|
+
user.access_secret.should == @token.secret
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#token' do
|
72
|
+
before do
|
73
|
+
@user = Factory.create(:stocktwits_oauth_user, :access_token => 'token', :access_secret => 'secret')
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should return an AccessToken' do
|
77
|
+
@user.token.should be_a(OAuth::AccessToken)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should use the user's access_token and secret" do
|
81
|
+
@user.token.token.should == @user.access_token
|
82
|
+
@user.token.secret.should == @user.access_secret
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#stocktwits' do
|
87
|
+
before do
|
88
|
+
@user = Factory.create(:stocktwits_oauth_user, :access_token => 'token', :access_secret => 'secret')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should return a Stocktwits::Dispatcher::Oauth' do
|
92
|
+
@user.stocktwits.should be_a(Stocktwits::Dispatcher::Oauth)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should use my token and secret' do
|
96
|
+
@user.stocktwits.token.should == @user.access_token
|
97
|
+
@user.stocktwits.secret.should == @user.access_secret
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/spec/schema.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
ActiveRecord::Schema.define :version => 0 do
|
2
|
+
create_table :stocktwits_users, :force => true do |t|
|
3
|
+
t.string :twitter_id
|
4
|
+
t.string :login
|
5
|
+
|
6
|
+
# OAuth fields
|
7
|
+
t.string :access_token
|
8
|
+
t.string :access_secret
|
9
|
+
|
10
|
+
# Basic fields
|
11
|
+
t.binary :crypted_password
|
12
|
+
t.string :salt
|
13
|
+
|
14
|
+
# Remember token fields
|
15
|
+
t.string :remember_token
|
16
|
+
t.datetime :remember_token_expires_at
|
17
|
+
|
18
|
+
# This information is automatically kept
|
19
|
+
# in-sync at each login of the user. You
|
20
|
+
# may remove any/all of these columns.
|
21
|
+
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# begin
|
2
|
+
# require File.dirname(__FILE__) + '/../../../../spec/spec_helper'
|
3
|
+
# rescue LoadError
|
4
|
+
# puts "You need to install rspec in your base app"
|
5
|
+
# exit
|
6
|
+
# end
|
7
|
+
|
8
|
+
RAILS_ROOT = File.dirname(__FILE__) unless defined?(RAILS_ROOT)
|
9
|
+
|
10
|
+
|
11
|
+
module Rails
|
12
|
+
|
13
|
+
module VERSION
|
14
|
+
STRING = "2.3.5"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.env
|
18
|
+
"test"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.root
|
22
|
+
File.dirname(__FILE__)
|
23
|
+
end
|
24
|
+
end unless defined?(Rails)
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
require 'rubygems'
|
29
|
+
require 'active_record'
|
30
|
+
require 'action_controller'
|
31
|
+
require 'action_controller/test_process'
|
32
|
+
require 'spec'
|
33
|
+
require 'spec/rails'
|
34
|
+
require 'shoulda'
|
35
|
+
#require 'shoulda/rails'
|
36
|
+
|
37
|
+
#include Shoulda::Rails
|
38
|
+
|
39
|
+
ActiveRecord::Base.establish_connection(
|
40
|
+
:adapter => "sqlite3",
|
41
|
+
:database => ":memory:"
|
42
|
+
)
|
43
|
+
|
44
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
45
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
46
|
+
|
47
|
+
require 'stocktwits'
|
48
|
+
|
49
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__),'..','lib','**','*.rb'))].each {|f| require f}
|
50
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__),'..','app','**','*.rb'))].each {|f| require f}
|
51
|
+
|
52
|
+
|
53
|
+
class Stocktwits::GenericUser
|
54
|
+
def self.table_name; 'stocktwits_users' end
|
55
|
+
end
|
56
|
+
|
57
|
+
class User < Stocktwits::GenericUser; end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
require 'remarkable'
|
62
|
+
require File.dirname(__FILE__) + '/fixtures/factories'
|
63
|
+
require File.dirname(__FILE__) + '/fixtures/fakeweb'
|
64
|
+
# require File.dirname(__FILE__) + '/fixtures/stocktwits'
|
65
|
+
|
66
|
+
plugin_spec_dir = File.dirname(__FILE__)
|
67
|
+
ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
|
68
|
+
|
69
|
+
load(File.dirname(__FILE__) + '/schema.rb')
|
70
|
+
|
71
|
+
def define_basic_user_class!
|
72
|
+
Stocktwits::GenericUser.send :include, Stocktwits::BasicUser
|
73
|
+
end
|
74
|
+
|
75
|
+
def define_oauth_user_class!
|
76
|
+
Stocktwits::GenericUser.send :include, Stocktwits::OauthUser
|
77
|
+
end
|
78
|
+
|
79
|
+
def define_plain_user_class!
|
80
|
+
Stocktwits::GenericUser.send :include, Stocktwits::PlainUser
|
81
|
+
end
|
82
|
+
|
83
|
+
def stub_oauth!
|
84
|
+
Stocktwits.stub!(:config).and_return({
|
85
|
+
'strategy' => 'oauth',
|
86
|
+
'oauth_consumer_key' => 'testkey',
|
87
|
+
'oauth_consumer_secret' => 'testsecret'
|
88
|
+
})
|
89
|
+
define_oauth_user_class!
|
90
|
+
end
|
91
|
+
|
92
|
+
def stub_basic!
|
93
|
+
Stocktwits.stub!(:config).and_return({
|
94
|
+
'strategy' => 'basic',
|
95
|
+
'encryption_key' => 'secretcode'
|
96
|
+
})
|
97
|
+
define_basic_user_class!
|
98
|
+
end
|
99
|
+
|
100
|
+
def stub_plain!
|
101
|
+
Stocktwits.stub!(:config).and_return({
|
102
|
+
'strategy' => 'plain'
|
103
|
+
})
|
104
|
+
define_plain_user_class!
|
105
|
+
end
|
106
|
+
|
107
|
+
define_oauth_user_class!
|