2019-05-03 06:17:27 +08:00
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
2022-07-28 10:27:38 +08:00
|
|
|
|
RSpec.describe PrettyText do
|
2017-06-09 06:02:30 +08:00
|
|
|
|
|
|
|
|
|
def n(html)
|
2018-02-15 11:35:20 +08:00
|
|
|
|
html.strip
|
2017-06-09 06:02:30 +08:00
|
|
|
|
end
|
|
|
|
|
|
2017-07-26 01:38:04 +08:00
|
|
|
|
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
|
|
|
|
|
|
2020-10-02 15:21:24 +08:00
|
|
|
|
expected = <<~HTML
|
2018-02-15 11:35:20 +08:00
|
|
|
|
<div class="poll" data-poll-status="open" data-poll-type="multiple" data-poll-name="poll">
|
2017-07-26 01:38:04 +08:00
|
|
|
|
<div>
|
|
|
|
|
<div class="poll-container">
|
|
|
|
|
<ol>
|
2022-02-09 19:18:59 +08:00
|
|
|
|
<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>
|
2017-07-26 01:38:04 +08:00
|
|
|
|
</li>
|
2018-02-15 11:35:20 +08:00
|
|
|
|
<li data-poll-option-id="7158af352698eb1443d709818df097d4">test 2</li>
|
2017-07-26 01:38:04 +08:00
|
|
|
|
</ol>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="poll-info">
|
|
|
|
|
<p>
|
|
|
|
|
<span class="info-number">0</span>
|
2018-05-03 16:32:01 +08:00
|
|
|
|
<span class="info-label">voters</span>
|
2017-07-26 01:38:04 +08:00
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2020-10-02 15:21:24 +08:00
|
|
|
|
HTML
|
2017-07-26 01:38:04 +08:00
|
|
|
|
|
|
|
|
|
# note, hashes should remain stable even if emoji changes cause text content is hashed
|
|
|
|
|
expect(n cooked).to eq(n expected)
|
|
|
|
|
|
2017-06-09 06:02:30 +08:00
|
|
|
|
end
|
2019-05-29 23:05:52 +08:00
|
|
|
|
|
|
|
|
|
it 'can onebox posts' do
|
2019-06-04 16:31:18 +08:00
|
|
|
|
post = Fabricate(:post, raw: <<~MD)
|
2019-05-29 23:05:52 +08:00
|
|
|
|
A post with a poll
|
|
|
|
|
|
|
|
|
|
[poll type=regular]
|
|
|
|
|
* Hello
|
|
|
|
|
* World
|
|
|
|
|
[/poll]
|
2019-06-04 16:31:18 +08:00
|
|
|
|
MD
|
2019-05-29 23:05:52 +08:00
|
|
|
|
|
|
|
|
|
onebox = Oneboxer.onebox_raw(post.full_url, user_id: Fabricate(:user).id)
|
2020-05-05 11:46:57 +08:00
|
|
|
|
doc = Nokogiri::HTML5(onebox[:preview])
|
2019-05-29 23:05:52 +08:00
|
|
|
|
|
|
|
|
|
expect(onebox[:preview]).to include("A post with a poll")
|
|
|
|
|
expect(onebox[:preview]).to include("<a href=\"#{post.url}\">poll</a>")
|
|
|
|
|
end
|
2019-06-04 00:58:26 +08:00
|
|
|
|
|
|
|
|
|
it 'can reduce excerpts' do
|
2019-06-04 16:31:18 +08:00
|
|
|
|
post = Fabricate(:post, raw: <<~MD)
|
2019-06-04 00:58:26 +08:00
|
|
|
|
A post with a poll
|
|
|
|
|
|
|
|
|
|
[poll type=regular]
|
|
|
|
|
* Hello
|
|
|
|
|
* World
|
|
|
|
|
[/poll]
|
2019-06-04 16:31:18 +08:00
|
|
|
|
MD
|
2019-06-04 00:58:26 +08:00
|
|
|
|
|
|
|
|
|
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
|
2020-10-02 15:21:24 +08:00
|
|
|
|
|
|
|
|
|
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(<<~HTML)
|
2022-02-09 19:18:59 +08:00
|
|
|
|
<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>
|
2020-10-02 15:21:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
HTML
|
|
|
|
|
end
|
2020-10-06 19:24:38 +08:00
|
|
|
|
|
|
|
|
|
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(<<~HTML)
|
2022-02-09 19:18:59 +08:00
|
|
|
|
<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>
|
2020-10-06 19:24:38 +08:00
|
|
|
|
</div>
|
|
|
|
|
HTML
|
|
|
|
|
|
2021-04-16 15:54:19 +08:00
|
|
|
|
expect(cooked).to include("<h1>\n<a name=\"pre-heading-1\" class=\"anchor\" href=\"#pre-heading-1\"></a>Pre-heading</h1>")
|
|
|
|
|
expect(cooked).to include("<h1>\n<a name=\"post-heading-2\" class=\"anchor\" href=\"#post-heading-2\"></a>Post-heading</h1>")
|
2020-10-06 19:24:38 +08:00
|
|
|
|
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
|
|
|
|
|
|
2021-04-16 15:54:19 +08:00
|
|
|
|
expect(cooked).to include("<h1>\n<a name=\"pre-heading-1\" class=\"anchor\" href=\"#pre-heading-1\"></a>Pre-heading</h1>")
|
|
|
|
|
expect(cooked).to include("<h1>\n<a name=\"post-heading-2\" class=\"anchor\" href=\"#post-heading-2\"></a>Post-heading</h1>")
|
2020-10-06 19:24:38 +08:00
|
|
|
|
end
|
2017-06-09 06:02:30 +08:00
|
|
|
|
end
|