tweetwine 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/CHANGELOG.rdoc +9 -0
- data/Gemfile +5 -13
- data/LICENSE.txt +1 -1
- data/README.md +3 -2
- data/Rakefile +8 -2
- data/lib/tweetwine/character_encoding.rb +1 -1
- data/lib/tweetwine/cli.rb +9 -3
- data/lib/tweetwine/config.rb +3 -3
- data/lib/tweetwine/exceptions.rb +54 -0
- data/lib/tweetwine/http.rb +1 -1
- data/lib/tweetwine/{util.rb → support.rb} +19 -12
- data/lib/tweetwine/tweet.rb +69 -0
- data/lib/tweetwine/twitter.rb +70 -72
- data/lib/tweetwine/ui.rb +36 -41
- data/lib/tweetwine/uri.rb +31 -0
- data/lib/tweetwine/version.rb +15 -0
- data/lib/tweetwine.rb +6 -64
- data/man/tweetwine.7 +4 -3
- data/man/tweetwine.7.ronn +3 -2
- data/release-script.txt +10 -0
- data/test/example/authorization_example.rb +40 -0
- data/test/example/example_helper.rb +1 -1
- data/test/example/global_options_example.rb +64 -0
- data/test/example/search_statuses_example.rb +36 -31
- data/test/example/show_followers_example.rb +1 -1
- data/test/example/show_friends_example.rb +1 -1
- data/test/example/show_home_example.rb +17 -29
- data/test/example/show_mentions_example.rb +2 -2
- data/test/example/show_user_example.rb +14 -12
- data/test/example/update_status_example.rb +9 -9
- data/test/example/use_http_proxy_example.rb +7 -6
- data/test/example/{application_behavior_example.rb → user_help_example.rb} +6 -39
- data/test/unit/config_test.rb +1 -1
- data/test/unit/http_test.rb +1 -21
- data/test/unit/oauth_test.rb +11 -11
- data/test/unit/{util_test.rb → support_test.rb} +37 -38
- data/test/unit/tweet_helper.rb +83 -0
- data/test/unit/tweet_test.rb +153 -0
- data/test/unit/twitter_test.rb +240 -248
- data/test/unit/ui_test.rb +174 -78
- data/test/unit/unit_helper.rb +18 -6
- data/test/unit/uri_test.rb +41 -0
- data/test/unit/url_shortener_test.rb +7 -7
- data/tweetwine.gemspec +12 -22
- metadata +52 -73
data/test/unit/twitter_test.rb
CHANGED
@@ -5,24 +5,32 @@ require "unit_helper"
|
|
5
5
|
module Tweetwine::Test
|
6
6
|
|
7
7
|
class ClientTest < UnitTestCase
|
8
|
+
setup do
|
9
|
+
@config = {
|
10
|
+
:num_tweets => 20,
|
11
|
+
:page => 1
|
12
|
+
}
|
13
|
+
stub_config @config
|
14
|
+
end
|
15
|
+
|
8
16
|
context "for initialization" do
|
9
17
|
should "use default number of statuses if not configured" do
|
10
18
|
@twitter = Twitter.new
|
11
|
-
assert_equal
|
19
|
+
assert_equal @config[:num_tweets], @twitter.num_tweets
|
12
20
|
end
|
13
21
|
|
14
22
|
should "use configured number of statuses if in allowed range" do
|
15
|
-
@twitter = Twitter.new(:
|
16
|
-
assert_equal 12, @twitter.
|
23
|
+
@twitter = Twitter.new(:num_tweets => 12)
|
24
|
+
assert_equal 12, @twitter.num_tweets
|
17
25
|
end
|
18
26
|
|
19
27
|
should "raise exception if configured number of status not in allowed range" do
|
20
|
-
assert_raise(
|
28
|
+
assert_raise(CommandLineError) { Twitter.new(:num_tweets => 0) }
|
21
29
|
end
|
22
30
|
|
23
31
|
should "use default page number if not configured otherwise" do
|
24
32
|
@twitter = Twitter.new
|
25
|
-
assert_equal
|
33
|
+
assert_equal @config[:page], @twitter.page
|
26
34
|
end
|
27
35
|
|
28
36
|
should "use configured page number if in allowed range" do
|
@@ -31,7 +39,7 @@ class ClientTest < UnitTestCase
|
|
31
39
|
end
|
32
40
|
|
33
41
|
should "raise exception if configured page number not in allowed range" do
|
34
|
-
assert_raise(
|
42
|
+
assert_raise(CommandLineError) { Twitter.new(:page => 0) }
|
35
43
|
end
|
36
44
|
end
|
37
45
|
|
@@ -46,132 +54,139 @@ class ClientTest < UnitTestCase
|
|
46
54
|
@http.stubs(:as_resource).with("https://api.twitter.com/1").returns(@rest_api)
|
47
55
|
@http.stubs(:as_resource).with("http://search.twitter.com").returns(@search_api)
|
48
56
|
@twitter = Twitter.new(:username => @username)
|
49
|
-
@rest_api_status_query_str = "count=#{
|
50
|
-
@search_api_query_str = "page=#{
|
57
|
+
@rest_api_status_query_str = "count=#{@config[:num_tweets]}&page=#{@config[:page]}"
|
58
|
+
@search_api_query_str = "page=#{@config[:page]}&rpp=#{@config[:num_tweets]}"
|
59
|
+
end
|
60
|
+
|
61
|
+
should "skip showing an invalid tweet" do
|
62
|
+
invalid_from_user = nil
|
63
|
+
twitter_records, internal_records = create_rest_api_status_records(
|
64
|
+
{
|
65
|
+
:from_user => invalid_from_user,
|
66
|
+
:status => "wassup?"
|
67
|
+
},
|
68
|
+
{
|
69
|
+
:from_user => "lulzwoo",
|
70
|
+
:status => "nuttin'"
|
71
|
+
}
|
72
|
+
)
|
73
|
+
@oauth.expects(:request_signer)
|
74
|
+
@rest_api.expects(:[]).
|
75
|
+
with("statuses/home_timeline.json?#{@rest_api_status_query_str}").
|
76
|
+
returns(stub(:get => twitter_records.to_json))
|
77
|
+
@ui.expects(:warn).with("Invalid tweet. Skipping...")
|
78
|
+
@ui.expects(:show_tweets).with(internal_records[1..-1])
|
79
|
+
@twitter.home
|
51
80
|
end
|
52
81
|
|
53
82
|
should "fetch friends' statuses (home view)" do
|
54
|
-
twitter_records, internal_records =
|
83
|
+
twitter_records, internal_records = create_rest_api_status_records(
|
55
84
|
{
|
56
85
|
:from_user => "zanzibar",
|
57
|
-
:status => "wassup?"
|
58
|
-
:created_at => Time.at(1).to_s,
|
59
|
-
:to_user => nil
|
86
|
+
:status => "wassup?"
|
60
87
|
},
|
61
88
|
{
|
62
89
|
:from_user => "lulzwoo",
|
63
|
-
:status => "nuttin'"
|
64
|
-
|
65
|
-
|
66
|
-
})
|
90
|
+
:status => "nuttin'"
|
91
|
+
}
|
92
|
+
)
|
67
93
|
@oauth.expects(:request_signer)
|
68
94
|
@rest_api.expects(:[]).
|
69
|
-
|
70
|
-
|
71
|
-
@ui.expects(:
|
72
|
-
@ui.expects(:show_record).with(internal_records[1])
|
95
|
+
with("statuses/home_timeline.json?#{@rest_api_status_query_str}").
|
96
|
+
returns(stub(:get => twitter_records.to_json))
|
97
|
+
@ui.expects(:show_tweets).with(internal_records)
|
73
98
|
@twitter.home
|
74
99
|
end
|
75
100
|
|
76
101
|
should "fetch mentions" do
|
77
|
-
twitter_records, internal_records =
|
102
|
+
twitter_records, internal_records = create_rest_api_status_records(
|
78
103
|
{
|
79
104
|
:from_user => "zanzibar",
|
80
105
|
:status => "wassup, @#{@username}?",
|
81
|
-
:created_at => Time.at(1).to_s,
|
82
106
|
:to_user => @username
|
83
107
|
},
|
84
108
|
{
|
85
109
|
:from_user => "lulzwoo",
|
86
110
|
:status => "@#{@username}, doing nuttin'",
|
87
|
-
:created_at => Time.at(1).to_s,
|
88
111
|
:to_user => @username
|
89
|
-
}
|
112
|
+
}
|
113
|
+
)
|
90
114
|
@oauth.expects(:request_signer)
|
91
115
|
@rest_api.expects(:[]).
|
92
|
-
|
93
|
-
|
94
|
-
@ui.expects(:
|
95
|
-
@ui.expects(:show_record).with(internal_records[1])
|
116
|
+
with("statuses/mentions.json?#{@rest_api_status_query_str}").
|
117
|
+
returns(stub(:get => twitter_records.to_json))
|
118
|
+
@ui.expects(:show_tweets).with(internal_records)
|
96
119
|
@twitter.mentions
|
97
120
|
end
|
98
121
|
|
99
122
|
should "fetch a specific user's statuses, when user is given as argument" do
|
100
123
|
username = "spoonman"
|
101
|
-
twitter_records, internal_records =
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
:to_user => nil
|
106
|
-
})
|
124
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
125
|
+
:from_user => username,
|
126
|
+
:status => "wassup?"
|
127
|
+
})
|
107
128
|
@oauth.expects(:request_signer)
|
108
129
|
@rest_api.expects(:[]).
|
109
|
-
|
110
|
-
|
111
|
-
@ui.expects(:
|
130
|
+
with("statuses/user_timeline.json?#{@rest_api_status_query_str}&screen_name=#{username}").
|
131
|
+
returns(stub(:get => twitter_records.to_json))
|
132
|
+
@ui.expects(:show_tweets).with(internal_records)
|
112
133
|
@twitter.user(username)
|
113
134
|
end
|
114
135
|
|
115
136
|
should "fetch a specific user's statuses, with user being the authenticated user itself when given no argument" do
|
116
|
-
twitter_records, internal_records =
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
:to_user => nil
|
121
|
-
})
|
137
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
138
|
+
:from_user => @username,
|
139
|
+
:status => "wassup?"
|
140
|
+
})
|
122
141
|
@oauth.expects(:request_signer)
|
123
142
|
@rest_api.expects(:[]).
|
124
|
-
|
125
|
-
|
126
|
-
@ui.expects(:
|
143
|
+
with("statuses/user_timeline.json?#{@rest_api_status_query_str}&screen_name=#{@username}").
|
144
|
+
returns(stub(:get => twitter_records.to_json))
|
145
|
+
@ui.expects(:show_tweets).with(internal_records)
|
127
146
|
@twitter.user
|
128
147
|
end
|
129
148
|
|
130
149
|
context "when posting status updates" do
|
131
150
|
should "post a status update via argument, when positive confirmation" do
|
132
151
|
status = "wondering around"
|
133
|
-
twitter_records, internal_records =
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
:to_user => nil
|
138
|
-
})
|
152
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
153
|
+
:from_user => @username,
|
154
|
+
:status => status
|
155
|
+
})
|
139
156
|
@oauth.expects(:request_signer)
|
140
157
|
http_subresource = mock
|
141
158
|
http_subresource.expects(:post).
|
142
|
-
|
143
|
-
|
159
|
+
with({ :status => status }).
|
160
|
+
returns(twitter_records[0].to_json)
|
144
161
|
@rest_api.expects(:[]).
|
145
|
-
|
146
|
-
|
162
|
+
with("statuses/update.json").
|
163
|
+
returns(http_subresource)
|
147
164
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
148
165
|
@ui.expects(:show_status_preview).with(status)
|
149
166
|
@ui.expects(:info).with("Sent status update.\n\n")
|
150
|
-
@ui.expects(:
|
167
|
+
@ui.expects(:show_tweets).with(internal_records)
|
151
168
|
@twitter.update(status)
|
152
169
|
end
|
153
170
|
|
154
171
|
should "post a status update via prompt, when positive confirmation" do
|
155
172
|
status = "wondering around"
|
156
|
-
twitter_records, internal_records =
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
:to_user => nil
|
161
|
-
})
|
173
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
174
|
+
:from_user => @username,
|
175
|
+
:status => status
|
176
|
+
})
|
162
177
|
@oauth.expects(:request_signer)
|
163
178
|
http_subresource = mock
|
164
179
|
http_subresource.expects(:post).
|
165
|
-
|
166
|
-
|
180
|
+
with({ :status => status }).
|
181
|
+
returns(twitter_records[0].to_json)
|
167
182
|
@rest_api.expects(:[]).
|
168
|
-
|
169
|
-
|
183
|
+
with("statuses/update.json").
|
184
|
+
returns(http_subresource)
|
170
185
|
@ui.expects(:prompt).with("Status update").returns(status)
|
171
186
|
@ui.expects(:show_status_preview).with(status)
|
172
187
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
173
188
|
@ui.expects(:info).with("Sent status update.\n\n")
|
174
|
-
@ui.expects(:
|
189
|
+
@ui.expects(:show_tweets).with(internal_records)
|
175
190
|
@twitter.update
|
176
191
|
end
|
177
192
|
|
@@ -181,7 +196,7 @@ class ClientTest < UnitTestCase
|
|
181
196
|
@ui.expects(:show_status_preview).with(status)
|
182
197
|
@ui.expects(:confirm).with("Really send?").returns(false)
|
183
198
|
@ui.expects(:info).with("Cancelled.")
|
184
|
-
@ui.expects(:
|
199
|
+
@ui.expects(:show_tweets).never
|
185
200
|
@twitter.update(status)
|
186
201
|
end
|
187
202
|
|
@@ -192,7 +207,7 @@ class ClientTest < UnitTestCase
|
|
192
207
|
@ui.expects(:show_status_preview).with(status)
|
193
208
|
@ui.expects(:confirm).with("Really send?").returns(false)
|
194
209
|
@ui.expects(:info).with("Cancelled.")
|
195
|
-
@ui.expects(:
|
210
|
+
@ui.expects(:show_tweets).never
|
196
211
|
@twitter.update
|
197
212
|
end
|
198
213
|
|
@@ -201,7 +216,7 @@ class ClientTest < UnitTestCase
|
|
201
216
|
@ui.expects(:prompt).with("Status update").returns("")
|
202
217
|
@ui.expects(:confirm).never
|
203
218
|
@ui.expects(:info).with("Cancelled.")
|
204
|
-
@ui.expects(:
|
219
|
+
@ui.expects(:show_tweets).never
|
205
220
|
@twitter.update("")
|
206
221
|
end
|
207
222
|
|
@@ -210,80 +225,74 @@ class ClientTest < UnitTestCase
|
|
210
225
|
@ui.expects(:prompt).with("Status update").returns("")
|
211
226
|
@ui.expects(:confirm).never
|
212
227
|
@ui.expects(:info).with("Cancelled.")
|
213
|
-
@ui.expects(:
|
228
|
+
@ui.expects(:show_tweets).never
|
214
229
|
@twitter.update
|
215
230
|
end
|
216
231
|
|
217
232
|
should "remove excess whitespace around a status update" do
|
218
233
|
whitespaced_status = " oh, i was sloppy \t "
|
219
234
|
stripped_status = "oh, i was sloppy"
|
220
|
-
twitter_records, internal_records =
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
:to_user => nil
|
225
|
-
})
|
235
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
236
|
+
:from_user => @username,
|
237
|
+
:status => stripped_status
|
238
|
+
})
|
226
239
|
@oauth.expects(:request_signer)
|
227
240
|
http_subresource = mock
|
228
241
|
http_subresource.expects(:post).
|
229
|
-
|
230
|
-
|
242
|
+
with({ :status => stripped_status }).
|
243
|
+
returns(twitter_records[0].to_json)
|
231
244
|
@rest_api.expects(:[]).
|
232
|
-
|
233
|
-
|
245
|
+
with("statuses/update.json").
|
246
|
+
returns(http_subresource)
|
234
247
|
@ui.expects(:show_status_preview).with(stripped_status)
|
235
248
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
236
249
|
@ui.expects(:info).with("Sent status update.\n\n")
|
237
|
-
@ui.expects(:
|
250
|
+
@ui.expects(:show_tweets).with(internal_records)
|
238
251
|
@twitter.update(whitespaced_status)
|
239
252
|
end
|
240
253
|
|
241
254
|
should "truncate a status update with too long argument and warn the user" do
|
242
255
|
truncated_status = "ab c" * 35 # 4 * 35 = 140
|
243
256
|
long_status = "#{truncated_status} dd"
|
244
|
-
twitter_records, internal_records =
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
:to_user => nil
|
249
|
-
})
|
257
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
258
|
+
:from_user => @username,
|
259
|
+
:status => truncated_status
|
260
|
+
})
|
250
261
|
@oauth.expects(:request_signer)
|
251
262
|
http_subresource = mock
|
252
263
|
http_subresource.expects(:post).
|
253
|
-
|
254
|
-
|
264
|
+
with({ :status => truncated_status }).
|
265
|
+
returns(twitter_records[0].to_json)
|
255
266
|
@rest_api.expects(:[]).
|
256
|
-
|
257
|
-
|
267
|
+
with("statuses/update.json").
|
268
|
+
returns(http_subresource)
|
258
269
|
@ui.expects(:warn).with("Status will be truncated.")
|
259
270
|
@ui.expects(:show_status_preview).with(truncated_status)
|
260
271
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
261
272
|
@ui.expects(:info).with("Sent status update.\n\n")
|
262
|
-
@ui.expects(:
|
273
|
+
@ui.expects(:show_tweets).with(internal_records)
|
263
274
|
@twitter.update(long_status)
|
264
275
|
end
|
265
276
|
|
266
277
|
if defined? Encoding
|
267
278
|
should "encode status in UTF-8 (String supports encoding)" do
|
268
279
|
status_utf8, status_latin1 = "résumé", "résumé".encode('ISO-8859-1')
|
269
|
-
twitter_records, internal_records =
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
:to_user => nil
|
274
|
-
})
|
280
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
281
|
+
:from_user => @username,
|
282
|
+
:status => status_utf8
|
283
|
+
})
|
275
284
|
@oauth.expects(:request_signer)
|
276
285
|
http_subresource = mock
|
277
286
|
http_subresource.expects(:post).
|
278
|
-
|
279
|
-
|
287
|
+
with({ :status => status_utf8 }).
|
288
|
+
returns(twitter_records[0].to_json)
|
280
289
|
@rest_api.expects(:[]).
|
281
|
-
|
282
|
-
|
290
|
+
with("statuses/update.json").
|
291
|
+
returns(http_subresource)
|
283
292
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
284
293
|
@ui.expects(:show_status_preview).with(status_latin1)
|
285
294
|
@ui.expects(:info).with("Sent status update.\n\n")
|
286
|
-
@ui.expects(:
|
295
|
+
@ui.expects(:show_tweets).with(internal_records)
|
287
296
|
@twitter.update(status_latin1)
|
288
297
|
end
|
289
298
|
else
|
@@ -291,24 +300,22 @@ class ClientTest < UnitTestCase
|
|
291
300
|
tmp_kcode('NONE') do
|
292
301
|
tmp_env(:LANG => 'ISO-8859-1') do
|
293
302
|
status_utf8, status_latin1 = "r\xc3\xa9sum\xc3\xa9", "r\xe9sum\xe9"
|
294
|
-
twitter_records, internal_records =
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
:to_user => nil
|
299
|
-
})
|
303
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
304
|
+
:from_user => @username,
|
305
|
+
:status => status_utf8
|
306
|
+
})
|
300
307
|
@oauth.expects(:request_signer)
|
301
308
|
http_subresource = mock
|
302
309
|
http_subresource.expects(:post).
|
303
|
-
|
304
|
-
|
310
|
+
with({ :status => status_utf8 }).
|
311
|
+
returns(twitter_records[0].to_json)
|
305
312
|
@rest_api.expects(:[]).
|
306
|
-
|
307
|
-
|
313
|
+
with("statuses/update.json").
|
314
|
+
returns(http_subresource)
|
308
315
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
309
316
|
@ui.expects(:show_status_preview).with(status_latin1)
|
310
317
|
@ui.expects(:info).with("Sent status update.\n\n")
|
311
|
-
@ui.expects(:
|
318
|
+
@ui.expects(:show_tweets).with(internal_records)
|
312
319
|
@twitter.update(status_latin1)
|
313
320
|
end
|
314
321
|
end
|
@@ -330,25 +337,23 @@ class ClientTest < UnitTestCase
|
|
330
337
|
should "not shorten URLs if not configured" do
|
331
338
|
stub_config
|
332
339
|
status = "reading http://www.w3.org/TR/1999/REC-xpath-19991116"
|
333
|
-
twitter_records, internal_records =
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
:to_user => nil
|
338
|
-
})
|
340
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
341
|
+
:from_user => @username,
|
342
|
+
:status => status
|
343
|
+
})
|
339
344
|
@oauth.expects(:request_signer)
|
340
345
|
http_subresource = mock
|
341
346
|
http_subresource.expects(:post).
|
342
|
-
|
343
|
-
|
347
|
+
with({ :status => status }).
|
348
|
+
returns(twitter_records[0].to_json)
|
344
349
|
@url_shortener.expects(:shorten).never
|
345
350
|
@rest_api.expects(:[]).
|
346
|
-
|
347
|
-
|
351
|
+
with("statuses/update.json").
|
352
|
+
returns(http_subresource)
|
348
353
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
349
354
|
@ui.expects(:show_status_preview).with(status)
|
350
355
|
@ui.expects(:info).with("Sent status update.\n\n")
|
351
|
-
@ui.expects(:
|
356
|
+
@ui.expects(:show_tweets).with(internal_records)
|
352
357
|
@twitter.update(status)
|
353
358
|
end
|
354
359
|
|
@@ -357,26 +362,24 @@ class ClientTest < UnitTestCase
|
|
357
362
|
long_status = long_urls.join(" and ")
|
358
363
|
short_urls = ["http://shorten.it/2k7i8", "http://shorten.it/2k7mk"]
|
359
364
|
shortened_status = short_urls.join(" and ")
|
360
|
-
twitter_records, internal_records =
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
:to_user => nil
|
365
|
-
})
|
365
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
366
|
+
:from_user => @username,
|
367
|
+
:status => shortened_status
|
368
|
+
})
|
366
369
|
@oauth.expects(:request_signer)
|
367
370
|
http_subresource = mock
|
368
371
|
http_subresource.expects(:post).
|
369
|
-
|
370
|
-
|
372
|
+
with({ :status => shortened_status }).
|
373
|
+
returns(twitter_records[0].to_json)
|
371
374
|
@rest_api.expects(:[]).
|
372
|
-
|
373
|
-
|
375
|
+
with("statuses/update.json").
|
376
|
+
returns(http_subresource)
|
374
377
|
@url_shortener.expects(:shorten).with(long_urls.first).returns(short_urls.first)
|
375
378
|
@url_shortener.expects(:shorten).with(long_urls.last).returns(short_urls.last)
|
376
379
|
@ui.expects(:show_status_preview).with(shortened_status)
|
377
380
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
378
381
|
@ui.expects(:info).with("Sent status update.\n\n")
|
379
|
-
@ui.expects(:
|
382
|
+
@ui.expects(:show_tweets).with(internal_records)
|
380
383
|
@twitter.update(long_status)
|
381
384
|
end
|
382
385
|
|
@@ -384,26 +387,24 @@ class ClientTest < UnitTestCase
|
|
384
387
|
long_urls = ["http://www.google.fi/", "http://www.w3.org/TR/1999/REC-xpath-19991116"]
|
385
388
|
status = long_urls.join(" and ")
|
386
389
|
short_urls = [nil, ""]
|
387
|
-
twitter_records, internal_records =
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
:to_user => nil
|
392
|
-
})
|
390
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
391
|
+
:from_user => @username,
|
392
|
+
:status => status
|
393
|
+
})
|
393
394
|
@oauth.expects(:request_signer)
|
394
395
|
http_subresource = mock
|
395
396
|
http_subresource.expects(:post).
|
396
|
-
|
397
|
-
|
397
|
+
with({ :status => status }).
|
398
|
+
returns(twitter_records[0].to_json)
|
398
399
|
@rest_api.expects(:[]).
|
399
|
-
|
400
|
-
|
400
|
+
with("statuses/update.json").
|
401
|
+
returns(http_subresource)
|
401
402
|
@url_shortener.expects(:shorten).with(long_urls.first).returns(short_urls.first)
|
402
403
|
@url_shortener.expects(:shorten).with(long_urls.last).returns(short_urls.last)
|
403
404
|
@ui.expects(:show_status_preview).with(status)
|
404
405
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
405
406
|
@ui.expects(:info).with("Sent status update.\n\n")
|
406
|
-
@ui.expects(:
|
407
|
+
@ui.expects(:show_tweets).with(internal_records)
|
407
408
|
@twitter.update(status)
|
408
409
|
end
|
409
410
|
|
@@ -412,25 +413,23 @@ class ClientTest < UnitTestCase
|
|
412
413
|
long_status = long_urls.join(" and ")
|
413
414
|
short_url = "http://shorten.it/2k7mk"
|
414
415
|
short_status = ([short_url] * 2).join(" and ")
|
415
|
-
twitter_records, internal_records =
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
:to_user => nil
|
420
|
-
})
|
416
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
417
|
+
:from_user => @username,
|
418
|
+
:status => short_status
|
419
|
+
})
|
421
420
|
@oauth.expects(:request_signer)
|
422
421
|
http_subresource = mock
|
423
422
|
http_subresource.expects(:post).
|
424
|
-
|
425
|
-
|
423
|
+
with({ :status => short_status }).
|
424
|
+
returns(twitter_records[0].to_json)
|
426
425
|
@rest_api.expects(:[]).
|
427
|
-
|
428
|
-
|
426
|
+
with("statuses/update.json").
|
427
|
+
returns(http_subresource)
|
429
428
|
@url_shortener.expects(:shorten).with(long_urls.first).returns(short_url)
|
430
429
|
@ui.expects(:show_status_preview).with(short_status)
|
431
430
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
432
431
|
@ui.expects(:info).with("Sent status update.\n\n")
|
433
|
-
@ui.expects(:
|
432
|
+
@ui.expects(:show_tweets).with(internal_records)
|
434
433
|
@twitter.update(long_status)
|
435
434
|
end
|
436
435
|
|
@@ -438,12 +437,10 @@ class ClientTest < UnitTestCase
|
|
438
437
|
setup do
|
439
438
|
@url = "http://www.w3.org/TR/1999/REC-xpath-19991116"
|
440
439
|
@status = "skimming through #{@url}"
|
441
|
-
@twitter_records, @internal_records =
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
:to_user => nil
|
446
|
-
})
|
440
|
+
@twitter_records, @internal_records = create_rest_api_status_records({
|
441
|
+
:from_user => @username,
|
442
|
+
:status => @status
|
443
|
+
})
|
447
444
|
end
|
448
445
|
|
449
446
|
should "skip shortening URLs if required libraries are not found" do
|
@@ -451,16 +448,16 @@ class ClientTest < UnitTestCase
|
|
451
448
|
@oauth.expects(:request_signer)
|
452
449
|
http_subresource = mock
|
453
450
|
http_subresource.expects(:post).
|
454
|
-
|
455
|
-
|
451
|
+
with({ :status => @status }).
|
452
|
+
returns(@twitter_records[0].to_json)
|
456
453
|
@rest_api.expects(:[]).
|
457
|
-
|
458
|
-
|
454
|
+
with("statuses/update.json").
|
455
|
+
returns(http_subresource)
|
459
456
|
@ui.expects(:warn)
|
460
457
|
@ui.expects(:show_status_preview).with(@status)
|
461
458
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
462
459
|
@ui.expects(:info).with("Sent status update.\n\n")
|
463
|
-
@ui.expects(:
|
460
|
+
@ui.expects(:show_tweets).with(@internal_records)
|
464
461
|
@twitter.update(@status)
|
465
462
|
end
|
466
463
|
|
@@ -468,17 +465,17 @@ class ClientTest < UnitTestCase
|
|
468
465
|
@oauth.expects(:request_signer)
|
469
466
|
http_subresource = mock
|
470
467
|
http_subresource.expects(:post).
|
471
|
-
|
472
|
-
|
468
|
+
with({ :status => @status }).
|
469
|
+
returns(@twitter_records[0].to_json)
|
473
470
|
@rest_api.expects(:[]).
|
474
|
-
|
475
|
-
|
471
|
+
with("statuses/update.json").
|
472
|
+
returns(http_subresource)
|
476
473
|
@url_shortener.expects(:shorten).with(@url).raises(HttpError.new(404, "Not Found"))
|
477
474
|
@ui.expects(:warn)
|
478
475
|
@ui.expects(:show_status_preview).with(@status)
|
479
476
|
@ui.expects(:confirm).with("Really send?").returns(true)
|
480
477
|
@ui.expects(:info).with("Sent status update.\n\n")
|
481
|
-
@ui.expects(:
|
478
|
+
@ui.expects(:show_tweets).with(@internal_records)
|
482
479
|
@twitter.update(@status)
|
483
480
|
end
|
484
481
|
end
|
@@ -486,48 +483,42 @@ class ClientTest < UnitTestCase
|
|
486
483
|
end
|
487
484
|
|
488
485
|
should "fetch friends" do
|
489
|
-
twitter_records, internal_records =
|
486
|
+
twitter_records, internal_records = create_rest_api_user_records(
|
490
487
|
{
|
491
488
|
:from_user => "zanzibar",
|
492
489
|
:status => "wassup, @foo?",
|
493
|
-
:created_at => Time.at(1).to_s,
|
494
490
|
:to_user => "foo"
|
495
491
|
},
|
496
492
|
{
|
497
493
|
:from_user => "lulzwoo",
|
498
494
|
:status => "@foo, doing nuttin'",
|
499
|
-
:created_at => Time.at(1).to_s,
|
500
495
|
:to_user => "foo"
|
501
|
-
}
|
496
|
+
}
|
497
|
+
)
|
502
498
|
@oauth.expects(:request_signer)
|
503
499
|
@rest_api.expects(:[]).
|
504
|
-
|
505
|
-
|
506
|
-
@ui.expects(:
|
507
|
-
@ui.expects(:show_record).with(internal_records[1])
|
500
|
+
with("statuses/friends.json?#{@rest_api_status_query_str}").
|
501
|
+
returns(stub(:get => twitter_records.to_json))
|
502
|
+
@ui.expects(:show_tweets).with(internal_records)
|
508
503
|
@twitter.friends
|
509
504
|
end
|
510
505
|
|
511
506
|
should "fetch followers" do
|
512
|
-
twitter_records, internal_records =
|
507
|
+
twitter_records, internal_records = create_rest_api_user_records(
|
513
508
|
{
|
514
509
|
:from_user => "zanzibar",
|
515
510
|
:status => "wassup, @foo?",
|
516
|
-
:created_at => Time.at(1).to_s,
|
517
511
|
:to_user => "foo"
|
518
512
|
},
|
519
513
|
{
|
520
|
-
:from_user => "lulzwoo"
|
521
|
-
|
522
|
-
|
523
|
-
:to_user => nil
|
524
|
-
})
|
514
|
+
:from_user => "lulzwoo"
|
515
|
+
}
|
516
|
+
)
|
525
517
|
@oauth.expects(:request_signer)
|
526
518
|
@rest_api.expects(:[]).
|
527
|
-
|
528
|
-
|
529
|
-
@ui.expects(:
|
530
|
-
@ui.expects(:show_record).with(internal_records[1])
|
519
|
+
with("statuses/followers.json?#{@rest_api_status_query_str}").
|
520
|
+
returns(stub(:get => twitter_records.to_json))
|
521
|
+
@ui.expects(:show_tweets).with(internal_records)
|
531
522
|
@twitter.followers
|
532
523
|
end
|
533
524
|
|
@@ -541,47 +532,43 @@ class ClientTest < UnitTestCase
|
|
541
532
|
[:and, "and operator"]
|
542
533
|
].each do |op, desc|
|
543
534
|
should "search tweets matching all the given words with #{desc}" do
|
544
|
-
twitter_response, internal_records =
|
535
|
+
twitter_response, internal_records = create_search_api_status_records(
|
545
536
|
{
|
546
537
|
:from_user => "zanzibar",
|
547
538
|
:status => "@foo, wassup? #greets",
|
548
|
-
:created_at => Time.at(1).to_s,
|
549
539
|
:to_user => "foo"
|
550
540
|
},
|
551
541
|
{
|
552
542
|
:from_user => "spoonman",
|
553
543
|
:status => "@foo long time no see #greets",
|
554
|
-
:created_at => Time.at(1).to_s,
|
555
544
|
:to_user => "foo"
|
556
|
-
}
|
545
|
+
}
|
546
|
+
)
|
557
547
|
@search_api.expects(:[]).
|
558
|
-
|
559
|
-
|
560
|
-
@ui.expects(:
|
561
|
-
@ui.expects(:show_record).with(internal_records[1])
|
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)
|
562
551
|
@twitter.search(["#greets", "@foo"], op)
|
563
552
|
end
|
564
553
|
end
|
565
554
|
|
566
555
|
should "search tweets matching any of the given words with or operator" do
|
567
|
-
twitter_response, internal_records =
|
556
|
+
twitter_response, internal_records = create_search_api_status_records(
|
568
557
|
{
|
569
558
|
:from_user => "zanzibar",
|
570
559
|
:status => "spinning around the floor #habits",
|
571
|
-
:created_at => Time.at(1).to_s,
|
572
560
|
:to_user => "foo"
|
573
561
|
},
|
574
562
|
{
|
575
563
|
:from_user => "spoonman",
|
576
564
|
:status => "drinking coffee, again #neurotic",
|
577
|
-
:created_at => Time.at(1).to_s,
|
578
565
|
:to_user => "foo"
|
579
|
-
}
|
566
|
+
}
|
567
|
+
)
|
580
568
|
@search_api.expects(:[]).
|
581
|
-
|
582
|
-
|
583
|
-
@ui.expects(:
|
584
|
-
@ui.expects(:show_record).with(internal_records[1])
|
569
|
+
with("search.json?q=%23habits%20OR%20%23neurotic&#{@search_api_query_str}").
|
570
|
+
returns(stub(:get => twitter_response.to_json))
|
571
|
+
@ui.expects(:show_tweets).with(internal_records)
|
585
572
|
@twitter.search(["#habits", "#neurotic"], :or)
|
586
573
|
end
|
587
574
|
end
|
@@ -592,29 +579,27 @@ class ClientTest < UnitTestCase
|
|
592
579
|
end
|
593
580
|
|
594
581
|
should "authorize with OAuth and save config" do
|
595
|
-
twitter_records, internal_records =
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
:to_user => nil
|
600
|
-
})
|
582
|
+
twitter_records, internal_records = create_rest_api_status_records({
|
583
|
+
:from_user => @username,
|
584
|
+
:status => "wassup?"
|
585
|
+
})
|
601
586
|
access_token = 'access token'
|
602
587
|
user_has_authorized = states('User has authorized?').starts_as(false)
|
603
588
|
@oauth.expects(:request_signer).twice
|
604
589
|
@oauth.expects(:authorize).
|
605
|
-
|
606
|
-
|
590
|
+
yields(access_token).
|
591
|
+
then(user_has_authorized.is(true))
|
607
592
|
http_subresource = mock
|
608
593
|
http_subresource.expects(:get).
|
609
|
-
|
610
|
-
|
594
|
+
raises(HttpError.new(401, 'Unauthorized')).
|
595
|
+
when(user_has_authorized.is(false))
|
611
596
|
http_subresource.expects(:get).
|
612
|
-
|
613
|
-
|
597
|
+
returns(twitter_records.to_json).
|
598
|
+
when(user_has_authorized.is(true))
|
614
599
|
@rest_api.expects(:[]).returns(http_subresource)
|
615
600
|
@config.expects(:[]=).with(:oauth_access, access_token)
|
616
601
|
@config.expects(:save)
|
617
|
-
@ui.expects(:
|
602
|
+
@ui.expects(:show_tweets).with(internal_records)
|
618
603
|
@twitter.home
|
619
604
|
end
|
620
605
|
end
|
@@ -622,49 +607,56 @@ class ClientTest < UnitTestCase
|
|
622
607
|
|
623
608
|
private
|
624
609
|
|
625
|
-
def
|
626
|
-
|
610
|
+
def create_rest_api_status_records(*records)
|
611
|
+
create_twitter_and_internal_records(records, Twitter::REST_API_STATUS_PATHS) do |record|
|
627
612
|
{
|
628
|
-
"user" => { "screen_name" =>
|
629
|
-
"created_at" =>
|
630
|
-
"text" =>
|
631
|
-
"in_reply_to_screen_name" =>
|
613
|
+
"user" => { "screen_name" => record[:from_user] },
|
614
|
+
"created_at" => create_timestamp,
|
615
|
+
"text" => record[:status],
|
616
|
+
"in_reply_to_screen_name" => record[:to_user]
|
632
617
|
}
|
633
618
|
end
|
634
|
-
[twitter_records, internal_records]
|
635
619
|
end
|
636
620
|
|
637
|
-
def
|
638
|
-
|
639
|
-
twitter_record = { "screen_name" =>
|
640
|
-
if
|
621
|
+
def create_rest_api_user_records(*records)
|
622
|
+
create_twitter_and_internal_records(records, Twitter::REST_API_USER_PATHS) do |record|
|
623
|
+
twitter_record = { "screen_name" => record[:from_user] }
|
624
|
+
if record[:status]
|
641
625
|
twitter_record.merge!({
|
642
626
|
"status" => {
|
643
|
-
"created_at" =>
|
644
|
-
"text" =>
|
645
|
-
"in_reply_to_screen_name" =>
|
627
|
+
"created_at" => create_timestamp,
|
628
|
+
"text" => record[:status],
|
629
|
+
"in_reply_to_screen_name" => record[:to_user],
|
646
630
|
}
|
647
631
|
})
|
648
632
|
end
|
649
633
|
twitter_record
|
650
634
|
end
|
651
|
-
[twitter_records, internal_records]
|
652
635
|
end
|
653
636
|
|
654
|
-
def
|
655
|
-
|
637
|
+
def create_search_api_status_records(*records)
|
638
|
+
twitter_records, internal_records = create_twitter_and_internal_records(
|
639
|
+
records, Twitter::SEARCH_API_STATUS_PATHS) do |record|
|
656
640
|
{
|
657
|
-
"from_user" =>
|
658
|
-
"created_at" =>
|
659
|
-
"text" =>
|
660
|
-
"to_user" =>
|
641
|
+
"from_user" => record[:from_user],
|
642
|
+
"created_at" => create_timestamp,
|
643
|
+
"text" => record[:status],
|
644
|
+
"to_user" => record[:to_user]
|
661
645
|
}
|
662
646
|
end
|
663
|
-
twitter_records = {
|
664
|
-
|
665
|
-
|
647
|
+
twitter_records = { 'results' => twitter_records }
|
648
|
+
[twitter_records, internal_records]
|
649
|
+
end
|
650
|
+
|
651
|
+
def create_twitter_and_internal_records(records, paths, &twitter_record_maker)
|
652
|
+
twitter_records = records.map(&twitter_record_maker)
|
653
|
+
internal_records = twitter_records.map { |rec| Tweet.new(rec, paths) rescue nil }
|
666
654
|
[twitter_records, internal_records]
|
667
655
|
end
|
656
|
+
|
657
|
+
def create_timestamp
|
658
|
+
Time.at(1).to_s
|
659
|
+
end
|
668
660
|
end
|
669
661
|
|
670
662
|
end
|