mirror of
https://github.com/discourse/discourse.git
synced 2025-06-04 03:54:47 +08:00
FIX: smarter newline handling for <img> tags on line alone
Run all of pretty text spec on new engine
This commit is contained in:
@ -4,6 +4,10 @@ require 'html_normalize'
|
||||
|
||||
describe PrettyText do
|
||||
|
||||
before do
|
||||
SiteSetting.enable_experimental_markdown_it = true
|
||||
end
|
||||
|
||||
def n(html)
|
||||
HtmlNormalize.normalize(html)
|
||||
end
|
||||
@ -12,23 +16,15 @@ describe PrettyText do
|
||||
n(PrettyText.cook(*args))
|
||||
end
|
||||
|
||||
# see: https://github.com/sparklemotion/nokogiri/issues/1173
|
||||
skip 'allows html entities correctly' do
|
||||
expect(PrettyText.cook("ℵ£¢")).to eq("<p>ℵ£¢</p>")
|
||||
end
|
||||
|
||||
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) { }
|
||||
|
||||
describe "Cooking" do
|
||||
|
||||
describe "off topic quoting" do
|
||||
it "can correctly populate topic title" do
|
||||
topic = Fabricate(:topic, title: "this is a test topic :slight_smile:")
|
||||
expected = <<HTML
|
||||
<aside class="quote" data-post="2" data-topic="#{topic.id}"><div class="title">
|
||||
<div class="quote-controls"></div><a href="http://test.localhost/t/this-is-a-test-topic-slight-smile/#{topic.id}/2">This is a test topic <img src="/images/emoji/twitter/slight_smile.png?v=5" title="slight_smile" alt="slight_smile" class="emoji"></a>
|
||||
</div>
|
||||
<blockquote><p>ddd</p></blockquote></aside>
|
||||
HTML
|
||||
expect(PrettyText.cook("[quote=\"EvilTrout, post:2, topic:#{topic.id}\"]ddd\n[/quote]", topic_id: 1)).to match_html expected
|
||||
end
|
||||
end
|
||||
describe "Quoting" do
|
||||
|
||||
describe "with avatar" do
|
||||
let(:default_avatar) { "//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/{size}.png" }
|
||||
@ -38,19 +34,91 @@ HTML
|
||||
User.stubs(:default_template).returns(default_avatar)
|
||||
end
|
||||
|
||||
it "produces a quote even with new lines in it" do
|
||||
expect(PrettyText.cook("[quote=\"#{user.username}, post:123, topic:456, full:true\"]ddd\n[/quote]")).to 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 alt='' width=\"20\" height=\"20\" src=\"//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">#{user.username}:</div>\n<blockquote><p>ddd</p></blockquote></aside>"
|
||||
it "do off topic quoting with emoji unescape" do
|
||||
|
||||
topic = Fabricate(:topic, title: "this is a test topic :slight_smile:")
|
||||
expected = <<~HTML
|
||||
<aside class="quote" data-topic="#{topic.id}" data-post="2">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<a href="http://test.localhost/t/this-is-a-test-topic-slight-smile/#{topic.id}/2">This is a test topic <img src="/images/emoji/twitter/slight_smile.png?v=5" title="slight_smile" alt="slight_smile" class="emoji"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>ddd</p>
|
||||
</blockquote>
|
||||
</aside>
|
||||
HTML
|
||||
|
||||
expect(cook("[quote=\"EvilTrout, post:2, topic:#{topic.id}\"]\nddd\n[/quote]", topic_id: 1)).to eq(n(expected))
|
||||
end
|
||||
|
||||
it "should produce a quote" do
|
||||
expect(PrettyText.cook("[quote=\"#{user.username}, post:123, topic:456, full:true\"]ddd[/quote]")).to 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 alt='' width=\"20\" height=\"20\" src=\"//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">#{user.username}:</div>\n<blockquote><p>ddd</p></blockquote></aside>"
|
||||
it "produces a quote even with new lines in it" do
|
||||
md = <<~MD
|
||||
[quote="#{user.username}, post:123, topic:456, full:true"]
|
||||
|
||||
ddd
|
||||
|
||||
[/quote]
|
||||
MD
|
||||
html = <<~HTML
|
||||
<aside class="quote" data-post="123" data-topic="456">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img alt width="20" height="20" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png" class="avatar"> #{user.username}:</div>
|
||||
<blockquote>
|
||||
<p>ddd</p>
|
||||
</blockquote>
|
||||
</aside>
|
||||
HTML
|
||||
|
||||
expect(PrettyText.cook(md)).to eq(html.strip)
|
||||
end
|
||||
|
||||
|
||||
it "trims spaces on quote params" do
|
||||
expect(PrettyText.cook("[quote=\"#{user.username}, post:555, topic: 666\"]ddd[/quote]")).to match_html "<aside class=\"quote\" data-post=\"555\" data-topic=\"666\"><div class=\"title\">\n<div class=\"quote-controls\"></div>\n<img alt='' width=\"20\" height=\"20\" src=\"//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">#{user.username}:</div>\n<blockquote><p>ddd</p></blockquote></aside>"
|
||||
md = <<~MD
|
||||
[quote="#{user.username}, post:555, topic: 666"]
|
||||
ddd
|
||||
[/quote]
|
||||
MD
|
||||
|
||||
html = <<~HTML
|
||||
<aside class="quote" data-post="555" data-topic="666">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<img alt width="20" height="20" src="//test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png" class="avatar"> #{user.username}:</div>
|
||||
<blockquote>
|
||||
<p>ddd</p>
|
||||
</blockquote>
|
||||
</aside>
|
||||
HTML
|
||||
|
||||
expect(PrettyText.cook(md)).to eq(html.strip)
|
||||
end
|
||||
end
|
||||
|
||||
it "can handle quote edge cases" do
|
||||
expect(PrettyText.cook("a\n[quote]\ntest\n[/quote]\n\n\na")).to include('aside')
|
||||
expect(PrettyText.cook("- a\n[quote]\ntest\n[/quote]\n\n\na")).to include('aside')
|
||||
expect(PrettyText.cook("[quote]\ntest")).not_to include('aside')
|
||||
expect(PrettyText.cook("[quote]abc\ntest\n[/quote]")).not_to include('aside')
|
||||
expect(PrettyText.cook("[quote]\ntest\n[/quote]z")).not_to include('aside')
|
||||
|
||||
nested = <<~QUOTE
|
||||
[quote]
|
||||
a
|
||||
[quote]
|
||||
b
|
||||
[/quote]
|
||||
c
|
||||
[/quote]
|
||||
QUOTE
|
||||
|
||||
cooked = PrettyText.cook(nested)
|
||||
expect(cooked.scan('aside').length).to eq(4)
|
||||
expect(cooked.scan('quote]').length).to eq(0)
|
||||
end
|
||||
|
||||
describe "with letter avatar" do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
@ -61,22 +129,44 @@ HTML
|
||||
end
|
||||
|
||||
it "should have correct avatar url" do
|
||||
expect(PrettyText.cook("[quote=\"#{user.username}, post:123, topic:456, full:true\"]ddd[/quote]")).to include("/forum/letter_avatar_proxy")
|
||||
md = <<~MD
|
||||
[quote="#{user.username}, post:123, topic:456, full:true"]
|
||||
ddd
|
||||
[/quote]
|
||||
MD
|
||||
expect(PrettyText.cook(md)).to include("/forum/letter_avatar_proxy")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Mentions" do
|
||||
|
||||
it "should handle 3 mentions in a row" do
|
||||
expect(PrettyText.cook('@hello @hello @hello')).to match_html "<p><span class=\"mention\">@hello</span> <span class=\"mention\">@hello</span> <span class=\"mention\">@hello</span></p>"
|
||||
end
|
||||
|
||||
it "should handle group mentions with a hyphen and without" do
|
||||
expect(PrettyText.cook('@hello @hello-hello')).to match_html "<p><span class=\"mention\">@hello</span> <span class=\"mention\">@hello-hello</span></p>"
|
||||
it "can handle mentions" do
|
||||
Fabricate(:user, username: "sam")
|
||||
expect(PrettyText.cook("hi @sam! hi")).to match_html '<p>hi <a class="mention" href="/u/sam">@sam</a>! hi</p>'
|
||||
expect(PrettyText.cook("hi\n@sam")).to eq("<p>hi<br>\n<a class=\"mention\" href=\"/u/sam\">@sam</a></p>")
|
||||
end
|
||||
|
||||
it "can handle mentions inside a hyperlink" do
|
||||
expect(PrettyText.cook("<a> @inner</a> ")).to match_html '<p><a> @inner</a></p>'
|
||||
end
|
||||
|
||||
|
||||
it "should sanitize the html" do
|
||||
expect(PrettyText.cook("<script>alert(42)</script>")).to match_html "<p></p>"
|
||||
it "can handle mentions inside a hyperlink" do
|
||||
expect(PrettyText.cook("[link @inner](http://site.com)")).to match_html '<p><a href="http://site.com" rel="nofollow noopener">link @inner</a></p>'
|
||||
end
|
||||
|
||||
it "can handle a list of mentions" do
|
||||
expect(PrettyText.cook("@a,@b")).to match_html('<p><span class="mention">@a</span>,<span class="mention">@b</span></p>')
|
||||
end
|
||||
|
||||
it "should handle group mentions with a hyphen and without" do
|
||||
expect(PrettyText.cook('@hello @hello-hello')).to match_html "<p><span class=\"mention\">@hello</span> <span class=\"mention\">@hello-hello</span></p>"
|
||||
end
|
||||
|
||||
it 'should allow for @mentions to have punctuation' do
|
||||
@ -85,13 +175,52 @@ HTML
|
||||
)
|
||||
end
|
||||
|
||||
# see: https://github.com/sparklemotion/nokogiri/issues/1173
|
||||
skip 'allows html entities correctly' do
|
||||
expect(PrettyText.cook("ℵ£¢")).to eq("<p>ℵ£¢</p>")
|
||||
end
|
||||
|
||||
describe "code fences" do
|
||||
it 'indents code correctly' do
|
||||
code = <<~MD
|
||||
X
|
||||
```
|
||||
#
|
||||
x
|
||||
```
|
||||
MD
|
||||
cooked = PrettyText.cook(code)
|
||||
|
||||
html = <<~HTML
|
||||
<p>X</p>
|
||||
<pre><code class="lang-auto"> #
|
||||
x
|
||||
</code></pre>
|
||||
HTML
|
||||
|
||||
expect(cooked).to eq(html.strip)
|
||||
end
|
||||
|
||||
it "doesn't replace emoji in code blocks with our emoji sets if emoji is enabled" do
|
||||
expect(PrettyText.cook("```\n💣`\n```\n")).not_to match(/\:bomb\:/)
|
||||
end
|
||||
|
||||
it 'can include code class correctly' do
|
||||
expect(PrettyText.cook("```cpp\ncpp\n```")).to match_html("<pre><code class='lang-cpp'>cpp\n</code></pre>")
|
||||
expect(PrettyText.cook("```\ncpp\n```")).to match_html("<pre><code class='lang-auto'>cpp\n</code></pre>")
|
||||
expect(PrettyText.cook("```text\ncpp\n```")).to match_html("<pre><code class='lang-nohighlight'>cpp\n</code></pre>")
|
||||
end
|
||||
|
||||
it 'indents code correctly' do
|
||||
code = "X\n```\n\n #\n x\n```"
|
||||
cooked = PrettyText.cook(code)
|
||||
expect(cooked).to match_html("<p>X</p>\n<pre><code class=\"lang-auto\">\n #\n x\n</code></pre>")
|
||||
end
|
||||
|
||||
it 'does censor code fences' do
|
||||
SiteSetting.censored_words = 'apple|banana'
|
||||
expect(PrettyText.cook("# banana")).not_to include('banana')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "rel nofollow" do
|
||||
before do
|
||||
SiteSetting.add_rel_nofollow_to_user_content = true
|
||||
@ -330,7 +459,6 @@ HTML
|
||||
)).to eq("boom")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "strip links" do
|
||||
@ -402,20 +530,55 @@ HTML
|
||||
end
|
||||
end
|
||||
|
||||
it 'can escape *' do
|
||||
expect(PrettyText.cook("***a***a")).to match_html("<p><strong><em>a</em></strong>a</p>")
|
||||
expect(PrettyText.cook("***\\****a")).to match_html("<p><strong><em>*</em></strong>a</p>")
|
||||
it 'Is smart about linebreaks and IMG tags' do
|
||||
raw = <<~MD
|
||||
a <img>
|
||||
<img>
|
||||
|
||||
<img>
|
||||
<img>
|
||||
|
||||
<img>
|
||||
a
|
||||
|
||||
<img>
|
||||
- li
|
||||
|
||||
<img>
|
||||
```
|
||||
test
|
||||
```
|
||||
|
||||
```
|
||||
test
|
||||
```
|
||||
MD
|
||||
|
||||
html = <<~HTML
|
||||
<p>a <img><br>
|
||||
<img></p>
|
||||
<p>
|
||||
<img><br>
|
||||
<img></p>
|
||||
<p>
|
||||
<img></p>
|
||||
<p>a</p>
|
||||
<p>
|
||||
<img></p>
|
||||
<ul>
|
||||
<li>li</li>
|
||||
</ul>
|
||||
<p>
|
||||
<img></p>
|
||||
<pre><code class="lang-auto">test
|
||||
</code></pre>
|
||||
<pre><code class="lang-auto">test
|
||||
</code></pre>
|
||||
HTML
|
||||
|
||||
expect(PrettyText.cook(raw)).to eq(html.strip)
|
||||
end
|
||||
|
||||
it 'can include code class correctly' do
|
||||
expect(PrettyText.cook("```cpp\ncpp\n```")).to match_html("<p></p><pre><code class='lang-cpp'>cpp</code></pre>")
|
||||
end
|
||||
|
||||
it 'indents code correctly' do
|
||||
code = "X\n```\n\n #\n x\n```"
|
||||
cooked = PrettyText.cook(code)
|
||||
expect(cooked).to match_html("<p>X<br></p>\n\n<p></p><pre><code class=\"lang-auto\"> #\n x</code></pre>")
|
||||
end
|
||||
|
||||
it 'can substitute s3 cdn correctly' do
|
||||
SiteSetting.enable_s3_uploads = true
|
||||
@ -425,19 +588,22 @@ HTML
|
||||
SiteSetting.s3_cdn_url = "https://awesome.cdn"
|
||||
|
||||
# add extra img tag to ensure it does not blow up
|
||||
raw = <<HTML
|
||||
<img>
|
||||
<img src='https:#{Discourse.store.absolute_base_url}/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg'>
|
||||
<img src='http:#{Discourse.store.absolute_base_url}/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg'>
|
||||
<img src='#{Discourse.store.absolute_base_url}/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg'>
|
||||
raw = <<~HTML
|
||||
<img>
|
||||
<img src='https:#{Discourse.store.absolute_base_url}/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg'>
|
||||
<img src='http:#{Discourse.store.absolute_base_url}/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg'>
|
||||
<img src='#{Discourse.store.absolute_base_url}/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg'>
|
||||
HTML
|
||||
|
||||
HTML
|
||||
html = <<~HTML
|
||||
<p>
|
||||
<img><br>
|
||||
<img src="https://awesome.cdn/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg"><br>
|
||||
<img src="https://awesome.cdn/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg"><br>
|
||||
<img src="https://awesome.cdn/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg"></p>
|
||||
HTML
|
||||
|
||||
cooked = <<HTML
|
||||
<p> <img><br> <img src="https://awesome.cdn/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg"><br> <img src="https://awesome.cdn/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg"><br> <img src="https://awesome.cdn/original/9/9/99c9384b8b6d87f8509f8395571bc7512ca3cad1.jpg"></p>
|
||||
HTML
|
||||
|
||||
expect(PrettyText.cook(raw)).to match_html(cooked)
|
||||
expect(PrettyText.cook(raw)).to eq(html.strip)
|
||||
end
|
||||
|
||||
describe "emoji" do
|
||||
@ -449,10 +615,6 @@ HTML
|
||||
expect(PrettyText.cook("`💣`")).not_to match(/\:bomb\:/)
|
||||
end
|
||||
|
||||
it "doesn't replace emoji in code blocks with our emoji sets if emoji is enabled" do
|
||||
expect(PrettyText.cook("```\n💣`\n```\n")).not_to match(/\:bomb\:/)
|
||||
end
|
||||
|
||||
it "replaces some glyphs that are not in the emoji range" do
|
||||
expect(PrettyText.cook("☺")).to match(/\:slight_smile\:/)
|
||||
end
|
||||
@ -470,22 +632,6 @@ HTML
|
||||
end
|
||||
end
|
||||
|
||||
describe "tag and category links" do
|
||||
it "produces tag links" do
|
||||
Fabricate(:topic, {tags: [Fabricate(:tag, name: 'known')]})
|
||||
|
||||
cooked = PrettyText.cook(" #unknown::tag #known::tag")
|
||||
|
||||
html = <<~HTML
|
||||
<p> <span class=\"hashtag\">#unknown::tag</span> <a class=\"hashtag\" href=\"http://test.localhost/tags/known\">#<span>known</span></a></p>
|
||||
HTML
|
||||
|
||||
expect(cooked).to match_html(html)
|
||||
end
|
||||
|
||||
# TODO does it make sense to generate hashtags for tags that are missing in action?
|
||||
end
|
||||
|
||||
describe "custom emoji" do
|
||||
it "replaces the custom emoji" do
|
||||
CustomEmoji.create!(name: 'trout', upload: Fabricate(:upload))
|
||||
@ -504,317 +650,245 @@ HTML
|
||||
end
|
||||
end
|
||||
|
||||
context "markdown it" do
|
||||
|
||||
before do
|
||||
SiteSetting.enable_experimental_markdown_it = true
|
||||
end
|
||||
|
||||
it "replaces skin toned emoji" do
|
||||
expect(PrettyText.cook("hello 👱🏿♀️")).to eq("<p>hello <img src=\"/images/emoji/twitter/blonde_woman/6.png?v=5\" title=\":blonde_woman:t6:\" class=\"emoji\" alt=\":blonde_woman:t6:\"></p>")
|
||||
expect(PrettyText.cook("hello 👩🎤")).to eq("<p>hello <img src=\"/images/emoji/twitter/woman_singer.png?v=5\" title=\":woman_singer:\" class=\"emoji\" alt=\":woman_singer:\"></p>")
|
||||
expect(PrettyText.cook("hello 👩🏾🎓")).to eq("<p>hello <img src=\"/images/emoji/twitter/woman_student/5.png?v=5\" title=\":woman_student:t5:\" class=\"emoji\" alt=\":woman_student:t5:\"></p>")
|
||||
expect(PrettyText.cook("hello 🤷♀️")).to eq("<p>hello <img src=\"/images/emoji/twitter/woman_shrugging.png?v=5\" title=\":woman_shrugging:\" class=\"emoji\" alt=\":woman_shrugging:\"></p>")
|
||||
end
|
||||
it "replaces skin toned emoji" do
|
||||
expect(PrettyText.cook("hello 👱🏿♀️")).to eq("<p>hello <img src=\"/images/emoji/twitter/blonde_woman/6.png?v=5\" title=\":blonde_woman:t6:\" class=\"emoji\" alt=\":blonde_woman:t6:\"></p>")
|
||||
expect(PrettyText.cook("hello 👩🎤")).to eq("<p>hello <img src=\"/images/emoji/twitter/woman_singer.png?v=5\" title=\":woman_singer:\" class=\"emoji\" alt=\":woman_singer:\"></p>")
|
||||
expect(PrettyText.cook("hello 👩🏾🎓")).to eq("<p>hello <img src=\"/images/emoji/twitter/woman_student/5.png?v=5\" title=\":woman_student:t5:\" class=\"emoji\" alt=\":woman_student:t5:\"></p>")
|
||||
expect(PrettyText.cook("hello 🤷♀️")).to eq("<p>hello <img src=\"/images/emoji/twitter/woman_shrugging.png?v=5\" title=\":woman_shrugging:\" class=\"emoji\" alt=\":woman_shrugging:\"></p>")
|
||||
end
|
||||
|
||||
|
||||
it "supports href schemes" do
|
||||
SiteSetting.allowed_href_schemes = "macappstore|steam"
|
||||
cooked = cook("[Steam URL Scheme](steam://store/452530)")
|
||||
expected = '<p><a href="steam://store/452530" rel="nofollow noopener">Steam URL Scheme</a></p>'
|
||||
expect(cooked).to eq(n expected)
|
||||
end
|
||||
it "supports href schemes" do
|
||||
SiteSetting.allowed_href_schemes = "macappstore|steam"
|
||||
cooked = cook("[Steam URL Scheme](steam://store/452530)")
|
||||
expected = '<p><a href="steam://store/452530" rel="nofollow noopener">Steam URL Scheme</a></p>'
|
||||
expect(cooked).to eq(n expected)
|
||||
end
|
||||
|
||||
it "supports forbidden schemes" do
|
||||
SiteSetting.allowed_href_schemes = "macappstore|itunes"
|
||||
cooked = cook("[Steam URL Scheme](steam://store/452530)")
|
||||
expected = '<p><a>Steam URL Scheme</a></p>'
|
||||
expect(cooked).to eq(n expected)
|
||||
end
|
||||
it "supports forbidden schemes" do
|
||||
SiteSetting.allowed_href_schemes = "macappstore|itunes"
|
||||
cooked = cook("[Steam URL Scheme](steam://store/452530)")
|
||||
expected = '<p><a>Steam URL Scheme</a></p>'
|
||||
expect(cooked).to eq(n expected)
|
||||
end
|
||||
|
||||
it "produces tag links" do
|
||||
Fabricate(:topic, {tags: [Fabricate(:tag, name: 'known')]})
|
||||
it "produces tag links" do
|
||||
Fabricate(:topic, {tags: [Fabricate(:tag, name: 'known')]})
|
||||
|
||||
cooked = PrettyText.cook(" #unknown::tag #known::tag")
|
||||
cooked = PrettyText.cook(" #unknown::tag #known::tag")
|
||||
|
||||
html = <<~HTML
|
||||
<p><span class=\"hashtag\">#unknown::tag</span> <a class=\"hashtag\" href=\"http://test.localhost/tags/known\">#<span>known</span></a></p>
|
||||
HTML
|
||||
html = <<~HTML
|
||||
<p><span class=\"hashtag\">#unknown::tag</span> <a class=\"hashtag\" href=\"http://test.localhost/tags/known\">#<span>known</span></a></p>
|
||||
HTML
|
||||
|
||||
expect(cooked).to eq(html.strip)
|
||||
expect(cooked).to eq(html.strip)
|
||||
|
||||
cooked = PrettyText.cook("[`a` #known::tag here](http://somesite.com)")
|
||||
cooked = PrettyText.cook("[`a` #known::tag here](http://somesite.com)")
|
||||
|
||||
html = <<~HTML
|
||||
<p><a href="http://somesite.com" rel="nofollow noopener"><code>a</code> #known::tag here</a></p>
|
||||
HTML
|
||||
html = <<~HTML
|
||||
<p><a href="http://somesite.com" rel="nofollow noopener"><code>a</code> #known::tag here</a></p>
|
||||
HTML
|
||||
|
||||
expect(cooked).to eq(html.strip)
|
||||
expect(cooked).to eq(html.strip)
|
||||
|
||||
cooked = PrettyText.cook("<a href='http://somesite.com'>`a` #known::tag here</a>")
|
||||
cooked = PrettyText.cook("<a href='http://somesite.com'>`a` #known::tag here</a>")
|
||||
|
||||
expect(cooked).to eq(html.strip)
|
||||
expect(cooked).to eq(html.strip)
|
||||
|
||||
cooked = PrettyText.cook("<A href='/a'>test</A> #known::tag")
|
||||
html = <<~HTML
|
||||
<p><a href="/a">test</a> <a class="hashtag" href="http://test.localhost/tags/known">#<span>known</span></a></p>
|
||||
HTML
|
||||
cooked = PrettyText.cook("<A href='/a'>test</A> #known::tag")
|
||||
html = <<~HTML
|
||||
<p><a href="/a">test</a> <a class="hashtag" href="http://test.localhost/tags/known">#<span>known</span></a></p>
|
||||
HTML
|
||||
|
||||
expect(cooked).to eq(html.strip)
|
||||
expect(cooked).to eq(html.strip)
|
||||
|
||||
# ensure it does not fight with the autolinker
|
||||
expect(PrettyText.cook(' http://somewhere.com/#known')).not_to include('hashtag')
|
||||
expect(PrettyText.cook(' http://somewhere.com/?#known')).not_to include('hashtag')
|
||||
expect(PrettyText.cook(' http://somewhere.com/?abc#known')).not_to include('hashtag')
|
||||
|
||||
end
|
||||
|
||||
it "can handle mixed lists" do
|
||||
# known bug in old md engine
|
||||
cooked = PrettyText.cook("* a\n\n1. b")
|
||||
expect(cooked).to match_html("<ul>\n<li>a</li>\n</ul><ol>\n<li>b</li>\n</ol>")
|
||||
end
|
||||
|
||||
it "can handle traditional vs non traditional newlines" do
|
||||
SiteSetting.traditional_markdown_linebreaks = true
|
||||
expect(PrettyText.cook("1\n2")).to match_html "<p>1 2</p>"
|
||||
|
||||
SiteSetting.traditional_markdown_linebreaks = false
|
||||
expect(PrettyText.cook("1\n2")).to match_html "<p>1<br>\n2</p>"
|
||||
end
|
||||
|
||||
it "can handle mentions" do
|
||||
Fabricate(:user, username: "sam")
|
||||
expect(PrettyText.cook("hi @sam! hi")).to match_html '<p>hi <a class="mention" href="/u/sam">@sam</a>! hi</p>'
|
||||
expect(PrettyText.cook("hi\n@sam")).to eq("<p>hi<br>\n<a class=\"mention\" href=\"/u/sam\">@sam</a></p>")
|
||||
end
|
||||
|
||||
it "can handle mentions inside a hyperlink" do
|
||||
expect(PrettyText.cook("<a> @inner</a> ")).to match_html '<p><a> @inner</a></p>'
|
||||
end
|
||||
|
||||
|
||||
it "can handle mentions inside a hyperlink" do
|
||||
expect(PrettyText.cook("[link @inner](http://site.com)")).to match_html '<p><a href="http://site.com" rel="nofollow noopener">link @inner</a></p>'
|
||||
end
|
||||
|
||||
it "can handle a list of mentions" do
|
||||
expect(PrettyText.cook("@a,@b")).to match_html('<p><span class="mention">@a</span>,<span class="mention">@b</span></p>')
|
||||
end
|
||||
|
||||
it "can handle emoji by name" do
|
||||
|
||||
expected = <<HTML
|
||||
<p><img src="/images/emoji/twitter/smile.png?v=5\" title=":smile:" class="emoji" alt=":smile:"><img src="/images/emoji/twitter/sunny.png?v=5" title=":sunny:" class="emoji" alt=":sunny:"></p>
|
||||
HTML
|
||||
expect(PrettyText.cook(":smile::sunny:")).to eq(expected.strip)
|
||||
end
|
||||
|
||||
it "handles emoji boundaries correctly" do
|
||||
cooked = PrettyText.cook("a,:man:t2:,b")
|
||||
expected = '<p>a,<img src="/images/emoji/twitter/man/2.png?v=5" title=":man:t2:" class="emoji" alt=":man:t2:">,b</p>'
|
||||
expect(cooked).to match(expected.strip)
|
||||
end
|
||||
|
||||
it "can handle emoji by translation" do
|
||||
expected = '<p><img src="/images/emoji/twitter/wink.png?v=5" title=":wink:" class="emoji" alt=":wink:"></p>'
|
||||
expect(PrettyText.cook(";)")).to eq(expected)
|
||||
end
|
||||
|
||||
it "can handle multiple emojis by translation" do
|
||||
cooked = PrettyText.cook(":) ;) :)")
|
||||
expect(cooked.split("img").length-1).to eq(3)
|
||||
end
|
||||
|
||||
it "handles emoji boundries correctly" do
|
||||
expect(PrettyText.cook(",:)")).to include("emoji")
|
||||
expect(PrettyText.cook(":-)\n")).to include("emoji")
|
||||
expect(PrettyText.cook("a :)")).to include("emoji")
|
||||
expect(PrettyText.cook(":),")).not_to include("emoji")
|
||||
expect(PrettyText.cook("abcde ^:;-P")).to include("emoji")
|
||||
end
|
||||
|
||||
|
||||
it 'can include code class correctly' do
|
||||
expect(PrettyText.cook("```cpp\ncpp\n```")).to match_html("<pre><code class='lang-cpp'>cpp\n</code></pre>")
|
||||
expect(PrettyText.cook("```\ncpp\n```")).to match_html("<pre><code class='lang-auto'>cpp\n</code></pre>")
|
||||
expect(PrettyText.cook("```text\ncpp\n```")).to match_html("<pre><code class='lang-nohighlight'>cpp\n</code></pre>")
|
||||
end
|
||||
|
||||
it 'indents code correctly' do
|
||||
code = "X\n```\n\n #\n x\n```"
|
||||
cooked = PrettyText.cook(code)
|
||||
expect(cooked).to match_html("<p>X</p>\n<pre><code class=\"lang-auto\">\n #\n x\n</code></pre>")
|
||||
end
|
||||
|
||||
it 'can censor words correctly' do
|
||||
SiteSetting.censored_words = 'apple|banana'
|
||||
expect(PrettyText.cook('yay banana yay')).not_to include('banana')
|
||||
expect(PrettyText.cook('yay `banana` yay')).not_to include('banana')
|
||||
expect(PrettyText.cook("yay \n\n```\nbanana\n````\n yay")).not_to include('banana')
|
||||
expect(PrettyText.cook("# banana")).not_to include('banana')
|
||||
expect(PrettyText.cook("# banana")).to include("\u25a0\u25a0")
|
||||
end
|
||||
|
||||
it 'supports typographer' do
|
||||
SiteSetting.enable_markdown_typographer = true
|
||||
expect(PrettyText.cook('(tm)')).to eq('<p>™</p>')
|
||||
|
||||
SiteSetting.enable_markdown_typographer = false
|
||||
expect(PrettyText.cook('(tm)')).to eq('<p>(tm)</p>')
|
||||
end
|
||||
|
||||
it 'handles onebox correctly' do
|
||||
expect(PrettyText.cook("http://a.com\nhttp://b.com").split("onebox").length).to eq(3)
|
||||
expect(PrettyText.cook("http://a.com\n\nhttp://b.com").split("onebox").length).to eq(3)
|
||||
expect(PrettyText.cook("a\nhttp://a.com")).to include('onebox')
|
||||
expect(PrettyText.cook("> http://a.com")).not_to include('onebox')
|
||||
expect(PrettyText.cook("a\nhttp://a.com a")).not_to include('onebox')
|
||||
expect(PrettyText.cook("a\nhttp://a.com\na")).to include('onebox')
|
||||
expect(PrettyText.cook("http://a.com")).to include('onebox')
|
||||
expect(PrettyText.cook("http://a.com ")).to include('onebox')
|
||||
expect(PrettyText.cook("http://a.com a")).not_to include('onebox')
|
||||
expect(PrettyText.cook("- http://a.com")).not_to include('onebox')
|
||||
expect(PrettyText.cook("<http://a.com>")).not_to include('onebox')
|
||||
expect(PrettyText.cook(" http://a.com")).not_to include('onebox')
|
||||
expect(PrettyText.cook("a\n http://a.com")).not_to include('onebox')
|
||||
end
|
||||
|
||||
it "can handle bbcode" do
|
||||
expect(PrettyText.cook("a[b]b[/b]c")).to eq('<p>a<span class="bbcode-b">b</span>c</p>')
|
||||
expect(PrettyText.cook("a[i]b[/i]c")).to eq('<p>a<span class="bbcode-i">b</span>c</p>')
|
||||
end
|
||||
|
||||
it "can handle quote edge cases" do
|
||||
expect(PrettyText.cook("a\n[quote]\ntest\n[/quote]\n\n\na")).to include('aside')
|
||||
expect(PrettyText.cook("- a\n[quote]\ntest\n[/quote]\n\n\na")).to include('aside')
|
||||
expect(PrettyText.cook("[quote]\ntest")).not_to include('aside')
|
||||
expect(PrettyText.cook("[quote]abc\ntest\n[/quote]")).not_to include('aside')
|
||||
expect(PrettyText.cook("[quote]\ntest\n[/quote]z")).not_to include('aside')
|
||||
|
||||
nested = <<~QUOTE
|
||||
[quote]
|
||||
a
|
||||
[quote]
|
||||
b
|
||||
[/quote]
|
||||
c
|
||||
[/quote]
|
||||
QUOTE
|
||||
|
||||
cooked = PrettyText.cook(nested)
|
||||
expect(cooked.scan('aside').length).to eq(4)
|
||||
expect(cooked.scan('quote]').length).to eq(0)
|
||||
end
|
||||
|
||||
it "can onebox local topics" do
|
||||
op = Fabricate(:post)
|
||||
reply = Fabricate(:post, topic_id: op.topic_id)
|
||||
|
||||
|
||||
url = Discourse.base_url + reply.url
|
||||
quote = create_post(topic_id: op.topic.id, raw: "This is a sample reply with a quote\n\n#{url}")
|
||||
quote.reload
|
||||
|
||||
expect(quote.cooked).not_to include('[quote')
|
||||
end
|
||||
|
||||
it "supports tables" do
|
||||
|
||||
markdown = <<~MD
|
||||
| Tables | Are | Cool |
|
||||
| ------------- |:-------------:| -----:|
|
||||
| col 3 is | right-aligned | $1600 |
|
||||
MD
|
||||
|
||||
expected = <<~HTML
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tables</th>
|
||||
<th style="text-align:center">Are</th>
|
||||
<th style="text-align:right">Cool</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>col 3 is</td>
|
||||
<td style="text-align:center">right-aligned</td>
|
||||
<td style="text-align:right">$1600</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
HTML
|
||||
|
||||
expect(PrettyText.cook(markdown)).to eq(expected.strip)
|
||||
end
|
||||
|
||||
it "do off topic quoting with emoji unescape" do
|
||||
|
||||
topic = Fabricate(:topic, title: "this is a test topic :slight_smile:")
|
||||
expected = <<~HTML
|
||||
<aside class="quote" data-topic="#{topic.id}" data-post="2">
|
||||
<div class="title">
|
||||
<div class="quote-controls"></div>
|
||||
<a href="http://test.localhost/t/this-is-a-test-topic-slight-smile/#{topic.id}/2">This is a test topic <img src="/images/emoji/twitter/slight_smile.png?v=5" title="slight_smile" alt="slight_smile" class="emoji"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>ddd</p>
|
||||
</blockquote>
|
||||
</aside>
|
||||
HTML
|
||||
|
||||
expect(cook("[quote=\"EvilTrout, post:2, topic:#{topic.id}\"]\nddd\n[/quote]", topic_id: 1)).to eq(n(expected))
|
||||
end
|
||||
|
||||
it "supports img bbcode" do
|
||||
cooked = PrettyText.cook "[img]http://www.image/test.png[/img]"
|
||||
html = "<p><img src=\"http://www.image/test.png\" alt></p>"
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "provides safety for img bbcode" do
|
||||
cooked = PrettyText.cook "[img]http://aaa.com<script>alert(1);</script>[/img]"
|
||||
html = '<p><img src="http://aaa.com<script>alert(1);</script>" alt></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports email bbcode" do
|
||||
cooked = PrettyText.cook "[email]sam@sam.com[/email]"
|
||||
html = '<p><a href="mailto:sam@sam.com" data-bbcode="true">sam@sam.com</a></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports url bbcode" do
|
||||
cooked = PrettyText.cook "[url]http://sam.com[/url]"
|
||||
html = '<p><a href="http://sam.com" data-bbcode="true" rel="nofollow noopener">http://sam.com</a></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports inline code bbcode" do
|
||||
cooked = PrettyText.cook "Testing [code]codified **stuff** and `more` stuff[/code]"
|
||||
html = "<p>Testing <code>codified **stuff** and `more` stuff</code></p>"
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports block code bbcode" do
|
||||
cooked = PrettyText.cook "[code]\ncodified\n\n\n **stuff** and `more` stuff\n[/code]"
|
||||
html = "<pre><code class=\"lang-auto\">codified\n\n\n **stuff** and `more` stuff</code></pre>"
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "support special handling for space in urls" do
|
||||
cooked = PrettyText.cook "http://testing.com?a%20b"
|
||||
html = '<p><a href="http://testing.com?a%20b" class="onebox" rel="nofollow noopener">http://testing.com?a%20b</a></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports onebox for decoded urls" do
|
||||
cooked = PrettyText.cook "http://testing.com?a%50b"
|
||||
html = '<p><a href="http://testing.com?a%50b" class="onebox" rel="nofollow noopener">http://testing.com?aPb</a></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
# ensure it does not fight with the autolinker
|
||||
expect(PrettyText.cook(' http://somewhere.com/#known')).not_to include('hashtag')
|
||||
expect(PrettyText.cook(' http://somewhere.com/?#known')).not_to include('hashtag')
|
||||
expect(PrettyText.cook(' http://somewhere.com/?abc#known')).not_to include('hashtag')
|
||||
|
||||
end
|
||||
|
||||
it "can handle mixed lists" do
|
||||
# known bug in old md engine
|
||||
cooked = PrettyText.cook("* a\n\n1. b")
|
||||
expect(cooked).to match_html("<ul>\n<li>a</li>\n</ul><ol>\n<li>b</li>\n</ol>")
|
||||
end
|
||||
|
||||
it "can handle traditional vs non traditional newlines" do
|
||||
SiteSetting.traditional_markdown_linebreaks = true
|
||||
expect(PrettyText.cook("1\n2")).to match_html "<p>1 2</p>"
|
||||
|
||||
SiteSetting.traditional_markdown_linebreaks = false
|
||||
expect(PrettyText.cook("1\n2")).to match_html "<p>1<br>\n2</p>"
|
||||
end
|
||||
|
||||
|
||||
it "can handle emoji by name" do
|
||||
|
||||
expected = <<HTML
|
||||
<p><img src="/images/emoji/twitter/smile.png?v=5\" title=":smile:" class="emoji" alt=":smile:"><img src="/images/emoji/twitter/sunny.png?v=5" title=":sunny:" class="emoji" alt=":sunny:"></p>
|
||||
HTML
|
||||
expect(PrettyText.cook(":smile::sunny:")).to eq(expected.strip)
|
||||
end
|
||||
|
||||
it "handles emoji boundaries correctly" do
|
||||
cooked = PrettyText.cook("a,:man:t2:,b")
|
||||
expected = '<p>a,<img src="/images/emoji/twitter/man/2.png?v=5" title=":man:t2:" class="emoji" alt=":man:t2:">,b</p>'
|
||||
expect(cooked).to match(expected.strip)
|
||||
end
|
||||
|
||||
it "can handle emoji by translation" do
|
||||
expected = '<p><img src="/images/emoji/twitter/wink.png?v=5" title=":wink:" class="emoji" alt=":wink:"></p>'
|
||||
expect(PrettyText.cook(";)")).to eq(expected)
|
||||
end
|
||||
|
||||
it "can handle multiple emojis by translation" do
|
||||
cooked = PrettyText.cook(":) ;) :)")
|
||||
expect(cooked.split("img").length-1).to eq(3)
|
||||
end
|
||||
|
||||
it "handles emoji boundries correctly" do
|
||||
expect(PrettyText.cook(",:)")).to include("emoji")
|
||||
expect(PrettyText.cook(":-)\n")).to include("emoji")
|
||||
expect(PrettyText.cook("a :)")).to include("emoji")
|
||||
expect(PrettyText.cook(":),")).not_to include("emoji")
|
||||
expect(PrettyText.cook("abcde ^:;-P")).to include("emoji")
|
||||
end
|
||||
|
||||
it 'can censor words correctly' do
|
||||
SiteSetting.censored_words = 'apple|banana'
|
||||
expect(PrettyText.cook('yay banana yay')).not_to include('banana')
|
||||
expect(PrettyText.cook('yay `banana` yay')).not_to include('banana')
|
||||
expect(PrettyText.cook("# banana")).not_to include('banana')
|
||||
expect(PrettyText.cook("# banana")).to include("\u25a0\u25a0")
|
||||
end
|
||||
|
||||
it 'supports typographer' do
|
||||
SiteSetting.enable_markdown_typographer = true
|
||||
expect(PrettyText.cook('(tm)')).to eq('<p>™</p>')
|
||||
|
||||
SiteSetting.enable_markdown_typographer = false
|
||||
expect(PrettyText.cook('(tm)')).to eq('<p>(tm)</p>')
|
||||
end
|
||||
|
||||
it 'handles onebox correctly' do
|
||||
expect(PrettyText.cook("http://a.com\nhttp://b.com").split("onebox").length).to eq(3)
|
||||
expect(PrettyText.cook("http://a.com\n\nhttp://b.com").split("onebox").length).to eq(3)
|
||||
expect(PrettyText.cook("a\nhttp://a.com")).to include('onebox')
|
||||
expect(PrettyText.cook("> http://a.com")).not_to include('onebox')
|
||||
expect(PrettyText.cook("a\nhttp://a.com a")).not_to include('onebox')
|
||||
expect(PrettyText.cook("a\nhttp://a.com\na")).to include('onebox')
|
||||
expect(PrettyText.cook("http://a.com")).to include('onebox')
|
||||
expect(PrettyText.cook("http://a.com ")).to include('onebox')
|
||||
expect(PrettyText.cook("http://a.com a")).not_to include('onebox')
|
||||
expect(PrettyText.cook("- http://a.com")).not_to include('onebox')
|
||||
expect(PrettyText.cook("<http://a.com>")).not_to include('onebox')
|
||||
expect(PrettyText.cook(" http://a.com")).not_to include('onebox')
|
||||
expect(PrettyText.cook("a\n http://a.com")).not_to include('onebox')
|
||||
end
|
||||
|
||||
it "can handle bbcode" do
|
||||
expect(PrettyText.cook("a[b]b[/b]c")).to eq('<p>a<span class="bbcode-b">b</span>c</p>')
|
||||
expect(PrettyText.cook("a[i]b[/i]c")).to eq('<p>a<span class="bbcode-i">b</span>c</p>')
|
||||
end
|
||||
|
||||
|
||||
it "can onebox local topics" do
|
||||
op = Fabricate(:post)
|
||||
reply = Fabricate(:post, topic_id: op.topic_id)
|
||||
|
||||
|
||||
url = Discourse.base_url + reply.url
|
||||
quote = create_post(topic_id: op.topic.id, raw: "This is a sample reply with a quote\n\n#{url}")
|
||||
quote.reload
|
||||
|
||||
expect(quote.cooked).not_to include('[quote')
|
||||
end
|
||||
|
||||
it "supports tables" do
|
||||
|
||||
markdown = <<~MD
|
||||
| Tables | Are | Cool |
|
||||
| ------------- |:-------------:| -----:|
|
||||
| col 3 is | right-aligned | $1600 |
|
||||
MD
|
||||
|
||||
expected = <<~HTML
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tables</th>
|
||||
<th style="text-align:center">Are</th>
|
||||
<th style="text-align:right">Cool</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>col 3 is</td>
|
||||
<td style="text-align:center">right-aligned</td>
|
||||
<td style="text-align:right">$1600</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
HTML
|
||||
|
||||
expect(PrettyText.cook(markdown)).to eq(expected.strip)
|
||||
end
|
||||
|
||||
|
||||
it "supports img bbcode" do
|
||||
cooked = PrettyText.cook "[img]http://www.image/test.png[/img]"
|
||||
html = "<p><img src=\"http://www.image/test.png\" alt></p>"
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "provides safety for img bbcode" do
|
||||
cooked = PrettyText.cook "[img]http://aaa.com<script>alert(1);</script>[/img]"
|
||||
html = '<p><img src="http://aaa.com<script>alert(1);</script>" alt></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports email bbcode" do
|
||||
cooked = PrettyText.cook "[email]sam@sam.com[/email]"
|
||||
html = '<p><a href="mailto:sam@sam.com" data-bbcode="true">sam@sam.com</a></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports url bbcode" do
|
||||
cooked = PrettyText.cook "[url]http://sam.com[/url]"
|
||||
html = '<p><a href="http://sam.com" data-bbcode="true" rel="nofollow noopener">http://sam.com</a></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports inline code bbcode" do
|
||||
cooked = PrettyText.cook "Testing [code]codified **stuff** and `more` stuff[/code]"
|
||||
html = "<p>Testing <code>codified **stuff** and `more` stuff</code></p>"
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports block code bbcode" do
|
||||
cooked = PrettyText.cook "[code]\ncodified\n\n\n **stuff** and `more` stuff\n[/code]"
|
||||
html = "<pre><code class=\"lang-auto\">codified\n\n\n **stuff** and `more` stuff</code></pre>"
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "support special handling for space in urls" do
|
||||
cooked = PrettyText.cook "http://testing.com?a%20b"
|
||||
html = '<p><a href="http://testing.com?a%20b" class="onebox" rel="nofollow noopener">http://testing.com?a%20b</a></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
it "supports onebox for decoded urls" do
|
||||
cooked = PrettyText.cook "http://testing.com?a%50b"
|
||||
html = '<p><a href="http://testing.com?a%50b" class="onebox" rel="nofollow noopener">http://testing.com?aPb</a></p>'
|
||||
expect(cooked).to eq(html)
|
||||
end
|
||||
|
||||
|
||||
it "should sanitize the html" do
|
||||
expect(PrettyText.cook("<script>alert(42)</script>")).to eq ""
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
Reference in New Issue
Block a user