twitter-text-editted 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ describe "Twitter::Regex regular expressions" do
5
+ describe "matching URLS" do
6
+ TestUrls::VALID.each do |url|
7
+ it "should match the URL #{url}" do
8
+ url.should match_autolink_expression
9
+ end
10
+
11
+ it "should match the URL #{url} when it's embedded in other text" do
12
+ text = "Sweet url: #{url} I found. #awesome"
13
+ url.should match_autolink_expression_in(text)
14
+ end
15
+ end
16
+ end
17
+
18
+ describe "invalid URLS" do
19
+ it "does not link urls with invalid characters" do
20
+ TestUrls::INVALID.each {|url| url.should_not match_autolink_expression}
21
+ end
22
+ end
23
+
24
+ describe "matching List names" do
25
+ it "should match if less than 25 characters" do
26
+ name = "Shuffleboard Community"
27
+ name.length.should < 25
28
+ name.should match(Twitter::Regex::REGEXEN[:list_name])
29
+ end
30
+
31
+ it "should not match if greater than 25 characters" do
32
+ name = "Most Glorious Shady Meadows Shuffleboard Community"
33
+ name.length.should > 25
34
+ name.should match(Twitter::Regex[:list_name])
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,548 @@
1
+ # encoding: utf-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ describe Twitter::Rewriter do
5
+ def original_text; end
6
+ def url; end
7
+
8
+ def block(*args)
9
+ if Array === @block_args
10
+ unless Array === @block_args.first
11
+ @block_args = [@block_args]
12
+ end
13
+ @block_args << args
14
+ else
15
+ @block_args = args
16
+ end
17
+ "[rewritten]"
18
+ end
19
+
20
+ describe "rewrite usernames" do #{{{
21
+ before do
22
+ @rewritten_text = Twitter::Rewriter.rewrite_usernames_or_lists(original_text, &method(:block))
23
+ end
24
+
25
+ context "username preceded by a space" do
26
+ def original_text; "hello @jacob"; end
27
+
28
+ it "should be rewritten" do
29
+ @block_args.should == ["@", "jacob", nil]
30
+ @rewritten_text.should == "hello [rewritten]"
31
+ end
32
+ end
33
+
34
+ context "username at beginning of line" do
35
+ def original_text; "@jacob you're cool"; end
36
+
37
+ it "should be rewritten" do
38
+ @block_args.should == ["@", "jacob", nil]
39
+ @rewritten_text.should == "[rewritten] you're cool"
40
+ end
41
+ end
42
+
43
+ context "username preceded by word character" do
44
+ def original_text; "meet@the beach"; end
45
+
46
+ it "should not be rewritten" do
47
+ @block_args.should be_nil
48
+ @rewritten_text.should == "meet@the beach"
49
+ end
50
+ end
51
+
52
+ context "username preceded by non-word character" do
53
+ def original_text; "great.@jacob"; end
54
+
55
+ it "should be rewritten" do
56
+ @block_args.should == ["@", "jacob", nil]
57
+ @rewritten_text.should == "great.[rewritten]"
58
+ end
59
+ end
60
+
61
+ context "username containing non-word characters" do
62
+ def original_text; "@jacob&^$%^"; end
63
+
64
+ it "should be rewritten" do
65
+ @block_args.should == ["@", "jacob", nil]
66
+ @rewritten_text.should == "[rewritten]&^$%^"
67
+ end
68
+ end
69
+
70
+ context "username over twenty characters" do
71
+ def original_text
72
+ @twenty_character_username = "zach" * 5
73
+ "@" + @twenty_character_username + "1"
74
+ end
75
+
76
+ it "should be rewritten" do
77
+ @block_args.should == ["@", @twenty_character_username, nil]
78
+ @rewritten_text.should == "[rewritten]1"
79
+ end
80
+ end
81
+
82
+ context "username followed by japanese" do
83
+ def original_text; "@jacobの"; end
84
+
85
+ it "should be rewritten" do
86
+ @block_args.should == ["@", "jacob", nil]
87
+ @rewritten_text.should == "[rewritten]の"
88
+ end
89
+ end
90
+
91
+ context "username preceded by japanese" do
92
+ def original_text; "あ@jacob"; end
93
+
94
+ it "should be rewritten" do
95
+ @block_args.should == ["@", "jacob", nil]
96
+ @rewritten_text.should == "あ[rewritten]"
97
+ end
98
+ end
99
+
100
+ context "username surrounded by japanese" do
101
+ def original_text; "あ@jacobの"; end
102
+
103
+ it "should be rewritten" do
104
+ @block_args.should == ["@", "jacob", nil]
105
+ @rewritten_text.should == "あ[rewritten]の"
106
+ end
107
+ end
108
+
109
+ context "username using full-width at-sign" do
110
+ def original_text
111
+ "#{[0xFF20].pack('U')}jacob"
112
+ end
113
+
114
+ it "should be rewritten" do
115
+ @block_args.should == ["@", "jacob", nil]
116
+ @rewritten_text.should == "[rewritten]"
117
+ end
118
+ end
119
+ end #}}}
120
+
121
+ describe "rewrite lists" do #{{{
122
+ before do
123
+ @rewritten_text = Twitter::Rewriter.rewrite_usernames_or_lists(original_text, &method(:block))
124
+ end
125
+
126
+ context "slug preceded by a space" do
127
+ def original_text; "hello @jacob/my-list"; end
128
+
129
+ it "should be rewritten" do
130
+ @block_args.should == ["@", "jacob", "/my-list"]
131
+ @rewritten_text.should == "hello [rewritten]"
132
+ end
133
+ end
134
+
135
+ context "username followed by a slash but no list" do
136
+ def original_text; "hello @jacob/ my-list"; end
137
+
138
+ it "should not be rewritten" do
139
+ @block_args.should == ["@", "jacob", nil]
140
+ @rewritten_text.should == "hello [rewritten]/ my-list"
141
+ end
142
+ end
143
+
144
+ context "empty username followed by a list" do
145
+ def original_text; "hello @/my-list"; end
146
+
147
+ it "should not be rewritten" do
148
+ @block_args.should be_nil
149
+ @rewritten_text.should == "hello @/my-list"
150
+ end
151
+ end
152
+
153
+ context "list slug at beginning of line" do
154
+ def original_text; "@jacob/my-list"; end
155
+
156
+ it "should be rewritten" do
157
+ @block_args.should == ["@", "jacob", "/my-list"]
158
+ @rewritten_text.should == "[rewritten]"
159
+ end
160
+ end
161
+
162
+ context "username preceded by alpha-numeric character" do
163
+ def original_text; "meet@jacob/my-list"; end
164
+
165
+ it "should not be rewritten" do
166
+ @block_args.should be_nil
167
+ @rewritten_text.should == "meet@jacob/my-list"
168
+ end
169
+ end
170
+
171
+ context "username preceded by non-word character" do
172
+ def original_text; "great.@jacob/my-list"; end
173
+
174
+ it "should be rewritten" do
175
+ @block_args.should == ["@", "jacob", "/my-list"]
176
+ @rewritten_text.should == "great.[rewritten]"
177
+ end
178
+ end
179
+
180
+ context "username containing non-word characters" do
181
+ def original_text; "@jacob/my-list&^$%^"; end
182
+
183
+ it "should be rewritten" do
184
+ @block_args.should == ["@", "jacob", "/my-list"]
185
+ @rewritten_text.should == "[rewritten]&^$%^"
186
+ end
187
+ end
188
+
189
+ context "username over twenty characters" do
190
+ def original_text
191
+ @twentyfive_character_list = "a" * 25
192
+ "@jacob/#{@twentyfive_character_list}12345"
193
+ end
194
+
195
+ it "should be rewritten" do
196
+ @block_args.should == ["@", "jacob", "/#{@twentyfive_character_list}"]
197
+ @rewritten_text.should == "[rewritten]12345"
198
+ end
199
+ end
200
+ end #}}}
201
+
202
+ describe "rewrite hashtags" do #{{{
203
+ before do
204
+ @rewritten_text = Twitter::Rewriter.rewrite_hashtags(original_text, &method(:block))
205
+ end
206
+
207
+ context "with an all numeric hashtag" do
208
+ def original_text; "#123"; end
209
+
210
+ it "should not be rewritten" do
211
+ @block_args.should be_nil
212
+ @rewritten_text.should == "#123"
213
+ end
214
+ end
215
+
216
+ context "with a hashtag with alphanumeric characters" do
217
+ def original_text; "#ab1d"; end
218
+
219
+ it "should be rewritten" do
220
+ @block_args.should == ["#", "ab1d"]
221
+ @rewritten_text.should == "[rewritten]"
222
+ end
223
+ end
224
+
225
+ context "with a hashtag with underscores" do
226
+ def original_text; "#a_b_c_d"; end
227
+
228
+ it "should be rewritten" do
229
+ @block_args.should == ["#", "a_b_c_d"]
230
+ @rewritten_text.should == "[rewritten]"
231
+ end
232
+ end
233
+
234
+ context "with a hashtag that is preceded by a word character" do
235
+ def original_text; "ab#cd"; end
236
+
237
+ it "should not be rewritten" do
238
+ @block_args.should be_nil
239
+ @rewritten_text.should == "ab#cd"
240
+ end
241
+ end
242
+
243
+ context "with a hashtag that starts with a number but has word characters" do
244
+ def original_text; "#2ab"; end
245
+
246
+ it "should be rewritten" do
247
+ @block_args.should == ["#", "2ab"]
248
+ @rewritten_text.should == "[rewritten]"
249
+ end
250
+ end
251
+
252
+ context "with multiple valid hashtags" do
253
+ def original_text; "I'm frickin' awesome #ab #cd #ef"; end
254
+
255
+ it "rewrites each hashtag" do
256
+ @block_args.should == [["#", "ab"], ["#", "cd"], ["#", "ef"]]
257
+ @rewritten_text.should == "I'm frickin' awesome [rewritten] [rewritten] [rewritten]"
258
+ end
259
+ end
260
+
261
+ context "with a hashtag preceded by a ." do
262
+ def original_text; "ok, great.#abc"; end
263
+
264
+ it "should be rewritten" do
265
+ @block_args.should == ["#", "abc"]
266
+ @rewritten_text.should == "ok, great.[rewritten]"
267
+ end
268
+ end
269
+
270
+ context "with a hashtag preceded by a &" do
271
+ def original_text; "&#nbsp;"; end
272
+
273
+ it "should not be rewritten" do
274
+ @block_args.should be_nil
275
+ @rewritten_text.should == "&#nbsp;"
276
+ end
277
+ end
278
+
279
+ context "with a hashtag that ends in an !" do
280
+ def original_text; "#great!"; end
281
+
282
+ it "should be rewritten, but should not include the !" do
283
+ @block_args.should == ["#", "great"];
284
+ @rewritten_text.should == "[rewritten]!"
285
+ end
286
+ end
287
+
288
+ context "with a hashtag followed by Japanese" do
289
+ def original_text; "#twj_devの"; end
290
+
291
+ it "should be rewritten" do
292
+ @block_args.should == ["#", "twj_devの"];
293
+ @rewritten_text.should == "[rewritten]"
294
+ end
295
+ end
296
+
297
+ context "with a hashtag preceded by a full-width space" do
298
+ def original_text; "#{[0x3000].pack('U')}#twj_dev"; end
299
+
300
+ it "should be rewritten" do
301
+ @block_args.should == ["#", "twj_dev"];
302
+ @rewritten_text.should == " [rewritten]"
303
+ end
304
+ end
305
+
306
+ context "with a hashtag followed by a full-width space" do
307
+ def original_text; "#twj_dev#{[0x3000].pack('U')}"; end
308
+
309
+ it "should be rewritten" do
310
+ @block_args.should == ["#", "twj_dev"];
311
+ @rewritten_text.should == "[rewritten] "
312
+ end
313
+ end
314
+
315
+ context "with a hashtag using full-width hash" do
316
+ def original_text; "#{[0xFF03].pack('U')}twj_dev"; end
317
+
318
+ it "should be rewritten" do
319
+ @block_args.should == ["#", "twj_dev"];
320
+ @rewritten_text.should == "[rewritten]"
321
+ end
322
+ end
323
+
324
+ context "with a hashtag containing an accented latin character" do
325
+ def original_text
326
+ # the hashtag is #éhashtag
327
+ "##{[0x00e9].pack('U')}hashtag"
328
+ end
329
+
330
+ it "should be rewritten" do
331
+ @block_args.should == ["#", "éhashtag"];
332
+ @rewritten_text.should == "[rewritten]"
333
+ end
334
+ end
335
+ end #}}}
336
+
337
+ describe "rewrite urls" do #{{{
338
+ def url; "http://www.google.com"; end
339
+
340
+ before do
341
+ @rewritten_text = Twitter::Rewriter.rewrite_urls(original_text, &method(:block))
342
+ end
343
+
344
+ context "when embedded in plain text" do
345
+ def original_text; "On my search engine #{url} I found good links."; end
346
+
347
+ it "should be rewritten" do
348
+ @block_args.should == [url];
349
+ @rewritten_text.should == "On my search engine [rewritten] I found good links."
350
+ end
351
+ end
352
+
353
+ context "when surrounded by Japanese;" do
354
+ def original_text; "いまなにしてる#{url}いまなにしてる"; end
355
+
356
+ it "should be rewritten" do
357
+ @block_args.should == [url];
358
+ @rewritten_text.should == "いまなにしてる[rewritten]いまなにしてる"
359
+ end
360
+ end
361
+
362
+ context "with a path surrounded by parentheses;" do
363
+ def original_text; "I found a neatness (#{url})"; end
364
+
365
+ it "should be rewritten" do
366
+ @block_args.should == [url];
367
+ @rewritten_text.should == "I found a neatness ([rewritten])"
368
+ end
369
+
370
+ context "when the URL ends with a slash;" do
371
+ def url; "http://www.google.com/"; end
372
+
373
+ it "should be rewritten" do
374
+ @block_args.should == [url];
375
+ @rewritten_text.should == "I found a neatness ([rewritten])"
376
+ end
377
+ end
378
+
379
+ context "when the URL has a path;" do
380
+ def url; "http://www.google.com/fsdfasdf"; end
381
+
382
+ it "should be rewritten" do
383
+ @block_args.should == [url];
384
+ @rewritten_text.should == "I found a neatness ([rewritten])"
385
+ end
386
+ end
387
+ end
388
+
389
+ context "when path contains parens" do
390
+ def original_text; "I found a neatness (#{url})"; end
391
+
392
+ it "should be rewritten" do
393
+ @block_args.should == [url];
394
+ @rewritten_text.should == "I found a neatness ([rewritten])"
395
+ end
396
+
397
+ context "wikipedia" do
398
+ def url; "http://en.wikipedia.org/wiki/Madonna_(artist)"; end
399
+
400
+ it "should be rewritten" do
401
+ @block_args.should == [url];
402
+ @rewritten_text.should == "I found a neatness ([rewritten])"
403
+ end
404
+ end
405
+
406
+ context "IIS session" do
407
+ def url; "http://msdn.com/S(deadbeef)/page.htm"; end
408
+
409
+ it "should be rewritten" do
410
+ @block_args.should == [url];
411
+ @rewritten_text.should == "I found a neatness ([rewritten])"
412
+ end
413
+ end
414
+
415
+ context "unbalanced parens" do
416
+ def url; "http://example.com/i_has_a_("; end
417
+
418
+ it "should be rewritten" do
419
+ @block_args.should == ["http://example.com/i_has_a_"];
420
+ @rewritten_text.should == "I found a neatness ([rewritten]()"
421
+ end
422
+ end
423
+
424
+ context "balanced parens with a double quote inside" do
425
+ def url; "http://foo.bar.com/foo_(\")_bar" end
426
+
427
+ it "should be rewritten" do
428
+ @block_args.should == ["http://foo.bar.com/foo_"];
429
+ @rewritten_text.should == "I found a neatness ([rewritten](\")_bar)"
430
+ end
431
+ end
432
+
433
+ context "balanced parens hiding XSS" do
434
+ def url; 'http://x.xx.com/("style="color:red"onmouseover="alert(1)' end
435
+
436
+ it "should be rewritten" do
437
+ @block_args.should == ["http://x.xx.com/"];
438
+ @rewritten_text.should == 'I found a neatness ([rewritten]("style="color:red"onmouseover="alert(1))'
439
+ end
440
+ end
441
+ end
442
+
443
+ context "when preceded by a :" do
444
+ def original_text; "Check this out @hoverbird:#{url}"; end
445
+
446
+ it "should be rewritten" do
447
+ @block_args.should == [url];
448
+ @rewritten_text.should == "Check this out @hoverbird:[rewritten]"
449
+ end
450
+ end
451
+
452
+ context "with a URL ending in allowed punctuation" do
453
+ it "does not consume ending punctuation" do
454
+ %w| ? ! , . : ; ] ) } = \ ' |.each do |char|
455
+ Twitter::Rewriter.rewrite_urls("#{url}#{char}") do |url|
456
+ url.should == url; "[rewritten]"
457
+ end.should == "[rewritten]#{char}"
458
+ end
459
+ end
460
+ end
461
+
462
+ context "with a URL preceded in forbidden characters" do
463
+ it "should be rewritten" do
464
+ %w| \ ' / ! = |.each do |char|
465
+ Twitter::Rewriter.rewrite_urls("#{char}#{url}") do |url|
466
+ "[rewritten]" # should not be called here.
467
+ end.should == "#{char}[rewritten]"
468
+ end
469
+ end
470
+ end
471
+
472
+ context "when embedded in a link tag" do
473
+ def original_text; "<link rel='true'>#{url}</link>"; end
474
+
475
+ it "should be rewritten" do
476
+ @block_args.should == [url];
477
+ @rewritten_text.should == "<link rel='true'>[rewritten]</link>"
478
+ end
479
+ end
480
+
481
+ context "with multiple URLs" do
482
+ def original_text; "http://www.links.org link at start of page, link at end http://www.foo.org"; end
483
+
484
+ it "should autolink each one" do
485
+ @block_args.should == [["http://www.links.org"], ["http://www.foo.org"]];
486
+ @rewritten_text.should == "[rewritten] link at start of page, link at end [rewritten]"
487
+ end
488
+ end
489
+
490
+ context "with multiple URLs in different formats" do
491
+ def original_text; "http://foo.com https://bar.com http://mail.foobar.org"; end
492
+
493
+ it "should autolink each one, in the proper order" do
494
+ @block_args.should == [["http://foo.com"], ["https://bar.com"], ["http://mail.foobar.org"]];
495
+ @rewritten_text.should == "[rewritten] [rewritten] [rewritten]"
496
+ end
497
+ end
498
+
499
+ context "with a URL having a long TLD" do
500
+ def original_text; "Yahoo integriert Facebook http://golem.mobi/0912/71607.html"; end
501
+
502
+ it "should autolink it" do
503
+ @block_args.should == ["http://golem.mobi/0912/71607.html"]
504
+ @rewritten_text.should == "Yahoo integriert Facebook [rewritten]"
505
+ end
506
+ end
507
+
508
+ context "with a url lacking the protocol" do
509
+ def original_text; "I like www.foobar.com dudes"; end
510
+
511
+ it "does not link at all" do
512
+ @block_args.should be_nil
513
+ @rewritten_text.should == "I like www.foobar.com dudes"
514
+ end
515
+ end
516
+
517
+ context "with a @ in a URL" do
518
+ context "with XSS attack" do
519
+ def original_text; 'http://x.xx.com/@"style="color:pink"onmouseover=alert(1)//'; end
520
+
521
+ it "should not allow XSS follwing @" do
522
+ @block_args.should == ["http://x.xx.com/"]
523
+ @rewritten_text.should == '[rewritten]@"style="color:pink"onmouseover=alert(1)//'
524
+ end
525
+ end
526
+
527
+ context "with a username not followed by a /" do
528
+ def original_text; "http://example.com/@foobar"; end
529
+
530
+ it "should link url" do
531
+ @block_args.should == ["http://example.com/@foobar"]
532
+ @rewritten_text.should == "[rewritten]"
533
+ end
534
+ end
535
+
536
+ context "with a username followed by a /" do
537
+ def original_text; "http://example.com/@foobar/"; end
538
+
539
+ it "should not link the username but link full url" do
540
+ @block_args.should == ["http://example.com/@foobar/"]
541
+ @rewritten_text.should == "[rewritten]"
542
+ end
543
+ end
544
+ end
545
+ end #}}}
546
+ end
547
+
548
+ # vim: foldmethod=marker