tweetwine 0.4.1 → 0.4.2
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.rdoc +6 -0
- data/Rakefile +22 -23
- data/lib/tweetwine/cli.rb +167 -165
- data/lib/tweetwine/config.rb +3 -2
- data/lib/tweetwine/exceptions.rb +1 -0
- data/lib/tweetwine/version.rb +1 -1
- data/project.rb +16 -16
- data/test/fixture/{config_example.yaml → config_integration.yaml} +0 -0
- data/test/fixture/oauth.rb +11 -11
- data/test/{test_helper.rb → helper.rb} +16 -7
- data/test/{example/authorization_example.rb → integration/authorization_test.rb} +17 -17
- data/test/integration/global_options_test.rb +67 -0
- data/test/integration/helper.rb +70 -0
- data/test/integration/invalid_config_file_test.rb +28 -0
- data/test/integration/search_statuses_test.rb +81 -0
- data/test/integration/show_followers_test.rb +24 -0
- data/test/integration/show_friends_test.rb +24 -0
- data/test/integration/show_home_test.rb +47 -0
- data/test/integration/show_mentions_test.rb +24 -0
- data/test/integration/show_user_test.rb +48 -0
- data/test/integration/update_status_test.rb +199 -0
- data/test/integration/use_http_proxy_test.rb +71 -0
- data/test/{example/user_help_example.rb → integration/user_help_test.rb} +36 -36
- data/test/unit/character_encoding_test.rb +19 -15
- data/test/unit/cli_test.rb +9 -10
- data/test/unit/config_test.rb +73 -71
- data/test/unit/helper.rb +108 -0
- data/test/unit/http_test.rb +39 -39
- data/test/unit/oauth_test.rb +15 -16
- data/test/unit/obfuscate_test.rb +4 -4
- data/test/unit/option_parser_test.rb +12 -12
- data/test/unit/promise_test.rb +10 -10
- data/test/unit/support_test.rb +44 -45
- data/test/unit/tweet_helper.rb +1 -1
- data/test/unit/tweet_test.rb +42 -42
- data/test/unit/twitter_test.rb +300 -303
- data/test/unit/ui_test.rb +310 -312
- data/test/unit/uri_test.rb +7 -7
- data/test/unit/url_shortener_test.rb +77 -79
- data/tweetwine.gemspec +6 -15
- metadata +55 -145
- data/test/example/example_helper.rb +0 -58
- data/test/example/global_options_example.rb +0 -64
- data/test/example/search_statuses_example.rb +0 -76
- data/test/example/show_followers_example.rb +0 -24
- data/test/example/show_friends_example.rb +0 -24
- data/test/example/show_home_example.rb +0 -44
- data/test/example/show_mentions_example.rb +0 -24
- data/test/example/show_user_example.rb +0 -44
- data/test/example/update_status_example.rb +0 -183
- data/test/example/use_http_proxy_example.rb +0 -68
- data/test/unit/unit_helper.rb +0 -111
data/test/unit/twitter_test.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'unit/helper'
|
4
4
|
|
5
|
-
module Tweetwine::Test
|
5
|
+
module Tweetwine::Test::Unit
|
6
6
|
|
7
|
-
class ClientTest <
|
8
|
-
|
7
|
+
class ClientTest < TestCase
|
8
|
+
before do
|
9
9
|
@config = {
|
10
10
|
:num_tweets => 20,
|
11
11
|
:page => 1
|
@@ -13,38 +13,38 @@ class ClientTest < UnitTestCase
|
|
13
13
|
stub_config @config
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
describe "for initialization" do
|
17
|
+
it "uses default number of statuses if not configured" do
|
18
18
|
@twitter = Twitter.new
|
19
19
|
assert_equal @config[:num_tweets], @twitter.num_tweets
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
it "uses configured number of statuses if in allowed range" do
|
23
23
|
@twitter = Twitter.new(:num_tweets => 12)
|
24
24
|
assert_equal 12, @twitter.num_tweets
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
it "raises exception if configured number of status not in allowed range" do
|
28
|
+
assert_raises(CommandLineError) { Twitter.new(:num_tweets => 0) }
|
29
29
|
end
|
30
30
|
|
31
|
-
|
31
|
+
it "uses default page number if not configured otherwise" do
|
32
32
|
@twitter = Twitter.new
|
33
33
|
assert_equal @config[:page], @twitter.page
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
it "uses configured page number if in allowed range" do
|
37
37
|
@twitter = Twitter.new(:page => 12)
|
38
38
|
assert_equal 12, @twitter.page
|
39
39
|
end
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
it "raises exception if configured page number not in allowed range" do
|
42
|
+
assert_raises(CommandLineError) { Twitter.new(:page => 0) }
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
describe "at runtime" do
|
47
|
+
before do
|
48
48
|
mock_http
|
49
49
|
mock_oauth
|
50
50
|
mock_ui
|
@@ -58,7 +58,7 @@ class ClientTest < UnitTestCase
|
|
58
58
|
@search_api_query_str = "page=#{@config[:page]}&rpp=#{@config[:num_tweets]}"
|
59
59
|
end
|
60
60
|
|
61
|
-
|
61
|
+
it "skips showing an invalid tweet" do
|
62
62
|
invalid_from_user = nil
|
63
63
|
twitter_records, internal_records = create_rest_api_status_records(
|
64
64
|
{
|
@@ -79,7 +79,7 @@ class ClientTest < UnitTestCase
|
|
79
79
|
@twitter.home
|
80
80
|
end
|
81
81
|
|
82
|
-
|
82
|
+
it "fetches friends' statuses (home view)" do
|
83
83
|
twitter_records, internal_records = create_rest_api_status_records(
|
84
84
|
{
|
85
85
|
:from_user => "zanzibar",
|
@@ -98,7 +98,7 @@ class ClientTest < UnitTestCase
|
|
98
98
|
@twitter.home
|
99
99
|
end
|
100
100
|
|
101
|
-
|
101
|
+
it "fetches mentions" do
|
102
102
|
twitter_records, internal_records = create_rest_api_status_records(
|
103
103
|
{
|
104
104
|
:from_user => "zanzibar",
|
@@ -119,7 +119,7 @@ class ClientTest < UnitTestCase
|
|
119
119
|
@twitter.mentions
|
120
120
|
end
|
121
121
|
|
122
|
-
|
122
|
+
it "fetches a specific user's statuses, when user is given as argument" do
|
123
123
|
username = "spoonman"
|
124
124
|
twitter_records, internal_records = create_rest_api_status_records({
|
125
125
|
:from_user => username,
|
@@ -133,7 +133,7 @@ class ClientTest < UnitTestCase
|
|
133
133
|
@twitter.user(username)
|
134
134
|
end
|
135
135
|
|
136
|
-
|
136
|
+
it "fetches a specific user's statuses, with user being the authenticated user itself when given no argument" do
|
137
137
|
twitter_records, internal_records = create_rest_api_status_records({
|
138
138
|
:from_user => @username,
|
139
139
|
:status => "wassup?"
|
@@ -146,30 +146,197 @@ class ClientTest < UnitTestCase
|
|
146
146
|
@twitter.user
|
147
147
|
end
|
148
148
|
|
149
|
-
|
150
|
-
|
151
|
-
|
149
|
+
it "posts a status update via argument, when positive confirmation" do
|
150
|
+
status = "wondering around"
|
151
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
152
|
+
:from_user => @username,
|
153
|
+
:status => status
|
154
|
+
})
|
155
|
+
@oauth.expects(:request_signer)
|
156
|
+
http_subresource = mock
|
157
|
+
http_subresource.expects(:post).
|
158
|
+
with({ :status => status }).
|
159
|
+
returns(twitter_records[0].to_json)
|
160
|
+
@rest_api.expects(:[]).
|
161
|
+
with("statuses/update.json").
|
162
|
+
returns(http_subresource)
|
163
|
+
@ui.expects(:confirm).with("Really send?").returns(true)
|
164
|
+
@ui.expects(:show_status_preview).with(status)
|
165
|
+
@ui.expects(:info).with("Sent status update.\n\n")
|
166
|
+
@ui.expects(:show_tweets).with(internal_records)
|
167
|
+
@twitter.update(status)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "posts a status update via prompt, when positive confirmation" do
|
171
|
+
status = "wondering around"
|
172
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
173
|
+
:from_user => @username,
|
174
|
+
:status => status
|
175
|
+
})
|
176
|
+
@oauth.expects(:request_signer)
|
177
|
+
http_subresource = mock
|
178
|
+
http_subresource.expects(:post).
|
179
|
+
with({ :status => status }).
|
180
|
+
returns(twitter_records[0].to_json)
|
181
|
+
@rest_api.expects(:[]).
|
182
|
+
with("statuses/update.json").
|
183
|
+
returns(http_subresource)
|
184
|
+
@ui.expects(:prompt).with("Status update").returns(status)
|
185
|
+
@ui.expects(:show_status_preview).with(status)
|
186
|
+
@ui.expects(:confirm).with("Really send?").returns(true)
|
187
|
+
@ui.expects(:info).with("Sent status update.\n\n")
|
188
|
+
@ui.expects(:show_tweets).with(internal_records)
|
189
|
+
@twitter.update
|
190
|
+
end
|
191
|
+
|
192
|
+
it "cancels a status update via argument, when negative confirmation" do
|
193
|
+
status = "wondering around"
|
194
|
+
@rest_api.expects(:[]).never
|
195
|
+
@ui.expects(:show_status_preview).with(status)
|
196
|
+
@ui.expects(:confirm).with("Really send?").returns(false)
|
197
|
+
@ui.expects(:info).with("Cancelled.")
|
198
|
+
@ui.expects(:show_tweets).never
|
199
|
+
@twitter.update(status)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "cancels a status update via prompt, when negative confirmation" do
|
203
|
+
status = "wondering around"
|
204
|
+
@rest_api.expects(:[]).never
|
205
|
+
@ui.expects(:prompt).with("Status update").returns(status)
|
206
|
+
@ui.expects(:show_status_preview).with(status)
|
207
|
+
@ui.expects(:confirm).with("Really send?").returns(false)
|
208
|
+
@ui.expects(:info).with("Cancelled.")
|
209
|
+
@ui.expects(:show_tweets).never
|
210
|
+
@twitter.update
|
211
|
+
end
|
212
|
+
|
213
|
+
it "cancels a status update via argument, when empty status" do
|
214
|
+
@rest_api.expects(:[]).never
|
215
|
+
@ui.expects(:prompt).with("Status update").returns("")
|
216
|
+
@ui.expects(:confirm).never
|
217
|
+
@ui.expects(:info).with("Cancelled.")
|
218
|
+
@ui.expects(:show_tweets).never
|
219
|
+
@twitter.update("")
|
220
|
+
end
|
221
|
+
|
222
|
+
it "cancels a status update via prompt, when empty status" do
|
223
|
+
@rest_api.expects(:[]).never
|
224
|
+
@ui.expects(:prompt).with("Status update").returns("")
|
225
|
+
@ui.expects(:confirm).never
|
226
|
+
@ui.expects(:info).with("Cancelled.")
|
227
|
+
@ui.expects(:show_tweets).never
|
228
|
+
@twitter.update
|
229
|
+
end
|
230
|
+
|
231
|
+
it "removes excess whitespace around a status update" do
|
232
|
+
whitespaced_status = " oh, i was sloppy \t "
|
233
|
+
stripped_status = "oh, i was sloppy"
|
234
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
235
|
+
:from_user => @username,
|
236
|
+
:status => stripped_status
|
237
|
+
})
|
238
|
+
@oauth.expects(:request_signer)
|
239
|
+
http_subresource = mock
|
240
|
+
http_subresource.expects(:post).
|
241
|
+
with({ :status => stripped_status }).
|
242
|
+
returns(twitter_records[0].to_json)
|
243
|
+
@rest_api.expects(:[]).
|
244
|
+
with("statuses/update.json").
|
245
|
+
returns(http_subresource)
|
246
|
+
@ui.expects(:show_status_preview).with(stripped_status)
|
247
|
+
@ui.expects(:confirm).with("Really send?").returns(true)
|
248
|
+
@ui.expects(:info).with("Sent status update.\n\n")
|
249
|
+
@ui.expects(:show_tweets).with(internal_records)
|
250
|
+
@twitter.update(whitespaced_status)
|
251
|
+
end
|
252
|
+
|
253
|
+
it "truncates a status update with too long argument and warn the user" do
|
254
|
+
truncated_status = "ab c" * 35 # 4 * 35 = 140
|
255
|
+
long_status = "#{truncated_status} dd"
|
256
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
257
|
+
:from_user => @username,
|
258
|
+
:status => truncated_status
|
259
|
+
})
|
260
|
+
@oauth.expects(:request_signer)
|
261
|
+
http_subresource = mock
|
262
|
+
http_subresource.expects(:post).
|
263
|
+
with({ :status => truncated_status }).
|
264
|
+
returns(twitter_records[0].to_json)
|
265
|
+
@rest_api.expects(:[]).
|
266
|
+
with("statuses/update.json").
|
267
|
+
returns(http_subresource)
|
268
|
+
@ui.expects(:warn).with("Status will be truncated.")
|
269
|
+
@ui.expects(:show_status_preview).with(truncated_status)
|
270
|
+
@ui.expects(:confirm).with("Really send?").returns(true)
|
271
|
+
@ui.expects(:info).with("Sent status update.\n\n")
|
272
|
+
@ui.expects(:show_tweets).with(internal_records)
|
273
|
+
@twitter.update(long_status)
|
274
|
+
end
|
275
|
+
|
276
|
+
if defined? Encoding
|
277
|
+
it "encodes status in UTF-8 (String supports encoding)" do
|
278
|
+
status_utf8, status_latin1 = "résumé", "résumé".encode('ISO-8859-1')
|
152
279
|
twitter_records, internal_records = create_rest_api_status_records({
|
153
280
|
:from_user => @username,
|
154
|
-
:status =>
|
281
|
+
:status => status_utf8
|
155
282
|
})
|
156
283
|
@oauth.expects(:request_signer)
|
157
284
|
http_subresource = mock
|
158
285
|
http_subresource.expects(:post).
|
159
|
-
with({ :status =>
|
286
|
+
with({ :status => status_utf8 }).
|
160
287
|
returns(twitter_records[0].to_json)
|
161
288
|
@rest_api.expects(:[]).
|
162
289
|
with("statuses/update.json").
|
163
290
|
returns(http_subresource)
|
164
291
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
165
|
-
@ui.expects(:show_status_preview).with(
|
292
|
+
@ui.expects(:show_status_preview).with(status_latin1)
|
166
293
|
@ui.expects(:info).with("Sent status update.\n\n")
|
167
294
|
@ui.expects(:show_tweets).with(internal_records)
|
168
|
-
@twitter.update(
|
295
|
+
@twitter.update(status_latin1)
|
296
|
+
end
|
297
|
+
else
|
298
|
+
it "encodes status in UTF-8 (String does not support encoding)" do
|
299
|
+
CharacterEncoding.forget_guess
|
300
|
+
tmp_kcode('NONE') do
|
301
|
+
tmp_env(:LANG => 'ISO-8859-1') do
|
302
|
+
status_utf8, status_latin1 = "r\xc3\xa9sum\xc3\xa9", "r\xe9sum\xe9"
|
303
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
304
|
+
:from_user => @username,
|
305
|
+
:status => status_utf8
|
306
|
+
})
|
307
|
+
@oauth.expects(:request_signer)
|
308
|
+
http_subresource = mock
|
309
|
+
http_subresource.expects(:post).
|
310
|
+
with({ :status => status_utf8 }).
|
311
|
+
returns(twitter_records[0].to_json)
|
312
|
+
@rest_api.expects(:[]).
|
313
|
+
with("statuses/update.json").
|
314
|
+
returns(http_subresource)
|
315
|
+
@ui.expects(:confirm).with("Really send?").returns(true)
|
316
|
+
@ui.expects(:show_status_preview).with(status_latin1)
|
317
|
+
@ui.expects(:info).with("Sent status update.\n\n")
|
318
|
+
@ui.expects(:show_tweets).with(internal_records)
|
319
|
+
@twitter.update(status_latin1)
|
320
|
+
end
|
321
|
+
end
|
169
322
|
end
|
323
|
+
end
|
170
324
|
|
171
|
-
|
172
|
-
|
325
|
+
describe "with URL shortening" do
|
326
|
+
before do
|
327
|
+
mock_url_shortener
|
328
|
+
stub_config(
|
329
|
+
:shorten_urls => {
|
330
|
+
:service_url => "http://shorten.it/create",
|
331
|
+
:method => "post",
|
332
|
+
:url_param_name => "url",
|
333
|
+
:xpath_selector => "//input[@id='short_url']/@value"
|
334
|
+
})
|
335
|
+
end
|
336
|
+
|
337
|
+
it "does not shorten URLs if not configured" do
|
338
|
+
stub_config
|
339
|
+
status = "reading http://www.w3.org/TR/1999/REC-xpath-19991116"
|
173
340
|
twitter_records, internal_records = create_rest_api_status_records({
|
174
341
|
:from_user => @username,
|
175
342
|
:status => status
|
@@ -179,310 +346,142 @@ class ClientTest < UnitTestCase
|
|
179
346
|
http_subresource.expects(:post).
|
180
347
|
with({ :status => status }).
|
181
348
|
returns(twitter_records[0].to_json)
|
349
|
+
@url_shortener.expects(:shorten).never
|
182
350
|
@rest_api.expects(:[]).
|
183
351
|
with("statuses/update.json").
|
184
352
|
returns(http_subresource)
|
185
|
-
@ui.expects(:prompt).with("Status update").returns(status)
|
186
|
-
@ui.expects(:show_status_preview).with(status)
|
187
353
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
354
|
+
@ui.expects(:show_status_preview).with(status)
|
188
355
|
@ui.expects(:info).with("Sent status update.\n\n")
|
189
356
|
@ui.expects(:show_tweets).with(internal_records)
|
190
|
-
@twitter.update
|
191
|
-
end
|
192
|
-
|
193
|
-
should "cancel a status update via argument, when negative confirmation" do
|
194
|
-
status = "wondering around"
|
195
|
-
@rest_api.expects(:[]).never
|
196
|
-
@ui.expects(:show_status_preview).with(status)
|
197
|
-
@ui.expects(:confirm).with("Really send?").returns(false)
|
198
|
-
@ui.expects(:info).with("Cancelled.")
|
199
|
-
@ui.expects(:show_tweets).never
|
200
357
|
@twitter.update(status)
|
201
358
|
end
|
202
359
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
@
|
218
|
-
|
219
|
-
|
220
|
-
@
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
@
|
225
|
-
@ui.expects(:
|
226
|
-
@
|
227
|
-
@ui.expects(:info).with("Cancelled.")
|
228
|
-
@ui.expects(:show_tweets).never
|
229
|
-
@twitter.update
|
360
|
+
it "shortens HTTP and HTTPS URLs" do
|
361
|
+
long_urls = ["http://www.google.fi/search?q=ruby+nokogiri&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a", "https://twitter.com/#!/messages"]
|
362
|
+
long_status = long_urls.join(" and ")
|
363
|
+
short_urls = ["http://shorten.it/2k7i8", "http://shorten.it/2k7mk"]
|
364
|
+
shortened_status = short_urls.join(" and ")
|
365
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
366
|
+
:from_user => @username,
|
367
|
+
:status => shortened_status
|
368
|
+
})
|
369
|
+
@oauth.expects(:request_signer)
|
370
|
+
http_subresource = mock
|
371
|
+
http_subresource.expects(:post).
|
372
|
+
with({ :status => shortened_status }).
|
373
|
+
returns(twitter_records[0].to_json)
|
374
|
+
@rest_api.expects(:[]).
|
375
|
+
with("statuses/update.json").
|
376
|
+
returns(http_subresource)
|
377
|
+
@url_shortener.expects(:shorten).with(long_urls.first).returns(short_urls.first)
|
378
|
+
@url_shortener.expects(:shorten).with(long_urls.last).returns(short_urls.last)
|
379
|
+
@ui.expects(:show_status_preview).with(shortened_status)
|
380
|
+
@ui.expects(:confirm).with("Really send?").returns(true)
|
381
|
+
@ui.expects(:info).with("Sent status update.\n\n")
|
382
|
+
@ui.expects(:show_tweets).with(internal_records)
|
383
|
+
@twitter.update(long_status)
|
230
384
|
end
|
231
385
|
|
232
|
-
|
233
|
-
|
234
|
-
|
386
|
+
it "discards obviously invalid shortened URLs, using originals instead" do
|
387
|
+
long_urls = ["http://www.google.fi/", "http://www.w3.org/TR/1999/REC-xpath-19991116"]
|
388
|
+
status = long_urls.join(" and ")
|
389
|
+
short_urls = [nil, ""]
|
235
390
|
twitter_records, internal_records = create_rest_api_status_records({
|
236
391
|
:from_user => @username,
|
237
|
-
:status =>
|
392
|
+
:status => status
|
238
393
|
})
|
239
394
|
@oauth.expects(:request_signer)
|
240
395
|
http_subresource = mock
|
241
396
|
http_subresource.expects(:post).
|
242
|
-
with({ :status =>
|
397
|
+
with({ :status => status }).
|
243
398
|
returns(twitter_records[0].to_json)
|
244
399
|
@rest_api.expects(:[]).
|
245
400
|
with("statuses/update.json").
|
246
401
|
returns(http_subresource)
|
247
|
-
@
|
402
|
+
@url_shortener.expects(:shorten).with(long_urls.first).returns(short_urls.first)
|
403
|
+
@url_shortener.expects(:shorten).with(long_urls.last).returns(short_urls.last)
|
404
|
+
@ui.expects(:show_status_preview).with(status)
|
248
405
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
249
406
|
@ui.expects(:info).with("Sent status update.\n\n")
|
250
407
|
@ui.expects(:show_tweets).with(internal_records)
|
251
|
-
@twitter.update(
|
408
|
+
@twitter.update(status)
|
252
409
|
end
|
253
410
|
|
254
|
-
|
255
|
-
|
256
|
-
long_status = "
|
411
|
+
it "reuses a shortened URL for duplicate long URLs" do
|
412
|
+
long_urls = ["http://www.w3.org/TR/1999/REC-xpath-19991116"] * 2
|
413
|
+
long_status = long_urls.join(" and ")
|
414
|
+
short_url = "http://shorten.it/2k7mk"
|
415
|
+
short_status = ([short_url] * 2).join(" and ")
|
257
416
|
twitter_records, internal_records = create_rest_api_status_records({
|
258
417
|
:from_user => @username,
|
259
|
-
:status =>
|
418
|
+
:status => short_status
|
260
419
|
})
|
261
420
|
@oauth.expects(:request_signer)
|
262
421
|
http_subresource = mock
|
263
422
|
http_subresource.expects(:post).
|
264
|
-
with({ :status =>
|
423
|
+
with({ :status => short_status }).
|
265
424
|
returns(twitter_records[0].to_json)
|
266
425
|
@rest_api.expects(:[]).
|
267
426
|
with("statuses/update.json").
|
268
427
|
returns(http_subresource)
|
269
|
-
@
|
270
|
-
@ui.expects(:show_status_preview).with(
|
428
|
+
@url_shortener.expects(:shorten).with(long_urls.first).returns(short_url)
|
429
|
+
@ui.expects(:show_status_preview).with(short_status)
|
271
430
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
272
431
|
@ui.expects(:info).with("Sent status update.\n\n")
|
273
432
|
@ui.expects(:show_tweets).with(internal_records)
|
274
433
|
@twitter.update(long_status)
|
275
434
|
end
|
276
435
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
436
|
+
describe "in erroneous situations" do
|
437
|
+
before do
|
438
|
+
@url = "http://www.w3.org/TR/1999/REC-xpath-19991116"
|
439
|
+
@status = "skimming through #{@url}"
|
440
|
+
@twitter_records, @internal_records = create_rest_api_status_records({
|
281
441
|
:from_user => @username,
|
282
|
-
:status =>
|
442
|
+
:status => @status
|
283
443
|
})
|
284
|
-
@oauth.expects(:request_signer)
|
285
|
-
http_subresource = mock
|
286
|
-
http_subresource.expects(:post).
|
287
|
-
with({ :status => status_utf8 }).
|
288
|
-
returns(twitter_records[0].to_json)
|
289
|
-
@rest_api.expects(:[]).
|
290
|
-
with("statuses/update.json").
|
291
|
-
returns(http_subresource)
|
292
|
-
@ui.expects(:confirm).with("Really send?").returns(true)
|
293
|
-
@ui.expects(:show_status_preview).with(status_latin1)
|
294
|
-
@ui.expects(:info).with("Sent status update.\n\n")
|
295
|
-
@ui.expects(:show_tweets).with(internal_records)
|
296
|
-
@twitter.update(status_latin1)
|
297
|
-
end
|
298
|
-
else
|
299
|
-
should "encode status in UTF-8 (String does not support encoding)" do
|
300
|
-
tmp_kcode('NONE') do
|
301
|
-
tmp_env(:LANG => 'ISO-8859-1') do
|
302
|
-
status_utf8, status_latin1 = "r\xc3\xa9sum\xc3\xa9", "r\xe9sum\xe9"
|
303
|
-
twitter_records, internal_records = create_rest_api_status_records({
|
304
|
-
:from_user => @username,
|
305
|
-
:status => status_utf8
|
306
|
-
})
|
307
|
-
@oauth.expects(:request_signer)
|
308
|
-
http_subresource = mock
|
309
|
-
http_subresource.expects(:post).
|
310
|
-
with({ :status => status_utf8 }).
|
311
|
-
returns(twitter_records[0].to_json)
|
312
|
-
@rest_api.expects(:[]).
|
313
|
-
with("statuses/update.json").
|
314
|
-
returns(http_subresource)
|
315
|
-
@ui.expects(:confirm).with("Really send?").returns(true)
|
316
|
-
@ui.expects(:show_status_preview).with(status_latin1)
|
317
|
-
@ui.expects(:info).with("Sent status update.\n\n")
|
318
|
-
@ui.expects(:show_tweets).with(internal_records)
|
319
|
-
@twitter.update(status_latin1)
|
320
|
-
end
|
321
|
-
end
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
context "with URL shortening" do
|
326
|
-
setup do
|
327
|
-
mock_url_shortener
|
328
|
-
stub_config(
|
329
|
-
:shorten_urls => {
|
330
|
-
:service_url => "http://shorten.it/create",
|
331
|
-
:method => "post",
|
332
|
-
:url_param_name => "url",
|
333
|
-
:xpath_selector => "//input[@id='short_url']/@value"
|
334
|
-
})
|
335
444
|
end
|
336
445
|
|
337
|
-
|
338
|
-
|
339
|
-
status = "reading http://www.w3.org/TR/1999/REC-xpath-19991116"
|
340
|
-
twitter_records, internal_records = create_rest_api_status_records({
|
341
|
-
:from_user => @username,
|
342
|
-
:status => status
|
343
|
-
})
|
344
|
-
@oauth.expects(:request_signer)
|
345
|
-
http_subresource = mock
|
346
|
-
http_subresource.expects(:post).
|
347
|
-
with({ :status => status }).
|
348
|
-
returns(twitter_records[0].to_json)
|
349
|
-
@url_shortener.expects(:shorten).never
|
350
|
-
@rest_api.expects(:[]).
|
351
|
-
with("statuses/update.json").
|
352
|
-
returns(http_subresource)
|
353
|
-
@ui.expects(:confirm).with("Really send?").returns(true)
|
354
|
-
@ui.expects(:show_status_preview).with(status)
|
355
|
-
@ui.expects(:info).with("Sent status update.\n\n")
|
356
|
-
@ui.expects(:show_tweets).with(internal_records)
|
357
|
-
@twitter.update(status)
|
358
|
-
end
|
359
|
-
|
360
|
-
should "shorten HTTP and HTTPS URLs" do
|
361
|
-
long_urls = ["http://www.google.fi/search?q=ruby+nokogiri&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a", "https://twitter.com/#!/messages"]
|
362
|
-
long_status = long_urls.join(" and ")
|
363
|
-
short_urls = ["http://shorten.it/2k7i8", "http://shorten.it/2k7mk"]
|
364
|
-
shortened_status = short_urls.join(" and ")
|
365
|
-
twitter_records, internal_records = create_rest_api_status_records({
|
366
|
-
:from_user => @username,
|
367
|
-
:status => shortened_status
|
368
|
-
})
|
369
|
-
@oauth.expects(:request_signer)
|
370
|
-
http_subresource = mock
|
371
|
-
http_subresource.expects(:post).
|
372
|
-
with({ :status => shortened_status }).
|
373
|
-
returns(twitter_records[0].to_json)
|
374
|
-
@rest_api.expects(:[]).
|
375
|
-
with("statuses/update.json").
|
376
|
-
returns(http_subresource)
|
377
|
-
@url_shortener.expects(:shorten).with(long_urls.first).returns(short_urls.first)
|
378
|
-
@url_shortener.expects(:shorten).with(long_urls.last).returns(short_urls.last)
|
379
|
-
@ui.expects(:show_status_preview).with(shortened_status)
|
380
|
-
@ui.expects(:confirm).with("Really send?").returns(true)
|
381
|
-
@ui.expects(:info).with("Sent status update.\n\n")
|
382
|
-
@ui.expects(:show_tweets).with(internal_records)
|
383
|
-
@twitter.update(long_status)
|
384
|
-
end
|
385
|
-
|
386
|
-
should "discard obviously invalid shortened URLs, using originals instead" do
|
387
|
-
long_urls = ["http://www.google.fi/", "http://www.w3.org/TR/1999/REC-xpath-19991116"]
|
388
|
-
status = long_urls.join(" and ")
|
389
|
-
short_urls = [nil, ""]
|
390
|
-
twitter_records, internal_records = create_rest_api_status_records({
|
391
|
-
:from_user => @username,
|
392
|
-
:status => status
|
393
|
-
})
|
446
|
+
it "skips shortening URLs if required libraries are not found" do
|
447
|
+
Tweetwine::CLI.stubs(:url_shortener).raises(LoadError, 'gem not found')
|
394
448
|
@oauth.expects(:request_signer)
|
395
449
|
http_subresource = mock
|
396
450
|
http_subresource.expects(:post).
|
397
|
-
with({ :status => status }).
|
398
|
-
returns(twitter_records[0].to_json)
|
451
|
+
with({ :status => @status }).
|
452
|
+
returns(@twitter_records[0].to_json)
|
399
453
|
@rest_api.expects(:[]).
|
400
454
|
with("statuses/update.json").
|
401
455
|
returns(http_subresource)
|
402
|
-
@
|
403
|
-
@
|
404
|
-
@ui.expects(:show_status_preview).with(status)
|
456
|
+
@ui.expects(:warn)
|
457
|
+
@ui.expects(:show_status_preview).with(@status)
|
405
458
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
406
459
|
@ui.expects(:info).with("Sent status update.\n\n")
|
407
|
-
@ui.expects(:show_tweets).with(internal_records)
|
408
|
-
@twitter.update(status)
|
460
|
+
@ui.expects(:show_tweets).with(@internal_records)
|
461
|
+
@twitter.update(@status)
|
409
462
|
end
|
410
463
|
|
411
|
-
|
412
|
-
long_urls = ["http://www.w3.org/TR/1999/REC-xpath-19991116"] * 2
|
413
|
-
long_status = long_urls.join(" and ")
|
414
|
-
short_url = "http://shorten.it/2k7mk"
|
415
|
-
short_status = ([short_url] * 2).join(" and ")
|
416
|
-
twitter_records, internal_records = create_rest_api_status_records({
|
417
|
-
:from_user => @username,
|
418
|
-
:status => short_status
|
419
|
-
})
|
464
|
+
it "skips shortening URLs upon connection error to the URL shortening service" do
|
420
465
|
@oauth.expects(:request_signer)
|
421
466
|
http_subresource = mock
|
422
467
|
http_subresource.expects(:post).
|
423
|
-
with({ :status =>
|
424
|
-
returns(twitter_records[0].to_json)
|
468
|
+
with({ :status => @status }).
|
469
|
+
returns(@twitter_records[0].to_json)
|
425
470
|
@rest_api.expects(:[]).
|
426
471
|
with("statuses/update.json").
|
427
472
|
returns(http_subresource)
|
428
|
-
@url_shortener.expects(:shorten).with(
|
429
|
-
@ui.expects(:
|
473
|
+
@url_shortener.expects(:shorten).with(@url).raises(HttpError.new(404, "Not Found"))
|
474
|
+
@ui.expects(:warn)
|
475
|
+
@ui.expects(:show_status_preview).with(@status)
|
430
476
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
431
477
|
@ui.expects(:info).with("Sent status update.\n\n")
|
432
|
-
@ui.expects(:show_tweets).with(internal_records)
|
433
|
-
@twitter.update(
|
434
|
-
end
|
435
|
-
|
436
|
-
context "in erroneous situations" do
|
437
|
-
setup do
|
438
|
-
@url = "http://www.w3.org/TR/1999/REC-xpath-19991116"
|
439
|
-
@status = "skimming through #{@url}"
|
440
|
-
@twitter_records, @internal_records = create_rest_api_status_records({
|
441
|
-
:from_user => @username,
|
442
|
-
:status => @status
|
443
|
-
})
|
444
|
-
end
|
445
|
-
|
446
|
-
should "skip shortening URLs if required libraries are not found" do
|
447
|
-
Tweetwine::CLI.stubs(:url_shortener).raises(LoadError, 'gem not found')
|
448
|
-
@oauth.expects(:request_signer)
|
449
|
-
http_subresource = mock
|
450
|
-
http_subresource.expects(:post).
|
451
|
-
with({ :status => @status }).
|
452
|
-
returns(@twitter_records[0].to_json)
|
453
|
-
@rest_api.expects(:[]).
|
454
|
-
with("statuses/update.json").
|
455
|
-
returns(http_subresource)
|
456
|
-
@ui.expects(:warn)
|
457
|
-
@ui.expects(:show_status_preview).with(@status)
|
458
|
-
@ui.expects(:confirm).with("Really send?").returns(true)
|
459
|
-
@ui.expects(:info).with("Sent status update.\n\n")
|
460
|
-
@ui.expects(:show_tweets).with(@internal_records)
|
461
|
-
@twitter.update(@status)
|
462
|
-
end
|
463
|
-
|
464
|
-
should "skip shortening URLs upon connection error to the URL shortening service" do
|
465
|
-
@oauth.expects(:request_signer)
|
466
|
-
http_subresource = mock
|
467
|
-
http_subresource.expects(:post).
|
468
|
-
with({ :status => @status }).
|
469
|
-
returns(@twitter_records[0].to_json)
|
470
|
-
@rest_api.expects(:[]).
|
471
|
-
with("statuses/update.json").
|
472
|
-
returns(http_subresource)
|
473
|
-
@url_shortener.expects(:shorten).with(@url).raises(HttpError.new(404, "Not Found"))
|
474
|
-
@ui.expects(:warn)
|
475
|
-
@ui.expects(:show_status_preview).with(@status)
|
476
|
-
@ui.expects(:confirm).with("Really send?").returns(true)
|
477
|
-
@ui.expects(:info).with("Sent status update.\n\n")
|
478
|
-
@ui.expects(:show_tweets).with(@internal_records)
|
479
|
-
@twitter.update(@status)
|
480
|
-
end
|
478
|
+
@ui.expects(:show_tweets).with(@internal_records)
|
479
|
+
@twitter.update(@status)
|
481
480
|
end
|
482
481
|
end
|
483
482
|
end
|
484
483
|
|
485
|
-
|
484
|
+
it "fetches friends" do
|
486
485
|
twitter_records, internal_records = create_rest_api_user_records(
|
487
486
|
{
|
488
487
|
:from_user => "zanzibar",
|
@@ -503,7 +502,7 @@ class ClientTest < UnitTestCase
|
|
503
502
|
@twitter.friends
|
504
503
|
end
|
505
504
|
|
506
|
-
|
505
|
+
it "fetches followers" do
|
507
506
|
twitter_records, internal_records = create_rest_api_user_records(
|
508
507
|
{
|
509
508
|
:from_user => "zanzibar",
|
@@ -522,63 +521,61 @@ class ClientTest < UnitTestCase
|
|
522
521
|
@twitter.followers
|
523
522
|
end
|
524
523
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
end
|
529
|
-
|
530
|
-
[
|
531
|
-
[nil, "no operator"],
|
532
|
-
[:and, "and operator"]
|
533
|
-
].each do |op, desc|
|
534
|
-
should "search tweets matching all the given words with #{desc}" do
|
535
|
-
twitter_response, internal_records = create_search_api_status_records(
|
536
|
-
{
|
537
|
-
:from_user => "zanzibar",
|
538
|
-
:status => "@foo, wassup? #greets",
|
539
|
-
:to_user => "foo"
|
540
|
-
},
|
541
|
-
{
|
542
|
-
:from_user => "spoonman",
|
543
|
-
:status => "@foo long time no see #greets",
|
544
|
-
:to_user => "foo"
|
545
|
-
}
|
546
|
-
)
|
547
|
-
@search_api.expects(:[]).
|
548
|
-
with("search.json?q=%23greets%20%40foo&#{@search_api_query_str}").
|
549
|
-
returns(stub(:get => twitter_response.to_json))
|
550
|
-
@ui.expects(:show_tweets).with(internal_records)
|
551
|
-
@twitter.search(["#greets", "@foo"], op)
|
552
|
-
end
|
553
|
-
end
|
524
|
+
it "raises exception if no search word is given for searching tweets" do
|
525
|
+
assert_raises(ArgumentError) { @twitter.search }
|
526
|
+
end
|
554
527
|
|
555
|
-
|
528
|
+
[
|
529
|
+
[nil, "no operator"],
|
530
|
+
[:and, "and operator"]
|
531
|
+
].each do |op, desc|
|
532
|
+
it "searches tweets matching all the given words with #{desc}" do
|
556
533
|
twitter_response, internal_records = create_search_api_status_records(
|
557
534
|
{
|
558
535
|
:from_user => "zanzibar",
|
559
|
-
:status => "
|
536
|
+
:status => "@foo, wassup? #greets",
|
560
537
|
:to_user => "foo"
|
561
538
|
},
|
562
539
|
{
|
563
540
|
:from_user => "spoonman",
|
564
|
-
:status => "
|
541
|
+
:status => "@foo long time no see #greets",
|
565
542
|
:to_user => "foo"
|
566
543
|
}
|
567
544
|
)
|
568
545
|
@search_api.expects(:[]).
|
569
|
-
with("search.json?q=%
|
546
|
+
with("search.json?q=%23greets%20%40foo&#{@search_api_query_str}").
|
570
547
|
returns(stub(:get => twitter_response.to_json))
|
571
548
|
@ui.expects(:show_tweets).with(internal_records)
|
572
|
-
@twitter.search(["#
|
549
|
+
@twitter.search(["#greets", "@foo"], op)
|
573
550
|
end
|
574
551
|
end
|
575
552
|
|
576
|
-
|
577
|
-
|
553
|
+
it "searches tweets matching any of the given words with or operator" do
|
554
|
+
twitter_response, internal_records = create_search_api_status_records(
|
555
|
+
{
|
556
|
+
:from_user => "zanzibar",
|
557
|
+
:status => "spinning around the floor #habits",
|
558
|
+
:to_user => "foo"
|
559
|
+
},
|
560
|
+
{
|
561
|
+
:from_user => "spoonman",
|
562
|
+
:status => "drinking coffee, again #neurotic",
|
563
|
+
:to_user => "foo"
|
564
|
+
}
|
565
|
+
)
|
566
|
+
@search_api.expects(:[]).
|
567
|
+
with("search.json?q=%23habits%20OR%20%23neurotic&#{@search_api_query_str}").
|
568
|
+
returns(stub(:get => twitter_response.to_json))
|
569
|
+
@ui.expects(:show_tweets).with(internal_records)
|
570
|
+
@twitter.search(["#habits", "#neurotic"], :or)
|
571
|
+
end
|
572
|
+
|
573
|
+
describe "when authorization fails with HTTP 401 response" do
|
574
|
+
before do
|
578
575
|
mock_config
|
579
576
|
end
|
580
577
|
|
581
|
-
|
578
|
+
it "authorizes with OAuth and save config" do
|
582
579
|
twitter_records, internal_records = create_rest_api_status_records({
|
583
580
|
:from_user => @username,
|
584
581
|
:status => "wassup?"
|