2013-02-06 03:16:51 +08:00
require 'spec_helper'
require 'pretty_text'
describe PrettyText do
2014-11-06 03:37:00 +08:00
let ( :wrapped_image ) { " <div class= \" lightbox-wrapper \" ><a href= \" //localhost:3000/uploads/default/4399/33691397e78b4d75.png \" class= \" lightbox \" title= \" Screen Shot 2014-04-14 at 9.47.10 PM.png \" ><img src= \" //localhost:3000/uploads/default/_optimized/bd9/b20/bbbcd6a0c0_655x500.png \" width= \" 655 \" height= \" 500 \" ><div class= \" meta \" > \n <span class= \" filename \" >Screen Shot 2014-04-14 at 9.47.10 PM.png</span><span class= \" informations \" >966x737 1.47 MB</span><span class= \" expand \" ></span> \n </div></a></div> " }
let ( :wrapped_image_excerpt ) { }
2013-02-26 00:42:20 +08:00
describe " Cooking " do
2013-02-06 03:16:51 +08:00
2013-08-14 04:08:29 +08:00
describe " with avatar " do
2013-02-06 03:16:51 +08:00
2013-08-14 04:08:29 +08:00
before ( :each ) do
eviltrout = User . new
eviltrout . stubs ( :avatar_template ) . returns ( " http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/{size}.png " )
2014-05-06 21:41:59 +08:00
User . expects ( :find_by ) . with ( username_lower : " eviltrout " ) . returns ( eviltrout )
2013-08-14 04:08:29 +08:00
end
2013-02-06 03:16:51 +08:00
2013-08-14 04:08:29 +08:00
it " produces a quote even with new lines in it " do
2014-09-19 11:39:18 +08:00
PrettyText . cook ( " [quote= \" EvilTrout, post:123, topic:456, full:true \" ]ddd \n [/quote] " ) . should match_html " <aside class= \" quote \" data-post= \" 123 \" data-topic= \" 456 \" data-full= \" true \" ><div class= \" title \" > \n <div class= \" quote-controls \" ></div> \n <img width= \" 20 \" height= \" 20 \" src= \" http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png \" class= \" avatar \" >EvilTrout:</div> \n <blockquote><p>ddd</p></blockquote></aside> "
2013-08-14 04:08:29 +08:00
end
2013-02-06 03:16:51 +08:00
2013-08-14 04:08:29 +08:00
it " should produce a quote " do
2014-09-19 11:39:18 +08:00
PrettyText . cook ( " [quote= \" EvilTrout, post:123, topic:456, full:true \" ]ddd[/quote] " ) . should match_html " <aside class= \" quote \" data-post= \" 123 \" data-topic= \" 456 \" data-full= \" true \" ><div class= \" title \" > \n <div class= \" quote-controls \" ></div> \n <img width= \" 20 \" height= \" 20 \" src= \" http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png \" class= \" avatar \" >EvilTrout:</div> \n <blockquote><p>ddd</p></blockquote></aside> "
2013-08-14 04:08:29 +08:00
end
it " trims spaces on quote params " do
2014-09-19 11:39:18 +08:00
PrettyText . cook ( " [quote= \" EvilTrout, post:555, topic: 666 \" ]ddd[/quote] " ) . should match_html " <aside class= \" quote \" data-post= \" 555 \" data-topic= \" 666 \" ><div class= \" title \" > \n <div class= \" quote-controls \" ></div> \n <img width= \" 20 \" height= \" 20 \" src= \" http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png \" class= \" avatar \" >EvilTrout:</div> \n <blockquote><p>ddd</p></blockquote></aside> "
2013-08-14 04:08:29 +08:00
end
end
2013-02-06 03:16:51 +08:00
2013-02-26 00:42:20 +08:00
it " should handle 3 mentions in a row " do
2013-04-10 11:27:33 +08:00
PrettyText . cook ( '@hello @hello @hello' ) . should match_html " <p><span class= \" mention \" >@hello</span> <span class= \" mention \" >@hello</span> <span class= \" mention \" >@hello</span></p> "
2013-02-06 03:16:51 +08:00
end
it " should sanitize the html " do
2013-10-19 03:20:27 +08:00
PrettyText . cook ( " <script>alert(42)</script> " ) . should match_html " <p></p> "
2013-02-06 03:16:51 +08:00
end
it 'should allow for @mentions to have punctuation' do
2013-04-10 11:27:33 +08:00
PrettyText . cook ( " hello @bob's @bob,@bob; @bob \" " ) . should
match_html " <p>hello <span class= \" mention \" >@bob</span>'s <span class= \" mention \" >@bob</span>,<span class= \" mention \" >@bob</span>; <span class= \" mention \" >@bob</span> \" </p> "
2013-02-06 03:16:51 +08:00
end
2014-10-03 10:37:07 +08:00
# see: https://github.com/sparklemotion/nokogiri/issues/1173
2014-10-29 23:06:50 +08:00
skip 'allows html entities correctly' do
2014-10-03 10:37:07 +08:00
PrettyText . cook ( " ℵ£& # 162; " ) . should == " <p>ℵ£& # 162;</p> "
end
2013-02-06 03:16:51 +08:00
end
2013-02-26 00:42:20 +08:00
2013-02-11 08:43:07 +08:00
describe " rel nofollow " do
2013-02-26 00:42:20 +08:00
before do
2013-02-11 08:43:07 +08:00
SiteSetting . stubs ( :add_rel_nofollow_to_user_content ) . returns ( true )
2014-03-30 07:50:44 +08:00
SiteSetting . stubs ( :exclude_rel_nofollow_domains ) . returns ( " foo.com|bar.com " )
2013-02-11 08:43:07 +08:00
end
2013-02-26 00:42:20 +08:00
it " should inject nofollow in all user provided links " do
2013-02-11 08:43:07 +08:00
PrettyText . cook ( '<a href="http://cnn.com">cnn</a>' ) . should =~ / nofollow /
end
2013-02-26 00:42:20 +08:00
it " should not inject nofollow in all local links " do
2014-09-25 23:44:48 +08:00
( PrettyText . cook ( " <a href=' #{ Discourse . base_url } /test.html'>cnn</a> " ) !~ / nofollow / ) . should == true
2013-02-11 08:43:07 +08:00
end
2013-02-26 00:42:20 +08:00
it " should not inject nofollow in all subdomain links " do
2014-09-25 23:44:48 +08:00
( PrettyText . cook ( " <a href=' #{ Discourse . base_url . sub ( 'http://' , 'http://bla.' ) } /test.html'>cnn</a> " ) !~ / nofollow / ) . should == true
2013-02-11 08:43:07 +08:00
end
2013-02-11 15:58:19 +08:00
it " should not inject nofollow for foo.com " do
2014-09-25 23:44:48 +08:00
( PrettyText . cook ( " <a href='http://foo.com/test.html'>cnn</a> " ) !~ / nofollow / ) . should == true
2013-02-11 15:58:19 +08:00
end
2013-02-26 00:42:20 +08:00
2013-02-11 15:58:19 +08:00
it " should not inject nofollow for bar.foo.com " do
2014-09-25 23:44:48 +08:00
( PrettyText . cook ( " <a href='http://bar.foo.com/test.html'>cnn</a> " ) !~ / nofollow / ) . should == true
2013-02-11 15:58:19 +08:00
end
2014-01-16 00:34:17 +08:00
it " should not inject nofollow if omit_nofollow option is given " do
2014-09-25 23:44:48 +08:00
( PrettyText . cook ( '<a href="http://cnn.com">cnn</a>' , omit_nofollow : true ) !~ / nofollow / ) . should == true
2014-01-16 00:34:17 +08:00
end
2013-02-11 08:43:07 +08:00
end
2013-02-06 03:16:51 +08:00
2013-02-26 00:42:20 +08:00
describe " Excerpt " do
2013-04-30 11:25:55 +08:00
2014-07-25 10:15:43 +08:00
it " sanitizes attempts to inject invalid attributes " do
spinner = " <a href= \" http://thedailywtf.com/ \" data-bbcode= \" ' class='fa fa-spin \" >WTF</a> "
PrettyText . excerpt ( spinner , 20 ) . should match_html spinner
spinner = %q{ <a href="http://thedailywtf.com/" title="' class="fa fa-spin"><img src='http://thedailywtf.com/Resources/Images/Primary/logo.gif"></a> }
PrettyText . excerpt ( spinner , 20 ) . should match_html spinner
end
2013-06-06 06:54:46 +08:00
context " images " do
2014-07-17 13:40:19 +08:00
2013-06-06 06:54:46 +08:00
it " should dump images " do
PrettyText . excerpt ( " <img src='http://cnn.com/a.gif'> " , 100 ) . should == " [image] "
end
2013-04-30 11:25:55 +08:00
2013-06-06 06:54:46 +08:00
it " should keep alt tags " do
PrettyText . excerpt ( " <img src='http://cnn.com/a.gif' alt='car' title='my big car'> " , 100 ) . should == " [car] "
end
it " should keep title tags " do
PrettyText . excerpt ( " <img src='http://cnn.com/a.gif' title='car'> " , 100 ) . should == " [car] "
end
it " should convert images to markdown if the option is set " do
PrettyText . excerpt ( " <img src='http://cnn.com/a.gif' title='car'> " , 100 , markdown_images : true ) . should == " ![car](http://cnn.com/a.gif) "
end
2013-02-06 03:16:51 +08:00
2014-02-20 16:48:30 +08:00
it " should keep spoilers " do
2014-07-25 10:15:43 +08:00
PrettyText . excerpt ( " <div class='spoiler'><img src='http://cnn.com/a.gif'></div> " , 100 ) . should match_html " <span class='spoiler'>[image]</span> "
PrettyText . excerpt ( " <span class='spoiler'>spoiler</div> " , 100 ) . should match_html " <span class='spoiler'>spoiler</span> "
2014-02-20 16:48:30 +08:00
end
2014-11-06 03:37:00 +08:00
it " should remove meta informations " do
PrettyText . excerpt ( wrapped_image , 100 ) . should match_html " <a href='//localhost:3000/uploads/default/4399/33691397e78b4d75.png' class='lightbox' title='Screen Shot 2014-04-14 at 9.47.10 PM.png'>[image]</a> "
end
2013-02-06 03:16:51 +08:00
end
2013-02-26 00:42:20 +08:00
2013-06-06 06:54:46 +08:00
it " should have an option to strip links " do
PrettyText . excerpt ( " <a href='http://cnn.com'>cnn</a> " , 100 , strip_links : true ) . should == " cnn "
2013-02-06 03:16:51 +08:00
end
2013-02-26 00:42:20 +08:00
2013-06-06 06:54:46 +08:00
it " should preserve links " do
2014-07-25 10:15:43 +08:00
PrettyText . excerpt ( " <a href='http://cnn.com'>cnn</a> " , 100 ) . should match_html " <a href='http://cnn.com'>cnn</a> "
2013-02-06 03:16:51 +08:00
end
2013-02-26 00:42:20 +08:00
it " should deal with special keys properly " do
2013-02-06 03:16:51 +08:00
PrettyText . excerpt ( " <pre><b></pre> " , 100 ) . should == " "
end
2013-02-26 00:42:20 +08:00
it " should truncate stuff properly " do
2013-02-06 03:16:51 +08:00
PrettyText . excerpt ( " hello world " , 5 ) . should == " hello… "
2013-05-10 18:28:17 +08:00
PrettyText . excerpt ( " <p>hello</p><p>world</p> " , 6 ) . should == " hello w… "
2013-02-06 03:16:51 +08:00
end
2013-02-26 00:42:20 +08:00
it " should insert a space between to Ps " do
2013-06-05 00:05:36 +08:00
PrettyText . excerpt ( " <p>a</p><p>b</p> " , 5 ) . should == " a b "
2013-02-06 03:16:51 +08:00
end
2013-02-26 00:42:20 +08:00
it " should strip quotes " do
2013-02-06 03:16:51 +08:00
PrettyText . excerpt ( " <aside class='quote'><p>a</p><p>b</p></aside>boom " , 5 ) . should == " boom "
end
2013-02-26 00:42:20 +08:00
it " should not count the surrounds of a link " do
2014-07-25 10:15:43 +08:00
PrettyText . excerpt ( " <a href='http://cnn.com'>cnn</a> " , 3 ) . should match_html " <a href='http://cnn.com'>cnn</a> "
2013-02-06 03:16:51 +08:00
end
2013-06-04 04:12:24 +08:00
it " uses an ellipsis instead of html entities if provided with the option " do
2014-07-25 10:15:43 +08:00
PrettyText . excerpt ( " <a href='http://cnn.com'>cnn</a> " , 2 , text_entities : true ) . should match_html " <a href='http://cnn.com'>cn...</a> "
2013-06-04 04:12:24 +08:00
end
2013-02-26 00:42:20 +08:00
it " should truncate links " do
2014-07-25 10:15:43 +08:00
PrettyText . excerpt ( " <a href='http://cnn.com'>cnn</a> " , 2 ) . should match_html " <a href='http://cnn.com'>cn…</a> "
2013-02-06 03:16:51 +08:00
end
2014-05-21 05:20:52 +08:00
it " doesn't extract empty quotes as links " do
PrettyText . extract_links ( " <aside class='quote'>not a linked quote</aside> \n " ) . to_a . should be_empty
end
2014-07-11 12:17:01 +08:00
def extract_urls ( text )
PrettyText . extract_links ( text ) . map ( & :url ) . to_a
end
2013-02-26 00:42:20 +08:00
it " should be able to extract links " do
2014-07-11 12:17:01 +08:00
extract_urls ( " <a href='http://cnn.com'>http://bla.com</a> " ) . should == [ " http://cnn.com " ]
2013-02-06 03:16:51 +08:00
end
2013-02-14 04:22:04 +08:00
it " should extract links to topics " do
2014-07-11 12:17:01 +08:00
extract_urls ( " <aside class= \" quote \" data-topic= \" 321 \" >aside</aside> " ) . should == [ " /t/topic/321 " ]
2013-02-14 04:22:04 +08:00
end
it " should extract links to posts " do
2014-07-11 12:17:01 +08:00
extract_urls ( " <aside class= \" quote \" data-topic= \" 1234 \" data-post= \" 4567 \" >aside</aside> " ) . should == [ " /t/topic/1234/4567 " ]
2013-02-14 04:22:04 +08:00
end
2013-06-06 02:53:07 +08:00
it " should not extract links inside quotes " do
2014-07-11 12:17:01 +08:00
links = PrettyText . extract_links ( "
2013-06-06 02:53:07 +08:00
< a href = 'http://body_only.com' > http : / /use less1 . com < / a>
< aside class = \ " quote \" data-topic= \" 1234 \" >
< a href = 'http://body_and_quote.com' > http : / /use less3 . com < / a>
< a href = 'http://quote_only.com' > http : / /use less4 . com < / a>
< / aside>
< a href = 'http://body_and_quote.com' > http : / /use less2 . com < / a>
2014-07-11 12:17:01 +08:00
" )
links . map { | l | [ l . url , l . is_quote ] } . to_a . sort . should ==
[ [ " http://body_only.com " , false ] ,
[ " http://body_and_quote.com " , false ] ,
[ " /t/topic/1234 " , true ]
] . sort
2013-06-06 02:53:07 +08:00
end
2013-02-26 00:42:20 +08:00
it " should not preserve tags in code blocks " do
2013-02-06 03:16:51 +08:00
PrettyText . excerpt ( " <pre><code class='handlebars'><h3>Hours</h3></code></pre> " , 100 ) . should == " <h3>Hours</h3> "
end
it " should handle nil " do
PrettyText . excerpt ( nil , 100 ) . should == ''
end
2013-05-10 18:28:17 +08:00
2014-09-03 15:12:56 +08:00
it " handles span excerpt at the beginning of a post " do
2014-07-17 19:32:17 +08:00
PrettyText . excerpt ( " <span class='excerpt'>hi</span> test " , 100 ) . should == 'hi'
post = Fabricate ( :post , raw : " <span class='excerpt'>hi</span> test " )
post . excerpt . should == " hi "
end
2014-09-04 13:03:12 +08:00
it " ignores max excerpt length if a span excerpt is specified " do
two_hundred = " 123456789 " * 20 + " . "
text = two_hundred + " <span class='excerpt'> #{ two_hundred } </span> " + two_hundred
PrettyText . excerpt ( text , 100 ) . should == two_hundred
2014-09-03 15:12:56 +08:00
post = Fabricate ( :post , raw : text )
2014-09-04 13:03:12 +08:00
post . excerpt . should == two_hundred
2014-09-03 15:12:56 +08:00
end
2014-12-10 19:52:51 +08:00
it " unescapes html entities when we want text entities " do
PrettyText . excerpt ( " & # 39; " , 500 , text_entities : true ) . should == " ' "
end
2013-02-06 03:16:51 +08:00
end
2013-06-06 03:28:10 +08:00
describe " strip links " do
it " returns blank for blank input " do
expect ( PrettyText . strip_links ( " " ) ) . to be_blank
end
it " does nothing to a string without links " do
expect ( PrettyText . strip_links ( " I'm the <b>batman</b> " ) ) . to eq ( " I'm the <b>batman</b> " )
end
it " strips links but leaves the text content " do
expect ( PrettyText . strip_links ( " I'm the linked <a href='http://en.wikipedia.org/wiki/Batman'>batman</a> " ) ) . to eq ( " I'm the linked batman " )
end
2014-09-18 00:08:00 +08:00
it " escapes the text content " do
expect ( PrettyText . strip_links ( " I'm the linked <a href='http://en.wikipedia.org/wiki/Batman'><batman></a> " ) ) . to eq ( " I'm the linked <batman> " )
end
2013-06-06 03:28:10 +08:00
end
2013-02-11 08:43:07 +08:00
2013-11-29 04:57:21 +08:00
describe " make_all_links_absolute " do
let ( :base_url ) { " http://baseurl.net " }
2014-04-18 00:32:51 +08:00
def make_abs_string ( html )
doc = Nokogiri :: HTML . fragment ( html )
described_class . make_all_links_absolute ( doc )
doc . to_html
end
2013-11-29 04:57:21 +08:00
before do
Discourse . stubs ( :base_url ) . returns ( base_url )
end
it " adds base url to relative links " do
html = " <p><a class= \" mention \" href= \" /users/wiseguy \" >@wiseguy</a>, <a class= \" mention \" href= \" /users/trollol \" >@trollol</a> what do you guys think? </p> "
2014-04-18 00:32:51 +08:00
output = make_abs_string ( html )
2013-11-29 04:57:21 +08:00
output . should == " <p><a class= \" mention \" href= \" #{ base_url } /users/wiseguy \" >@wiseguy</a>, <a class= \" mention \" href= \" #{ base_url } /users/trollol \" >@trollol</a> what do you guys think? </p> "
end
it " doesn't change external absolute links " do
html = " <p>Check out <a href= \" http://mywebsite.com/users/boss \" >this guy</a>.</p> "
2014-04-18 00:32:51 +08:00
make_abs_string ( html ) . should == html
2013-11-29 04:57:21 +08:00
end
it " doesn't change internal absolute links " do
html = " <p>Check out <a href= \" #{ base_url } /users/boss \" >this guy</a>.</p> "
2014-04-18 00:32:51 +08:00
make_abs_string ( html ) . should == html
2013-11-29 04:57:21 +08:00
end
it " can tolerate invalid URLs " do
html = " <p>Check out <a href= \" not a real url \" >this guy</a>.</p> "
2014-04-18 00:32:51 +08:00
expect { make_abs_string ( html ) } . to_not raise_error
end
end
describe " strip_image_wrapping " do
def strip_image_wrapping ( html )
doc = Nokogiri :: HTML . fragment ( html )
described_class . strip_image_wrapping ( doc )
doc . to_html
end
it " doesn't change HTML when there's no wrapped image " do
html = " <img src= \" wat.png \" > "
strip_image_wrapping ( html ) . should == html
end
it " strips the metadata " do
2014-11-06 03:37:00 +08:00
strip_image_wrapping ( wrapped_image ) . should match_html " <div class= \" lightbox-wrapper \" ><a href= \" //localhost:3000/uploads/default/4399/33691397e78b4d75.png \" class= \" lightbox \" title= \" Screen Shot 2014-04-14 at 9.47.10 PM.png \" ><img src= \" //localhost:3000/uploads/default/_optimized/bd9/b20/bbbcd6a0c0_655x500.png \" width= \" 655 \" height= \" 500 \" ></a></div> "
2013-11-29 04:57:21 +08:00
end
end
2014-07-30 15:09:55 +08:00
describe 'format_for_email' do
it 'does not crash' do
PrettyText . format_for_email ( '<a href="mailto:michael.brown@discourse.org?subject=Your%20post%20at%20http://try.discourse.org/t/discussion-happens-so-much/127/1000?u=supermathie">test</a>' )
end
end
2014-12-23 15:25:10 +08:00
it 'can escape *' do
PrettyText . cook ( " ***a***a " ) . should match_html ( " <p><strong><em>a</em></strong>a</p> " )
PrettyText . cook ( " *** \\ ****a " ) . should match_html ( " <p><strong><em>*</em></strong>a</p> " )
end
2013-02-06 03:16:51 +08:00
end