tweetwine 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.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
|