FEATURE: Implement Onebox for posts including polls. (#7539)

FEATURE: Implement Onebox for posts including polls. (#7539)

diff --git a/app/models/post.rb b/app/models/post.rb
index efb75dd..09691d1 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -453,11 +453,11 @@ class Post < ActiveRecord::Base
 
   # Strip out most of the markup
   def excerpt(maxlength = nil, options = {})
-    Post.excerpt(cooked, maxlength, options)
+    Post.excerpt(cooked, maxlength, options.merge(post: self))
   end
 
   def excerpt_for_topic
-    Post.excerpt(cooked, 220, strip_links: true, strip_images: true)
+    Post.excerpt(cooked, 220, strip_links: true, strip_images: true, post: self)
   end
 
   def is_first_post?
diff --git a/app/models/user_profile.rb b/app/models/user_profile.rb
index a6453de..3e51fd9 100644
--- a/app/models/user_profile.rb
+++ b/app/models/user_profile.rb
@@ -24,6 +24,7 @@ class UserProfile < ActiveRecord::Base
   BAKED_VERSION = 1
 
   def bio_excerpt(length = 350, opts = {})
+    return nil if bio_cooked.blank?
     excerpt = PrettyText.excerpt(bio_cooked, length, opts).sub(/<br>$/, '')
     return excerpt if excerpt.blank? || (user.has_trust_level?(TrustLevel[1]) && !user.suspended?)
     PrettyText.strip_links(excerpt)
@@ -35,7 +36,6 @@ class UserProfile < ActiveRecord::Base
   end
 
   def bio_summary
-    return nil unless bio_cooked.present?
     bio_excerpt(500, strip_links: true, text_entities: true)
   end
 
diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb
index 79b6e66..123bb91 100644
--- a/lib/pretty_text.rb
+++ b/lib/pretty_text.rb
@@ -347,6 +347,7 @@ module PrettyText
   def self.excerpt(html, max_length, options = {})
     # TODO: properly fix this HACK in ExcerptParser without introducing XSS
     doc = Nokogiri::HTML.fragment(html)
+    DiscourseEvent.trigger(:reduce_excerpt, doc, options)
     strip_image_wrapping(doc)
     html = doc.to_html
 
diff --git a/plugins/poll/config/locales/server.en.yml b/plugins/poll/config/locales/server.en.yml
index 1fdcbf4..c667a9d 100644
--- a/plugins/poll/config/locales/server.en.yml
+++ b/plugins/poll/config/locales/server.en.yml
@@ -22,6 +22,7 @@ en:
     poll_minimum_trust_level_to_create: "Define the minimum trust level needed to create polls."
 
   poll:
+    poll: "poll"
     invalid_argument: "Invalid value '%{value}' for argument '%{argument}'."
 
     multiple_polls_without_name: "There are multiple polls without a name. Use the '<code>name</code>' attribute to uniquely identify your polls."
diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb
index 7b64ddf..4a494cf 100644
--- a/plugins/poll/plugin.rb
+++ b/plugins/poll/plugin.rb
@@ -435,6 +435,13 @@ after_initialize do
     end
   end
 
+  on(:reduce_excerpt) do |doc, options|
+    post = options[:post]
+    doc.css("div.poll").each do |poll|
+      poll.replace "<a href='#{UrlHelper.escape_uri(post.url)}'>#{I18n.t("poll.poll")}</a>"
+    end
+  end
+
   on(:post_created) do |post|
     DiscoursePoll::Poll.schedule_jobs(post)
 
diff --git a/plugins/poll/spec/lib/pretty_text_spec.rb b/plugins/poll/spec/lib/pretty_text_spec.rb
index a7e1f3d..a1b834a 100644
--- a/plugins/poll/spec/lib/pretty_text_spec.rb
+++ b/plugins/poll/spec/lib/pretty_text_spec.rb
@@ -119,4 +119,21 @@ describe PrettyText do
     expect(n cooked).to eq(n expected)
 
   end
+
+  it 'can onebox posts' do
+    post = Fabricate(:post, raw: <<~EOF)
+      A post with a poll
+
+      [poll type=regular]
+      * Hello
+      * World
+      [/poll]
+    EOF
+
+    onebox = Oneboxer.onebox_raw(post.full_url, user_id: Fabricate(:user).id)
+    doc = Nokogiri::HTML(onebox[:preview])
+
+    expect(onebox[:preview]).to include("A post with a poll")
+    expect(onebox[:preview]).to include("<a href=\"#{post.url}\">poll</a>")
+  end
 end

GitHub sha: 227c4510

This commit has been mentioned on Discourse Meta. There might be relevant details there: