Refactor post presenter

This commit is contained in:
theworldbright 2015-08-13 13:01:09 +09:00 committed by Jonne Haß
parent a1ca45b201
commit 335b1c32aa
2 changed files with 101 additions and 83 deletions

View file

@ -3,83 +3,94 @@ class PostPresenter
attr_accessor :post, :current_user
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)}
collection.map {|post| PostPresenter.new(post, current_user) }
end
def as_json(options={})
text = if @post.message
def as_json(_options={})
@post.include_root_in_json = false
@post.as_json(only: directly_retrieved_attributes).merge(non_directly_retrieved_attributes)
end
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?,
end
:interactions => {
:likes => [user_like].compact,
:reshares => [user_reshare].compact,
:comments_count => @post.comments_count,
:likes_count => @post.likes_count,
:reshares_count => @post.reshares_count
}
}
def build_open_graph_cache
@post.open_graph_cache.try(:as_api_response, :backbone)
end
def build_mentioned_people_json
@post.mentioned_people.as_api_response(:backbone)
end
def build_photos_json
@post.photos.map {|p| p.as_api_response(:backbone) }
end
def title
@post.message.present? ? @post.message.title : I18n.t('posts.presenter.title', name: @post.author_name)
@post.message.present? ? @post.message.title : I18n.t("posts.presenter.title", name: @post.author_name)
end
def root
PostPresenter.new(@post.absolute_root, current_user).as_json if @post.respond_to?(:absolute_root) && @post.absolute_root.present?
if @post.respond_to?(:absolute_root) && @post.absolute_root.present?
PostPresenter.new(@post.absolute_root, current_user).as_json
end
end
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_like
@post.like_for(@current_user).try(:as_api_response, :backbone)
@post.like_for(current_user).try(:as_api_response, :backbone)
end
def user_reshare
@post.reshare_for(@current_user)
@post.reshare_for(current_user)
end
protected
def person
@current_user.person
end
def user_signed_in?
@current_user.present?
end
private
def already_participated_in_poll
if @post.poll && user_signed_in?
@post.poll.already_participated?(current_user)
@ -87,7 +98,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

View file

@ -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