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.

@@ -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.default_adapter
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
@@ -1,3 +1,3 @@
1
1
  module TweetStream
2
- VERSION = '1.1.5'
2
+ VERSION = '2.0.0' unless defined?(TweetStream::VERSION)
3
3
  end
@@ -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.username = 'abc'
7
- config.password = 'def'
8
- config.auth_method = :basic
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::JSONStream",
52
+ @stream = stub("EM::Twitter::Client",
52
53
  :connect => true,
53
54
  :unbind => true,
54
- :each_item => true,
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::JSONStream.stub!(:connect).and_return(@stream)
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::JSONStream.should_receive(:connect).with(
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
- :filters => 'monday',
71
- :params => {},
72
- :ssl => true,
73
- :auth => 'abc:def'
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 '#each_item' do
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(:each_item).and_yield(sample_tweets[0].to_json)
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 TweetStream::Status' do
88
- @stream.should_receive(:each_item).and_yield(sample_tweets[0].to_json)
89
- @client.track('abc'){|s| s.should be_kind_of(TweetStream::Status)}
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(:each_item).and_yield(sample_tweets[0].to_json)
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(:each_item).and_yield(tweet.to_json)
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(:each_item).and_yield(scrub_geo)
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(:each_item).and_yield(delete)
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(:each_item).and_yield(limit)
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(:each_item).and_yield(hash.to_json)
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.id.should == 1234
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(:each_item).and_yield(hash.to_json)
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(:each_item).and_yield(tweet.to_json)
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(:each_item).and_yield(sample_tweets[0].to_json)
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(:each_item).and_yield(direct_message.to_json)
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.user.screen_name.should == "coder"
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(:each_item).and_yield(sample_direct_messages[0].to_json)
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(:each_item).and_yield('["favorited"]')
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(:each_item).and_yield("{'a_key':}")
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::JSONStream",
365
+ @stream = stub("EM::Twitter::Client",
378
366
  :connect => true,
379
367
  :unbind => true,
380
- :each_item => true,
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::JSONStream.stub!(:connect).and_return(@stream)
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::JSONStream",
444
+ @stream = stub("EM::Twitter::Client",
416
445
  :connect => true,
417
446
  :unbind => true,
418
- :each_item => true,
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::JSONStream.stub!(:connect).and_return(@stream)
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::JSONStream.should_receive(:connect).with(
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
- :filters => 'monday',
435
- :params => {},
436
- :ssl => true,
464
+ :params => {:track => 'monday'},
437
465
  :oauth => {
438
466
  :consumer_key => '123456789',
439
467
  :consumer_secret => 'abcdefghijklmnopqrstuvwxyz',
440
- :access_key => '123456789',
441
- :access_secret => 'abcdefghijklmnopqrstuvwxyz'
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::JSONStream.should_receive(:connect).with(hash_including(:host => "userstream.twitter.com")).and_return(@stream)
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::JSONStream.should_receive(:connect).with(hash_including(:path => "/2/user.json")).and_return(@stream)
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