From 4205c1ad2bcbd2572fb4b7eb37c641a4c4db5cec Mon Sep 17 00:00:00 2001 From: Gerhard Schlager Date: Tue, 17 Oct 2017 20:37:51 +0200 Subject: [PATCH] FIX: postprocessing ignored cook method --- app/models/post.rb | 34 +++++++++++++------------------ app/models/post_analyzer.rb | 14 ++++++++++--- lib/cooked_post_processor.rb | 1 + spec/models/post_analyzer_spec.rb | 27 ++++++++++++++++++++---- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/app/models/post.rb b/app/models/post.rb index 4a0f7df3916..1ae23deac5e 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -5,7 +5,6 @@ require_dependency 'enum' require_dependency 'post_analyzer' require_dependency 'validators/post_validator' require_dependency 'plugin/filter' -require_dependency 'email_cook' require 'archetype' require 'digest/sha1' @@ -231,37 +230,32 @@ class Post < ActiveRecord::Base !add_nofollow? end - def cook(*args) + def cook(raw, opts = {}) # For some posts, for example those imported via RSS, we support raw HTML. In that # case we can skip the rendering pipeline. return raw if cook_method == Post.cook_methods[:raw_html] - cooked = - if cook_method == Post.cook_methods[:email] - EmailCook.new(raw).cook - else - cloned = args.dup - cloned[1] ||= {} + options = opts.dup + options[:cook_method] = cook_method - post_user = self.user - cloned[1][:user_id] = post_user.id if post_user + post_user = self.user + options[:user_id] = post_user.id if post_user - if add_nofollow? - post_analyzer.cook(*args) - else - # At trust level 3, we don't apply nofollow to links - cloned[1][:omit_nofollow] = true - post_analyzer.cook(*cloned) - end - end + if add_nofollow? + cooked = post_analyzer.cook(raw, options) + else + # At trust level 3, we don't apply nofollow to links + options[:omit_nofollow] = true + cooked = post_analyzer.cook(raw, options) + end new_cooked = Plugin::Filter.apply(:after_post_cook, self, cooked) if post_type == Post.types[:regular] if new_cooked != cooked && new_cooked.blank? - Rails.logger.debug("Plugin is blanking out post: #{self.url}\nraw: #{self.raw}") + Rails.logger.debug("Plugin is blanking out post: #{self.url}\nraw: #{raw}") elsif new_cooked.blank? - Rails.logger.debug("Blank post detected post: #{self.url}\nraw: #{self.raw}") + Rails.logger.debug("Blank post detected post: #{self.url}\nraw: #{raw}") end end diff --git a/app/models/post_analyzer.rb b/app/models/post_analyzer.rb index 84f018bfa8e..2d12b99e776 100644 --- a/app/models/post_analyzer.rb +++ b/app/models/post_analyzer.rb @@ -1,4 +1,5 @@ require_dependency 'oneboxer' +require_dependency 'email_cook' class PostAnalyzer @@ -13,12 +14,19 @@ class PostAnalyzer end # What we use to cook posts - def cook(*args) - cooked = PrettyText.cook(*args) + def cook(raw, opts = {}) + cook_method = opts[:cook_method] + return raw if cook_method == Post.cook_methods[:raw_html] + + if cook_method == Post.cook_methods[:email] + cooked = EmailCook.new(raw).cook + else + cooked = PrettyText.cook(raw, opts) + end result = Oneboxer.apply(cooked, topic_id: @topic_id) do |url, _| @found_oneboxes = true - Oneboxer.invalidate(url) if args.last[:invalidate_oneboxes] + Oneboxer.invalidate(url) if opts[:invalidate_oneboxes] Oneboxer.cached_onebox(url) end diff --git a/lib/cooked_post_processor.rb b/lib/cooked_post_processor.rb index 5a961eefb83..86948b10093 100644 --- a/lib/cooked_post_processor.rb +++ b/lib/cooked_post_processor.rb @@ -20,6 +20,7 @@ class CookedPostProcessor @cooking_options[:topic_id] = post.topic_id @cooking_options = @cooking_options.symbolize_keys @cooking_options[:omit_nofollow] = true if post.omit_nofollow? + @cooking_options[:cook_method] = post.cook_method analyzer = post.post_analyzer @doc = Nokogiri::HTML::fragment(analyzer.cook(post.raw, @cooking_options)) diff --git a/spec/models/post_analyzer_spec.rb b/spec/models/post_analyzer_spec.rb index c82341e881d..2ae66cef1c0 100644 --- a/spec/models/post_analyzer_spec.rb +++ b/spec/models/post_analyzer_spec.rb @@ -10,19 +10,18 @@ describe PostAnalyzer do let(:raw) { "Here's a tweet:\n#{url}" } let(:options) { {} } - let(:args) { [raw, options] } before { Oneboxer.stubs(:onebox) } it 'fetches the cached onebox for any urls in the post' do Oneboxer.expects(:cached_onebox).with url - post_analyzer.cook(*args) + post_analyzer.cook(raw, options) expect(post_analyzer.found_oneboxes?).to be(true) end it 'does not invalidate the onebox cache' do Oneboxer.expects(:invalidate).with(url).never - post_analyzer.cook(*args) + post_analyzer.cook(raw, options) end context 'when invalidating oneboxes' do @@ -30,9 +29,29 @@ describe PostAnalyzer do it 'invalidates the oneboxes for urls in the post' do Oneboxer.expects(:invalidate).with url - post_analyzer.cook(*args) + post_analyzer.cook(raw, options) end end + + it "does nothing when the cook_method is 'raw_html'" do + cooked = post_analyzer.cook('Hello
world', cook_method: Post.cook_methods[:raw_html]) + expect(cooked).to eq('Hello
world') + end + + it "does not interpret Markdown when cook_method is 'email'" do + cooked = post_analyzer.cook('*this is not italic* and here is a link: https://www.example.com', cook_method: Post.cook_methods[:email]) + expect(cooked).to eq('*this is not italic* and here is a link: https://www.example.com') + end + + it "does interpret Markdown when cook_method is 'regular'" do + cooked = post_analyzer.cook('*this is italic*', cook_method: Post.cook_methods[:regular]) + expect(cooked).to eq('

this is italic

') + end + + it "does interpret Markdown when not cook_method is set" do + cooked = post_analyzer.cook('*this is italic*') + expect(cooked).to eq('

this is italic

') + end end context "links" do