mirror of
https://github.com/discourse/discourse.git
synced 2024-12-05 06:13:42 +08:00
9e241e82e9
https://meta.discourse.org/t/markdown-preview-and-result-differ/263878 The result of this markdown had different results in the composer preview and the post. This is solved by updating Loofah to the latest version and using html5 fragments like our user had reported. While the change was only needed in cooked_post_processor.rb for this fix, other areas also had to be updated due to various side effects.
217 lines
5.9 KiB
Ruby
217 lines
5.9 KiB
Ruby
# frozen_string_literal: true
|
||
|
||
RSpec.describe PrettyText do
|
||
def n(html)
|
||
html.strip
|
||
end
|
||
|
||
it "supports multi choice polls" do
|
||
cooked = PrettyText.cook <<~MD
|
||
[poll type=multiple min=1 max=3 public=true]
|
||
* option 1
|
||
* option 2
|
||
* option 3
|
||
[/poll]
|
||
MD
|
||
|
||
expect(cooked).to include('class="poll"')
|
||
expect(cooked).to include('data-poll-status="open"')
|
||
expect(cooked).to include('data-poll-name="poll"')
|
||
expect(cooked).to include('data-poll-type="multiple"')
|
||
expect(cooked).to include('data-poll-min="1"')
|
||
expect(cooked).to include('data-poll-max="3"')
|
||
expect(cooked).to include('data-poll-public="true"')
|
||
end
|
||
|
||
it "can dynamically generate a poll" do
|
||
cooked = PrettyText.cook <<~MD
|
||
[poll type=number min=1 max=20 step=1]
|
||
[/poll]
|
||
MD
|
||
|
||
expect(cooked.scan("<li").length).to eq(20)
|
||
end
|
||
|
||
it "can properly bake 2 polls" do
|
||
md = <<~MD
|
||
this is a test
|
||
|
||
- i am a list
|
||
|
||
[poll]
|
||
1. test 1
|
||
2. test 2
|
||
[/poll]
|
||
|
||
[poll name=poll2]
|
||
1. test 1
|
||
2. test 2
|
||
[/poll]
|
||
MD
|
||
|
||
cooked = PrettyText.cook(md)
|
||
expect(cooked.scan('class="poll"').length).to eq(2)
|
||
end
|
||
|
||
it "does not break poll options when going from loose to tight" do
|
||
md = <<~MD
|
||
[poll type=multiple]
|
||
1. test 1 :) <b>test</b>
|
||
2. test 2
|
||
[/poll]
|
||
MD
|
||
|
||
tight_cooked = PrettyText.cook(md)
|
||
|
||
md = <<~MD
|
||
[poll type=multiple]
|
||
|
||
1. test 1 :) <b>test</b>
|
||
|
||
2. test 2
|
||
|
||
[/poll]
|
||
MD
|
||
|
||
loose_cooked = PrettyText.cook(md)
|
||
|
||
tight_hashes = tight_cooked.scan(/data-poll-option-id=['"]([^'"]+)/)
|
||
loose_hashes = loose_cooked.scan(/data-poll-option-id=['"]([^'"]+)/)
|
||
|
||
expect(tight_hashes).to eq(loose_hashes)
|
||
end
|
||
|
||
it "can correctly cook polls" do
|
||
md = <<~MD
|
||
[poll type=multiple]
|
||
1. test 1 :) <b>test</b>
|
||
2. test 2
|
||
[/poll]
|
||
MD
|
||
|
||
cooked = PrettyText.cook md
|
||
|
||
expected = <<~HTML
|
||
<div class="poll" data-poll-status="open" data-poll-type="multiple" data-poll-name="poll">
|
||
<div>
|
||
<div class="poll-container"><ol>
|
||
<li data-poll-option-id="b6475cbf6acb8676b20c60582cfc487a">test 1 <img src="/images/emoji/twitter/slight_smile.png?v=#{Emoji::EMOJI_VERSION}" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> <b>test</b></li>
|
||
<li data-poll-option-id="7158af352698eb1443d709818df097d4">test 2</li>
|
||
</ol>
|
||
</div>
|
||
<div class="poll-info">
|
||
<p>
|
||
<span class="info-number">0</span>
|
||
<span class="info-label">voters</span>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
HTML
|
||
|
||
# note, hashes should remain stable even if emoji changes cause text content is hashed
|
||
expect(n cooked).to eq(n expected)
|
||
end
|
||
|
||
it "can onebox posts" do
|
||
post = Fabricate(:post, raw: <<~MD)
|
||
A post with a poll
|
||
|
||
[poll type=regular]
|
||
* Hello
|
||
* World
|
||
[/poll]
|
||
MD
|
||
|
||
onebox = Oneboxer.onebox_raw(post.full_url, user_id: Fabricate(:user).id)
|
||
doc = Nokogiri.HTML5(onebox[:preview])
|
||
|
||
expect(onebox[:preview]).to include("A post with a poll")
|
||
expect(onebox[:preview]).to include("<a href=\"#{post.url}\">poll</a>")
|
||
end
|
||
|
||
it "can reduce excerpts" do
|
||
post = Fabricate(:post, raw: <<~MD)
|
||
A post with a poll
|
||
|
||
[poll type=regular]
|
||
* Hello
|
||
* World
|
||
[/poll]
|
||
MD
|
||
|
||
excerpt = PrettyText.excerpt(post.cooked, SiteSetting.post_onebox_maxlength, post: post)
|
||
expect(excerpt).to eq("A post with a poll \n<a href=\"#{post.url}\">poll</a>")
|
||
|
||
excerpt = PrettyText.excerpt(post.cooked, SiteSetting.post_onebox_maxlength)
|
||
expect(excerpt).to eq("A post with a poll \npoll")
|
||
end
|
||
|
||
it "supports the title attribute" do
|
||
cooked = PrettyText.cook <<~MD
|
||
[poll]
|
||
# What's your favorite *berry*? :wink: https://google.com/
|
||
* Strawberry
|
||
* Raspberry
|
||
* Blueberry
|
||
[/poll]
|
||
MD
|
||
|
||
expect(cooked).to include(
|
||
"<div class=\"poll-title\">What’s your favorite <em>berry</em>? <img src=\"/images/emoji/twitter/wink.png?v=#{Emoji::EMOJI_VERSION}\" title=\":wink:\" class=\"emoji\" alt=\":wink:\" loading=\"lazy\" width=\"20\" height=\"20\"> <a href=\"https://google.com/\" rel=\"noopener nofollow ugc\">https://google.com/</a></div>",
|
||
)
|
||
end
|
||
|
||
it "does not break when there are headings before/after a poll with a title" do
|
||
cooked = PrettyText.cook <<~MD
|
||
# Pre-heading
|
||
|
||
[poll]
|
||
# What's your favorite *berry*? :wink: https://google.com/
|
||
* Strawberry
|
||
* Raspberry
|
||
* Blueberry
|
||
[/poll]
|
||
|
||
# Post-heading
|
||
MD
|
||
|
||
expect(cooked).to include(
|
||
"<div class=\"poll-title\">What’s your favorite <em>berry</em>? <img src=\"/images/emoji/twitter/wink.png?v=#{Emoji::EMOJI_VERSION}\" title=\":wink:\" class=\"emoji\" alt=\":wink:\" loading=\"lazy\" width=\"20\" height=\"20\"> <a href=\"https://google.com/\" rel=\"noopener nofollow ugc\">https://google.com/</a></div>",
|
||
)
|
||
|
||
expect(cooked).to include(
|
||
"<h1><a name=\"pre-heading-1\" class=\"anchor\" href=\"#pre-heading-1\"></a>Pre-heading</h1>",
|
||
)
|
||
expect(cooked).to include(
|
||
"<h1><a name=\"post-heading-2\" class=\"anchor\" href=\"#post-heading-2\"></a>Post-heading</h1>",
|
||
)
|
||
end
|
||
|
||
it "does not break when there are headings before/after a poll without a title" do
|
||
cooked = PrettyText.cook <<~MD
|
||
# Pre-heading
|
||
|
||
[poll]
|
||
* Strawberry
|
||
* Raspberry
|
||
* Blueberry
|
||
[/poll]
|
||
|
||
# Post-heading
|
||
MD
|
||
|
||
expect(cooked).to_not include('<div class="poll-title">')
|
||
expect(cooked).to include(<<~HTML)
|
||
<div class="poll" data-poll-status="open" data-poll-name="poll">
|
||
HTML
|
||
|
||
expect(cooked).to include(
|
||
"<h1><a name=\"pre-heading-1\" class=\"anchor\" href=\"#pre-heading-1\"></a>Pre-heading</h1>",
|
||
)
|
||
expect(cooked).to include(
|
||
"<h1><a name=\"post-heading-2\" class=\"anchor\" href=\"#post-heading-2\"></a>Post-heading</h1>",
|
||
)
|
||
end
|
||
end
|