tweetstream 1.1.5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of tweetstream might be problematic. Click here for more details.
- data/CHANGELOG.md +19 -2
- data/LICENSE.md +1 -1
- data/README.md +116 -43
- data/Rakefile +0 -2
- data/examples/growl_daemon.rb +5 -5
- data/examples/oauth.rb +4 -5
- data/examples/sitestream.rb +40 -0
- data/examples/userstream.rb +4 -5
- data/lib/tweetstream.rb +0 -4
- data/lib/tweetstream/client.rb +95 -75
- data/lib/tweetstream/configuration.rb +12 -5
- data/lib/tweetstream/site_stream_client.rb +123 -0
- data/lib/tweetstream/version.rb +1 -1
- data/spec/fixtures/ids.json +30 -0
- data/spec/fixtures/info.json +18 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/tweetstream/client_spec.rb +172 -65
- data/spec/tweetstream/site_stream_client_spec.rb +232 -0
- data/spec/tweetstream_spec.rb +18 -18
- data/tweetstream.gemspec +9 -5
- metadata +69 -90
- data/lib/tweetstream/direct_message.rb +0 -6
- data/lib/tweetstream/hash.rb +0 -27
- data/lib/tweetstream/status.rb +0 -12
- data/lib/tweetstream/user.rb +0 -7
- data/spec/tweetstream/direct_message_spec.rb +0 -21
- data/spec/tweetstream/hash_spec.rb +0 -19
- data/spec/tweetstream/parser_spec.rb +0 -42
- data/spec/tweetstream/status_spec.rb +0 -15
@@ -16,8 +16,14 @@ module TweetStream
|
|
16
16
|
:oauth_token,
|
17
17
|
:oauth_token_secret].freeze
|
18
18
|
|
19
|
+
OAUTH_OPTIONS_KEYS = [
|
20
|
+
:consumer_key,
|
21
|
+
:consumer_secret,
|
22
|
+
:oauth_token,
|
23
|
+
:oauth_token_secret].freeze
|
24
|
+
|
19
25
|
# The parser that will be used to connect if none is set
|
20
|
-
DEFAULT_PARSER = MultiJson.
|
26
|
+
DEFAULT_PARSER = MultiJson.default_engine
|
21
27
|
|
22
28
|
# By default, don't set a username
|
23
29
|
DEFAULT_USERNAME = nil
|
@@ -47,9 +53,6 @@ module TweetStream
|
|
47
53
|
# By default, don't set a user oauth secret
|
48
54
|
DEFAULT_OAUTH_TOKEN_SECRET = nil
|
49
55
|
|
50
|
-
# Default time interval for use with on_interval
|
51
|
-
DEFAULT_TIMER_INTERVAL = 30
|
52
|
-
|
53
56
|
# @private
|
54
57
|
attr_accessor *VALID_OPTIONS_KEYS
|
55
58
|
|
@@ -68,9 +71,13 @@ module TweetStream
|
|
68
71
|
Hash[*VALID_OPTIONS_KEYS.map {|key| [key, send(key)] }.flatten]
|
69
72
|
end
|
70
73
|
|
74
|
+
# Create a hash of options and their values
|
75
|
+
def oauth_options
|
76
|
+
Hash[*OAUTH_OPTIONS_KEYS.map {|key| [key, send(key)] }.flatten]
|
77
|
+
end
|
78
|
+
|
71
79
|
# Reset all configuration options to defaults
|
72
80
|
def reset
|
73
|
-
self.parser = DEFAULT_PARSER
|
74
81
|
self.username = DEFAULT_USERNAME
|
75
82
|
self.password = DEFAULT_PASSWORD
|
76
83
|
self.user_agent = DEFAULT_USER_AGENT
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'em-http'
|
2
|
+
require 'em-http/middleware/oauth'
|
3
|
+
require 'em-http/middleware/json_response'
|
4
|
+
|
5
|
+
module TweetStream
|
6
|
+
class SiteStreamClient
|
7
|
+
|
8
|
+
attr_accessor *Configuration::OAUTH_OPTIONS_KEYS
|
9
|
+
|
10
|
+
def initialize(config_uri, oauth = {})
|
11
|
+
@config_uri = config_uri
|
12
|
+
|
13
|
+
options = TweetStream.oauth_options.merge(oauth)
|
14
|
+
Configuration::OAUTH_OPTIONS_KEYS.each do |key|
|
15
|
+
send("#{key}=", options[key])
|
16
|
+
end
|
17
|
+
|
18
|
+
EventMachine::HttpRequest.use EventMachine::Middleware::JSONResponse
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_error(&block)
|
22
|
+
if block_given?
|
23
|
+
@on_error = block
|
24
|
+
self
|
25
|
+
else
|
26
|
+
@on_error
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def info(&block)
|
31
|
+
error_msg = 'Failed to retrieve SiteStream info.'
|
32
|
+
|
33
|
+
http = connection.get(:path => info_path)
|
34
|
+
http.callback do
|
35
|
+
if http.response_header.status == 200
|
36
|
+
block.call http.response if block && block.kind_of?(Proc)
|
37
|
+
else
|
38
|
+
@on_error.call(error_msg) if @on_error && @on_error.kind_of?(Proc)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
http.errback do
|
42
|
+
@on_error.call(error_msg) if @on_error && @on_error.kind_of?(Proc)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_user(user_id, &block)
|
47
|
+
error_msg = 'Failed to add user to SiteStream'
|
48
|
+
user_management(add_user_path, user_id, error_msg, &block)
|
49
|
+
end
|
50
|
+
|
51
|
+
def remove_user(user_id, &block)
|
52
|
+
error_msg = 'Failed to remove user from SiteStream.'
|
53
|
+
user_management(remove_user_path, user_id, error_msg, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
def friends_ids(user_id, &block)
|
57
|
+
error_msg = 'Failed to retrieve SiteStream friends ids.'
|
58
|
+
|
59
|
+
http = connection.post(:path => friends_ids_path, :body => { 'user_id' => user_id })
|
60
|
+
http.callback do
|
61
|
+
if http.response_header.status == 200
|
62
|
+
block.call http.response if block && block.kind_of?(Proc)
|
63
|
+
else
|
64
|
+
@on_error.call(error_msg) if @on_error && @on_error.kind_of?(Proc)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
http.errback do
|
68
|
+
@on_error.call(error_msg) if @on_error && @on_error.kind_of?(Proc)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def user_management(path, user_id, error_msg, &block)
|
75
|
+
user_id = user_id.join(',') if user_id.kind_of?(Array)
|
76
|
+
|
77
|
+
http = connection.post(:path => path, :body => { 'user_id' => user_id })
|
78
|
+
http.callback do
|
79
|
+
if http.response_header.status == 200
|
80
|
+
block.call if block && block.kind_of?(Proc)
|
81
|
+
else
|
82
|
+
@on_error.call(error_msg) if @on_error && @on_error.kind_of?(Proc)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
http.errback do
|
86
|
+
@on_error.call(error_msg) if @on_error && @on_error.kind_of?(Proc)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def connection
|
91
|
+
return @conn if @conn
|
92
|
+
|
93
|
+
@conn = EventMachine::HttpRequest.new('https://sitestream.twitter.com/')
|
94
|
+
@conn.use EventMachine::Middleware::OAuth, oauth_configuration
|
95
|
+
@conn
|
96
|
+
end
|
97
|
+
|
98
|
+
def oauth_configuration
|
99
|
+
{
|
100
|
+
:consumer_key => consumer_key,
|
101
|
+
:consumer_secret => consumer_secret,
|
102
|
+
:access_token => oauth_token,
|
103
|
+
:access_token_secret => oauth_token_secret
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def info_path
|
108
|
+
@config_uri + '/info.json'
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_user_path
|
112
|
+
@config_uri + '/add_user.json'
|
113
|
+
end
|
114
|
+
|
115
|
+
def remove_user_path
|
116
|
+
@config_uri + '/remove_user.json'
|
117
|
+
end
|
118
|
+
|
119
|
+
def friends_ids_path
|
120
|
+
@config_uri + '/friends/ids.json'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/tweetstream/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
{
|
2
|
+
"follow":
|
3
|
+
{
|
4
|
+
"user":
|
5
|
+
{
|
6
|
+
"id":119476949,
|
7
|
+
"name":"oauth_dancer",
|
8
|
+
"dm":false
|
9
|
+
},
|
10
|
+
"friends":
|
11
|
+
[
|
12
|
+
795649,
|
13
|
+
819797,
|
14
|
+
1401881,
|
15
|
+
3191321,
|
16
|
+
6253282,
|
17
|
+
8285392,
|
18
|
+
9160152,
|
19
|
+
13058772,
|
20
|
+
15147442,
|
21
|
+
15266205,
|
22
|
+
15822993,
|
23
|
+
27831060,
|
24
|
+
101058399,
|
25
|
+
289788076
|
26
|
+
],
|
27
|
+
"previous_cursor":0,
|
28
|
+
"next_cursor":0
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{
|
2
|
+
"info":
|
3
|
+
{
|
4
|
+
"users":
|
5
|
+
[
|
6
|
+
{
|
7
|
+
"id":119476949,
|
8
|
+
"name":"oauth_dancer",
|
9
|
+
"dm":false
|
10
|
+
}
|
11
|
+
],
|
12
|
+
"delimited":"none",
|
13
|
+
"include_followings_activity":false,
|
14
|
+
"include_user_changes":false,
|
15
|
+
"replies":"none",
|
16
|
+
"with":"user"
|
17
|
+
}
|
18
|
+
}
|
data/spec/spec_helper.rb
CHANGED
@@ -7,7 +7,9 @@ unless ENV['CI']
|
|
7
7
|
end
|
8
8
|
|
9
9
|
require 'tweetstream'
|
10
|
+
require 'tweetstream/site_stream_client'
|
10
11
|
require 'rspec'
|
12
|
+
require 'webmock/rspec'
|
11
13
|
require 'yajl'
|
12
14
|
require 'json'
|
13
15
|
|
@@ -30,3 +32,16 @@ def sample_direct_messages
|
|
30
32
|
end
|
31
33
|
@direct_messages
|
32
34
|
end
|
35
|
+
|
36
|
+
def fixture_path
|
37
|
+
File.expand_path("../fixtures", __FILE__)
|
38
|
+
end
|
39
|
+
|
40
|
+
def fixture(file)
|
41
|
+
File.new(fixture_path + '/' + file)
|
42
|
+
end
|
43
|
+
|
44
|
+
FakeHttp = Class.new do
|
45
|
+
def callback; end
|
46
|
+
def errback; end
|
47
|
+
end
|
@@ -3,9 +3,10 @@ require 'spec_helper'
|
|
3
3
|
describe TweetStream::Client do
|
4
4
|
before(:each) do
|
5
5
|
TweetStream.configure do |config|
|
6
|
-
config.
|
7
|
-
config.
|
8
|
-
config.
|
6
|
+
config.consumer_key = 'abc'
|
7
|
+
config.consumer_secret = 'def'
|
8
|
+
config.oauth_token = '123'
|
9
|
+
config.oauth_token_secret = '456'
|
9
10
|
end
|
10
11
|
@client = TweetStream::Client.new
|
11
12
|
end
|
@@ -48,49 +49,53 @@ describe TweetStream::Client do
|
|
48
49
|
|
49
50
|
describe '#start' do
|
50
51
|
before do
|
51
|
-
@stream = stub("Twitter::
|
52
|
+
@stream = stub("EM::Twitter::Client",
|
52
53
|
:connect => true,
|
53
54
|
:unbind => true,
|
54
|
-
:
|
55
|
+
:each => true,
|
55
56
|
:on_error => true,
|
56
57
|
:on_max_reconnects => true,
|
57
58
|
:on_reconnect => true,
|
58
|
-
:connection_completed => true
|
59
|
+
:connection_completed => true,
|
60
|
+
:on_no_data_received => true
|
59
61
|
)
|
60
62
|
EM.stub!(:run).and_yield
|
61
|
-
Twitter::
|
63
|
+
EM::Twitter::Client.stub!(:connect).and_return(@stream)
|
62
64
|
end
|
63
65
|
|
64
66
|
it 'should try to connect via a JSON stream with basic auth' do
|
65
|
-
Twitter::
|
67
|
+
EM::Twitter::Client.should_receive(:connect).with(
|
66
68
|
:path => URI.parse('/1/statuses/filter.json'),
|
67
69
|
:method => 'POST',
|
68
70
|
:user_agent => TweetStream::Configuration::DEFAULT_USER_AGENT,
|
69
71
|
:on_inited => nil,
|
70
|
-
:
|
71
|
-
:
|
72
|
-
|
73
|
-
|
72
|
+
:params => { :track => 'monday'},
|
73
|
+
:oauth => {
|
74
|
+
:consumer_key => 'abc',
|
75
|
+
:consumer_secret => 'def',
|
76
|
+
:token => '123',
|
77
|
+
:token_secret => '456'
|
78
|
+
}
|
74
79
|
).and_return(@stream)
|
75
80
|
|
76
81
|
@client.track('monday')
|
77
82
|
end
|
78
83
|
|
79
|
-
describe '#
|
84
|
+
describe '#each' do
|
80
85
|
it 'should call the appropriate parser' do
|
81
86
|
@client = TweetStream::Client.new
|
82
87
|
MultiJson.should_receive(:decode).and_return({})
|
83
|
-
@stream.should_receive(:
|
88
|
+
@stream.should_receive(:each).and_yield(sample_tweets[0].to_json)
|
84
89
|
@client.track('abc','def')
|
85
90
|
end
|
86
91
|
|
87
|
-
it 'should yield a
|
88
|
-
@stream.should_receive(:
|
89
|
-
@client.track('abc'){|s| s.should be_kind_of(
|
92
|
+
it 'should yield a Twitter::Status' do
|
93
|
+
@stream.should_receive(:each).and_yield(sample_tweets[0].to_json)
|
94
|
+
@client.track('abc'){|s| s.should be_kind_of(Twitter::Status)}
|
90
95
|
end
|
91
96
|
|
92
97
|
it 'should also yield the client if a block with arity 2 is given' do
|
93
|
-
@stream.should_receive(:
|
98
|
+
@stream.should_receive(:each).and_yield(sample_tweets[0].to_json)
|
94
99
|
@client.track('abc'){|s,c| c.should == @client}
|
95
100
|
end
|
96
101
|
|
@@ -99,7 +104,7 @@ describe TweetStream::Client do
|
|
99
104
|
tweet[:id] = 123
|
100
105
|
tweet[:user][:screen_name] = 'monkey'
|
101
106
|
tweet[:text] = "Oo oo aa aa"
|
102
|
-
@stream.should_receive(:
|
107
|
+
@stream.should_receive(:each).and_yield(tweet.to_json)
|
103
108
|
@client.track('abc') do |s|
|
104
109
|
s[:id].should == 123
|
105
110
|
s.user.screen_name.should == 'monkey'
|
@@ -109,7 +114,7 @@ describe TweetStream::Client do
|
|
109
114
|
|
110
115
|
it 'should call the on_scrub_geo if specified' do
|
111
116
|
scrub_geo = '{ "scrub_geo": { "user_id": 1234, "user_id_str": "1234", "up_to_status_id":9876, "up_to_status_id_string": "9876" } }'
|
112
|
-
@stream.should_receive(:
|
117
|
+
@stream.should_receive(:each).and_yield(scrub_geo)
|
113
118
|
@client.on_scrub_geo do |up_to_status_id, user_id|
|
114
119
|
up_to_status_id.should == 9876
|
115
120
|
user_id.should == 1234
|
@@ -118,7 +123,7 @@ describe TweetStream::Client do
|
|
118
123
|
|
119
124
|
it 'should call the delete if specified' do
|
120
125
|
delete = '{ "delete": { "status": { "id": 1234, "user_id": 3 } } }'
|
121
|
-
@stream.should_receive(:
|
126
|
+
@stream.should_receive(:each).and_yield(delete)
|
122
127
|
@client.on_delete do |id, user_id|
|
123
128
|
id.should == 1234
|
124
129
|
user_id.should == 3
|
@@ -127,7 +132,7 @@ describe TweetStream::Client do
|
|
127
132
|
|
128
133
|
it 'should call the on_limit if specified' do
|
129
134
|
limit = '{ "limit": { "track": 1234 } }'
|
130
|
-
@stream.should_receive(:
|
135
|
+
@stream.should_receive(:each).and_yield(limit)
|
131
136
|
@client.on_limit do |track|
|
132
137
|
track.should == 1234
|
133
138
|
end.track('abc')
|
@@ -136,17 +141,17 @@ describe TweetStream::Client do
|
|
136
141
|
context "using on_anything" do
|
137
142
|
it "yields the raw hash" do
|
138
143
|
hash = {:id => 1234}
|
139
|
-
@stream.should_receive(:
|
144
|
+
@stream.should_receive(:each).and_yield(hash.to_json)
|
140
145
|
yielded_hash = nil
|
141
146
|
@client.on_anything do |hash|
|
142
147
|
yielded_hash = hash
|
143
148
|
end.track('abc')
|
144
149
|
yielded_hash.should_not be_nil
|
145
|
-
yielded_hash
|
150
|
+
yielded_hash['id'].should == 1234
|
146
151
|
end
|
147
152
|
it 'yields itself if block has an arity of 2' do
|
148
153
|
hash = {:id => 1234}
|
149
|
-
@stream.should_receive(:
|
154
|
+
@stream.should_receive(:each).and_yield(hash.to_json)
|
150
155
|
yielded_client = nil
|
151
156
|
@client.on_anything do |_, client|
|
152
157
|
yielded_client = client
|
@@ -162,7 +167,7 @@ describe TweetStream::Client do
|
|
162
167
|
tweet[:id] = 123
|
163
168
|
tweet[:user][:screen_name] = 'monkey'
|
164
169
|
tweet[:text] = "Oo oo aa aa"
|
165
|
-
@stream.should_receive(:
|
170
|
+
@stream.should_receive(:each).and_yield(tweet.to_json)
|
166
171
|
yielded_status = nil
|
167
172
|
@client.on_timeline_status do |status|
|
168
173
|
yielded_status = status
|
@@ -173,7 +178,7 @@ describe TweetStream::Client do
|
|
173
178
|
yielded_status.text.should == 'Oo oo aa aa'
|
174
179
|
end
|
175
180
|
it 'yields itself if block has an arity of 2' do
|
176
|
-
@stream.should_receive(:
|
181
|
+
@stream.should_receive(:each).and_yield(sample_tweets[0].to_json)
|
177
182
|
yielded_client = nil
|
178
183
|
@client.on_timeline_status do |_, client|
|
179
184
|
yielded_client = client
|
@@ -188,18 +193,18 @@ describe TweetStream::Client do
|
|
188
193
|
direct_message = sample_direct_messages[0]
|
189
194
|
direct_message["direct_message"]["id"] = 1234
|
190
195
|
direct_message["direct_message"]["sender"]["screen_name"] = "coder"
|
191
|
-
@stream.should_receive(:
|
196
|
+
@stream.should_receive(:each).and_yield(direct_message.to_json)
|
192
197
|
yielded_dm = nil
|
193
198
|
@client.on_direct_message do |dm|
|
194
199
|
yielded_dm = dm
|
195
200
|
end.userstream
|
196
201
|
yielded_dm.should_not be_nil
|
197
202
|
yielded_dm.id.should == 1234
|
198
|
-
yielded_dm.
|
203
|
+
yielded_dm.sender.screen_name.should == "coder"
|
199
204
|
end
|
200
205
|
|
201
206
|
it 'yields itself if block has an arity of 2' do
|
202
|
-
@stream.should_receive(:
|
207
|
+
@stream.should_receive(:each).and_yield(sample_direct_messages[0].to_json)
|
203
208
|
yielded_client = nil
|
204
209
|
@client.on_direct_message do |_, client|
|
205
210
|
yielded_client = client
|
@@ -209,14 +214,14 @@ describe TweetStream::Client do
|
|
209
214
|
end
|
210
215
|
|
211
216
|
it 'should call on_error if a non-hash response is received' do
|
212
|
-
@stream.should_receive(:
|
217
|
+
@stream.should_receive(:each).and_yield('["favorited"]')
|
213
218
|
@client.on_error do |message|
|
214
219
|
message.should == 'Unexpected JSON object in stream: ["favorited"]'
|
215
220
|
end.track('abc')
|
216
221
|
end
|
217
222
|
|
218
223
|
it 'should call on_error if a json parse error occurs' do
|
219
|
-
@stream.should_receive(:
|
224
|
+
@stream.should_receive(:each).and_yield("{'a_key':}")
|
220
225
|
@client.on_error do |message|
|
221
226
|
message.should == "MultiJson::DecodeError occured in stream: {'a_key':}"
|
222
227
|
end.track('abc')
|
@@ -320,7 +325,7 @@ describe TweetStream::Client do
|
|
320
325
|
end
|
321
326
|
end
|
322
327
|
|
323
|
-
%w(on_delete on_limit on_inited on_reconnect).each do |proc_setter|
|
328
|
+
%w(on_delete on_limit on_inited on_reconnect on_no_data_received).each do |proc_setter|
|
324
329
|
describe "##{proc_setter}" do
|
325
330
|
it 'should set when a block is given' do
|
326
331
|
proc = Proc.new{|a,b| puts a }
|
@@ -334,23 +339,6 @@ describe TweetStream::Client do
|
|
334
339
|
end
|
335
340
|
end
|
336
341
|
|
337
|
-
describe '#on_interval' do
|
338
|
-
it 'should set when a block is given' do
|
339
|
-
@client.on_interval(5) { puts 'hi' }
|
340
|
-
@client.on_interval[0].should == 5
|
341
|
-
@client.on_interval[1].should be_kind_of(Proc)
|
342
|
-
end
|
343
|
-
|
344
|
-
it 'should should create a periodic timer' do
|
345
|
-
# need to figure out a better way to test this
|
346
|
-
# for now, using on_inited to stop the reactor
|
347
|
-
proc = Proc.new{ puts 'hi' }
|
348
|
-
EM.should_receive(:add_periodic_timer).once.with(5)
|
349
|
-
@client.on_inited { EM.stop }.on_interval(5, &proc)
|
350
|
-
@client.track('go')
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
342
|
describe '#stop' do
|
355
343
|
it 'should call EventMachine::stop_event_loop' do
|
356
344
|
EventMachine.should_receive :stop_event_loop
|
@@ -374,17 +362,18 @@ describe TweetStream::Client do
|
|
374
362
|
|
375
363
|
describe '#stop_stream' do
|
376
364
|
before(:each) do
|
377
|
-
@stream = stub("Twitter::
|
365
|
+
@stream = stub("EM::Twitter::Client",
|
378
366
|
:connect => true,
|
379
367
|
:unbind => true,
|
380
|
-
:
|
368
|
+
:each => true,
|
381
369
|
:on_error => true,
|
382
370
|
:on_max_reconnects => true,
|
383
371
|
:on_reconnect => true,
|
384
372
|
:connection_completed => true,
|
373
|
+
:on_no_data_received => true,
|
385
374
|
:stop => true
|
386
375
|
)
|
387
|
-
Twitter::
|
376
|
+
EM::Twitter::Client.stub!(:connect).and_return(@stream)
|
388
377
|
@client = TweetStream::Client.new
|
389
378
|
@client.connect('/')
|
390
379
|
end
|
@@ -400,6 +389,46 @@ describe TweetStream::Client do
|
|
400
389
|
end
|
401
390
|
end
|
402
391
|
|
392
|
+
describe "basic auth" do
|
393
|
+
before do
|
394
|
+
TweetStream.configure do |config|
|
395
|
+
config.username = 'tweetstream'
|
396
|
+
config.password = 'rubygem'
|
397
|
+
config.auth_method = :basic
|
398
|
+
end
|
399
|
+
@client = TweetStream::Client.new
|
400
|
+
|
401
|
+
@stream = stub("EM::Twitter::Client",
|
402
|
+
:connect => true,
|
403
|
+
:unbind => true,
|
404
|
+
:each => true,
|
405
|
+
:on_error => true,
|
406
|
+
:on_max_reconnects => true,
|
407
|
+
:on_reconnect => true,
|
408
|
+
:connection_completed => true,
|
409
|
+
:on_no_data_received => true
|
410
|
+
)
|
411
|
+
EM.stub!(:run).and_yield
|
412
|
+
EM::Twitter::Client.stub!(:connect).and_return(@stream)
|
413
|
+
end
|
414
|
+
|
415
|
+
it 'should try to connect via a JSON stream with oauth' do
|
416
|
+
EM::Twitter::Client.should_receive(:connect).with(
|
417
|
+
:path => URI.parse('/1/statuses/filter.json'),
|
418
|
+
:method => 'POST',
|
419
|
+
:user_agent => TweetStream::Configuration::DEFAULT_USER_AGENT,
|
420
|
+
:on_inited => nil,
|
421
|
+
:params => {:track => 'monday'},
|
422
|
+
:basic => {
|
423
|
+
:username => 'tweetstream',
|
424
|
+
:password => 'rubygem'
|
425
|
+
}
|
426
|
+
).and_return(@stream)
|
427
|
+
|
428
|
+
@client.track('monday')
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
403
432
|
describe "oauth" do
|
404
433
|
describe '#start' do
|
405
434
|
before do
|
@@ -412,33 +441,32 @@ describe TweetStream::Client do
|
|
412
441
|
end
|
413
442
|
@client = TweetStream::Client.new
|
414
443
|
|
415
|
-
@stream = stub("Twitter::
|
444
|
+
@stream = stub("EM::Twitter::Client",
|
416
445
|
:connect => true,
|
417
446
|
:unbind => true,
|
418
|
-
:
|
447
|
+
:each => true,
|
419
448
|
:on_error => true,
|
420
449
|
:on_max_reconnects => true,
|
421
450
|
:on_reconnect => true,
|
422
|
-
:connection_completed => true
|
451
|
+
:connection_completed => true,
|
452
|
+
:on_no_data_received => true
|
423
453
|
)
|
424
454
|
EM.stub!(:run).and_yield
|
425
|
-
Twitter::
|
455
|
+
EM::Twitter::Client.stub!(:connect).and_return(@stream)
|
426
456
|
end
|
427
457
|
|
428
458
|
it 'should try to connect via a JSON stream with oauth' do
|
429
|
-
Twitter::
|
459
|
+
EM::Twitter::Client.should_receive(:connect).with(
|
430
460
|
:path => URI.parse('/1/statuses/filter.json'),
|
431
461
|
:method => 'POST',
|
432
462
|
:user_agent => TweetStream::Configuration::DEFAULT_USER_AGENT,
|
433
463
|
:on_inited => nil,
|
434
|
-
:
|
435
|
-
:params => {},
|
436
|
-
:ssl => true,
|
464
|
+
:params => {:track => 'monday'},
|
437
465
|
:oauth => {
|
438
466
|
:consumer_key => '123456789',
|
439
467
|
:consumer_secret => 'abcdefghijklmnopqrstuvwxyz',
|
440
|
-
:
|
441
|
-
:
|
468
|
+
:token => '123456789',
|
469
|
+
:token_secret => 'abcdefghijklmnopqrstuvwxyz'
|
442
470
|
}
|
443
471
|
).and_return(@stream)
|
444
472
|
|
@@ -447,15 +475,94 @@ describe TweetStream::Client do
|
|
447
475
|
|
448
476
|
context "when calling #userstream" do
|
449
477
|
it "sends the userstream host" do
|
450
|
-
Twitter::
|
478
|
+
EM::Twitter::Client.should_receive(:connect).with(hash_including(:host => "userstream.twitter.com")).and_return(@stream)
|
451
479
|
@client.userstream
|
452
480
|
end
|
453
481
|
|
454
482
|
it "uses the userstream uri" do
|
455
|
-
Twitter::
|
483
|
+
EM::Twitter::Client.should_receive(:connect).with(hash_including(:path => "/2/user.json")).and_return(@stream)
|
456
484
|
@client.userstream
|
457
485
|
end
|
458
486
|
end
|
487
|
+
|
488
|
+
context "when calling #sitestream" do
|
489
|
+
it "sends the sitestream host" do
|
490
|
+
EM::Twitter::Client.should_receive(:connect).with(hash_including(:host => "sitestream.twitter.com")).and_return(@stream)
|
491
|
+
@client.sitestream
|
492
|
+
end
|
493
|
+
|
494
|
+
it "uses the userstream uri" do
|
495
|
+
EM::Twitter::Client.should_receive(:connect).with(hash_including(:path => "/2b/site.json")).and_return(@stream)
|
496
|
+
@client.sitestream
|
497
|
+
end
|
498
|
+
|
499
|
+
it 'supports the "with followings"' do
|
500
|
+
@client.should_receive(:start).once.with('', hash_including(:with => 'followings')).and_return(@stream)
|
501
|
+
@client.sitestream(['115192457'], :followings => true)
|
502
|
+
end
|
503
|
+
|
504
|
+
context 'control management' do
|
505
|
+
before do
|
506
|
+
@control_response = {"control" =>
|
507
|
+
{
|
508
|
+
"control_uri" =>"/2b/site/c/01_225167_334389048B872A533002B34D73F8C29FD09EFC50"
|
509
|
+
}
|
510
|
+
}
|
511
|
+
end
|
512
|
+
it 'assigns the control_uri' do
|
513
|
+
@stream.should_receive(:each).and_yield(@control_response.to_json)
|
514
|
+
@client.sitestream
|
515
|
+
|
516
|
+
@client.control_uri.should eq("/2b/site/c/01_225167_334389048B872A533002B34D73F8C29FD09EFC50")
|
517
|
+
end
|
518
|
+
|
519
|
+
it 'instantiates a SiteStreamClient' do
|
520
|
+
@stream.should_receive(:each).and_yield(@control_response.to_json)
|
521
|
+
@client.sitestream
|
522
|
+
|
523
|
+
@client.control.should be_kind_of(TweetStream::SiteStreamClient)
|
524
|
+
end
|
525
|
+
|
526
|
+
it "passes the client's on_error to the SiteStreamClient" do
|
527
|
+
called = false
|
528
|
+
@client.on_error { |err| called = true }
|
529
|
+
@stream.should_receive(:each).and_yield(@control_response.to_json)
|
530
|
+
@client.sitestream
|
531
|
+
|
532
|
+
@client.control.on_error.call
|
533
|
+
|
534
|
+
called.should be_true
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
context 'data handling' do
|
539
|
+
before do
|
540
|
+
tweet = sample_tweets[0]
|
541
|
+
@ss_message = {'for_user' => '12345', 'message' => {'id' => 123, 'user' => {'screen_name' => 'monkey'}, 'text' => 'Oo oo aa aa'}}
|
542
|
+
end
|
543
|
+
|
544
|
+
it 'yields a site stream message' do
|
545
|
+
@stream.should_receive(:each).and_yield(@ss_message.to_json)
|
546
|
+
yielded_status = nil
|
547
|
+
@client.sitestream do |message|
|
548
|
+
yielded_status = message
|
549
|
+
end
|
550
|
+
yielded_status.should_not be_nil
|
551
|
+
yielded_status['for_user'].should == '12345'
|
552
|
+
yielded_status['message']['user']['screen_name'].should == 'monkey'
|
553
|
+
yielded_status['message']['text'].should == 'Oo oo aa aa'
|
554
|
+
end
|
555
|
+
it 'yields itself if block has an arity of 2' do
|
556
|
+
@stream.should_receive(:each).and_yield(@ss_message.to_json)
|
557
|
+
yielded_client = nil
|
558
|
+
@client.sitestream do |_, client|
|
559
|
+
yielded_client = client
|
560
|
+
end
|
561
|
+
yielded_client.should_not be_nil
|
562
|
+
yielded_client.should == @client
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
459
566
|
end
|
460
567
|
end
|
461
568
|
|