diff --git a/Changelog.md b/Changelog.md index 15eef00615918fd7f84e5450c6a3992fab4d5e6a..bfe7235c20d52f98fe057e2bd665f263cff55e25 100644 --- a/Changelog.md +++ b/Changelog.md @@ -76,6 +76,7 @@ With the port to Bootstrap 3, app/views/terms/default.haml has a new structure. * Refactor HomeController#toggle\_mobile [#6260](https://github.com/diaspora/diaspora/pull/6260) * Extract CommentService from CommentsController [#6307](https://github.com/diaspora/diaspora/pull/6307) * Extract user/profile discovery into the diaspora\_federation-rails gem [#6310](https://github.com/diaspora/diaspora/pull/6310) +* Refactor PostPresenter [#6315](https://github.com/diaspora/diaspora/pull/6315) ## Bug fixes * Fix indentation and a link title on the default home page [#6212](https://github.com/diaspora/diaspora/pull/6212) diff --git a/app/presenters/post_interaction_presenter.rb b/app/presenters/post_interaction_presenter.rb index 2616b0f76e77ff1fc3c71c2133891a104fadd962..12c999febb57bd0da85d16e30fe51625bc66d350 100644 --- a/app/presenters/post_interaction_presenter.rb +++ b/app/presenters/post_interaction_presenter.rb @@ -7,7 +7,7 @@ class PostInteractionPresenter def as_json(_options={}) { likes: as_api(@post.likes), - reshares: PostPresenter.collection_json(@post.reshares, @current_user), + reshares: PostPresenter.as_collection(@post.reshares, :as_json, @current_user), comments: CommentPresenter.as_collection(@post.comments.order("created_at ASC")), participations: as_api(participations), comments_count: @post.comments_count, diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb index f17e6bb8c33a3e1fd74a94c419c3eb28de01559f..b1df1a917aaec83c3effcee867f6ea6a960cfcc7 100644 --- a/app/presenters/post_presenter.rb +++ b/app/presenters/post_presenter.rb @@ -1,84 +1,91 @@ -class PostPresenter +class PostPresenter < BasePresenter include PostsHelper - attr_accessor :post, :current_user + attr_accessor :post - def initialize(post, current_user = nil) + def initialize(post, current_user=nil) @post = post @current_user = current_user end - def self.collection_json(collection, current_user) - collection.map {|post| PostPresenter.new(post, current_user)} + def as_json(_options={}) + @post.include_root_in_json = false + @post.as_json(only: directly_retrieved_attributes).merge(non_directly_retrieved_attributes) end - def as_json(options={}) - text = if @post.message + private + + def directly_retrieved_attributes + %i(id guid public created_at interacted_at provider_display_name image_url object_url) + end + + def non_directly_retrieved_attributes + { + text: build_text, + post_type: @post.post_type, + nsfw: @post.nsfw, + author: @post.author.as_api_response(:backbone), + o_embed_cache: @post.o_embed_cache.try(:as_api_response, :backbone), + open_graph_cache: build_open_graph_cache, + mentioned_people: build_mentioned_people_json, + photos: build_photos_json, + root: root, + title: title, + address: @post.address, + poll: @post.poll, + already_participated_in_poll: already_participated_in_poll, + participation: participate?, + interactions: build_interactions_json + } + end + + def build_text + if @post.message @post.message.plain_text_for_json else @post.raw_message end - { - :id => @post.id, - :guid => @post.guid, - :text => text, - :public => @post.public, - :created_at => @post.created_at, - :interacted_at => @post.interacted_at, - :provider_display_name => @post.provider_display_name, - :post_type => @post.post_type, - :image_url => @post.image_url, - :object_url => @post.object_url, - :nsfw => @post.nsfw, - :author => @post.author.as_api_response(:backbone), - :o_embed_cache => @post.o_embed_cache.try(:as_api_response, :backbone), - :open_graph_cache => @post.open_graph_cache.try(:as_api_response, :backbone), - :mentioned_people => @post.mentioned_people.as_api_response(:backbone), - :photos => @post.photos.map {|p| p.as_api_response(:backbone)}, - :root => root, - :title => title, - :address => @post.address, - :poll => @post.poll(), - :already_participated_in_poll => already_participated_in_poll, - :participation => participate?, - - :interactions => { - :likes => [user_like].compact, - :reshares => [user_reshare].compact, - :comments_count => @post.comments_count, - :likes_count => @post.likes_count, - :reshares_count => @post.reshares_count - } - } end - def title - @post.message.present? ? @post.message.title : I18n.t('posts.presenter.title', name: @post.author_name) + def build_open_graph_cache + @post.open_graph_cache.try(:as_api_response, :backbone) end - def root - PostPresenter.new(@post.absolute_root, current_user).as_json if @post.respond_to?(:absolute_root) && @post.absolute_root.present? + def build_mentioned_people_json + @post.mentioned_people.as_api_response(:backbone) end - def user_like - @post.like_for(@current_user).try(:as_api_response, :backbone) + def build_photos_json + @post.photos.map {|p| p.as_api_response(:backbone) } end - def user_reshare - @post.reshare_for(@current_user) + def title + @post.message.present? ? @post.message.title : I18n.t("posts.presenter.title", name: @post.author_name) end - protected + def root + if @post.respond_to?(:absolute_root) && @post.absolute_root.present? + PostPresenter.new(@post.absolute_root, current_user).as_json + end + end - def person - @current_user.person + def build_interactions_json + { + likes: [user_like].compact, + reshares: [user_reshare].compact, + comments_count: @post.comments_count, + likes_count: @post.likes_count, + reshares_count: @post.reshares_count + } end - def user_signed_in? - @current_user.present? + def user_like + @post.like_for(current_user).try(:as_api_response, :backbone) end - private + def user_reshare + @post.reshare_for(current_user) + end def already_participated_in_poll if @post.poll && user_signed_in? @@ -87,7 +94,14 @@ class PostPresenter end def participate? - user_signed_in? && @current_user.participations.where(:target_id => @post).exists? + user_signed_in? && current_user.participations.where(target_id: @post).exists? end + def user_signed_in? + current_user.present? + end + + def person + current_user.person + end end diff --git a/spec/presenters/post_presenter_spec.rb b/spec/presenters/post_presenter_spec.rb index 293f0337c545bb250c75f9a1aa3d61b4ed297065..07a4b2d8411407fda7cac100c946f9b968954e56 100644 --- a/spec/presenters/post_presenter_spec.rb +++ b/spec/presenters/post_presenter_spec.rb @@ -1,90 +1,90 @@ -require 'spec_helper' +require "spec_helper" describe PostPresenter do before do - @sm = FactoryGirl.create(:status_message, :public => true) + @sm = FactoryGirl.create(:status_message, public: true) @sm_with_poll = FactoryGirl.create(:status_message_with_poll, public: true) @presenter = PostPresenter.new(@sm, bob) @unauthenticated_presenter = PostPresenter.new(@sm) end - it 'takes a post and an optional user' do + it "takes a post and an optional user" do expect(@presenter).not_to be_nil end - describe '#as_json' do - it 'works with a user' do + describe "#as_json" do + it "works with a user" do expect(@presenter.as_json).to be_a Hash end - it 'works without a user' do + it "works without a user" do expect(@unauthenticated_presenter.as_json).to be_a Hash end end - describe '#user_like' do - it 'includes the users like' do + describe "#user_like" do + it "includes the users like" do bob.like!(@sm) - expect(@presenter.user_like).to be_present + expect(@presenter.send(:user_like)).to be_present end - it 'is nil if the user is not authenticated' do - expect(@unauthenticated_presenter.user_like).to be_nil + it "is nil if the user is not authenticated" do + expect(@unauthenticated_presenter.send(:user_like)).to be_nil end end - describe '#user_reshare' do - it 'includes the users reshare' do + describe "#user_reshare" do + it "includes the users reshare" do bob.reshare!(@sm) - expect(@presenter.user_reshare).to be_present + expect(@presenter.send(:user_reshare)).to be_present end - it 'is nil if the user is not authenticated' do - expect(@unauthenticated_presenter.user_reshare).to be_nil + it "is nil if the user is not authenticated" do + expect(@unauthenticated_presenter.send(:user_reshare)).to be_nil end end - describe '#root' do - it 'does not raise if the absolute_root does not exists' do + describe "#root" do + it "does not raise if the absolute_root does not exists" do first_reshare = FactoryGirl.create :reshare first_reshare.root = nil - reshare = FactoryGirl.create :reshare, :root => first_reshare + reshare = FactoryGirl.create :reshare, root: first_reshare expect { - PostPresenter.new(reshare).root + PostPresenter.new(reshare).send(:root) }.to_not raise_error end - it 'does not raise if the root does not exists' do - reshare = FactoryGirl.create:reshare + it "does not raise if the root does not exists" do + reshare = FactoryGirl.create :reshare reshare.root = nil expect { - PostPresenter.new(reshare).root + PostPresenter.new(reshare).send(:root) }.to_not raise_error end end - describe '#title' do - context 'with posts with text' do + describe "#title" do + context "with posts with text" do it "delegates to message.title" do message = double(present?: true) expect(message).to receive(:title) @presenter.post = double(message: message) - @presenter.title + @presenter.send(:title) end end - context 'with posts without text' do - it ' displays a messaage with the post class' do + context "with posts without text" do + it " displays a messaage with the post class" do @sm = double(message: double(present?: false), author: bob.person, author_name: bob.person.name) @presenter.post = @sm - expect(@presenter.title).to eq("A post from #{@sm.author.name}") + expect(@presenter.send(:title)).to eq("A post from #{@sm.author.name}") end end end - describe '#poll' do - it 'works without a user' do + describe "#poll" do + it "works without a user" do presenter = PostPresenter.new(@sm_with_poll) expect(presenter.as_json).to be_a(Hash) end