From ac52cef546929ed10640e148dbbb009fbe247b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 29 May 2015 13:10:30 +0200 Subject: [PATCH] Only return the current_users participation for post interactions closes #6007 --- Changelog.md | 1 + app/models/post.rb | 3 +- app/presenters/post_interaction_presenter.rb | 30 +++++++++ app/presenters/post_presenter.rb | 25 -------- spec/factories.rb | 62 ++++++++++++------- .../post_ineraction_presenter_spec.rb | 36 +++++++++++ 6 files changed, 109 insertions(+), 48 deletions(-) create mode 100644 app/presenters/post_interaction_presenter.rb create mode 100644 spec/presenters/post_ineraction_presenter_spec.rb diff --git a/Changelog.md b/Changelog.md index 5ae16c5c8..1a9f3c307 100644 --- a/Changelog.md +++ b/Changelog.md @@ -45,6 +45,7 @@ * Fix a freeze in new post parsing [#5965](https://github.com/diaspora/diaspora/pull/5965) * Add case insensitive unconfirmed email addresses as authentication key [#5967](https://github.com/diaspora/diaspora/pull/5967) * Fix liking on single post views when accessed via GUID [#5978](https://github.com/diaspora/diaspora/pull/5978) +* Only return the current_users participation for post interactions [#6007](https://github.com/diaspora/diaspora/pull/6007) ## Features * Hide post title of limited post in comment notification email [#5843](https://github.com/diaspora/diaspora/pull/5843) diff --git a/app/models/post.rb b/app/models/post.rb index ea317f5b1..79d06078c 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -11,8 +11,7 @@ class Post < ActiveRecord::Base include Diaspora::Commentable include Diaspora::Shareable - - has_many :participations, :dependent => :delete_all, :as => :target + has_many :participations, dependent: :delete_all, as: :target, inverse_of: :target attr_accessor :user_like diff --git a/app/presenters/post_interaction_presenter.rb b/app/presenters/post_interaction_presenter.rb new file mode 100644 index 000000000..c67b7528a --- /dev/null +++ b/app/presenters/post_interaction_presenter.rb @@ -0,0 +1,30 @@ +class PostInteractionPresenter + def initialize(post, current_user) + @post = post + @current_user = current_user + end + + def as_json(_options={}) + { + likes: as_api(@post.likes), + reshares: PostPresenter.collection_json(@post.reshares, @current_user), + comments: CommentPresenter.as_collection(@post.comments.order("created_at ASC")), + participations: as_api(participations), + comments_count: @post.comments_count, + likes_count: @post.likes_count, + reshares_count: @post.reshares_count + } + end + + def participations + return @post.participations.none unless @current_user + @post.participations.where(author: @current_user.person) + end + + def as_api(collection) + collection.includes(author: :profile).map {|element| + element.as_api_response(:backbone) + } + end +end + diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb index 90e074a6f..5a763dcee 100644 --- a/app/presenters/post_presenter.rb +++ b/app/presenters/post_presenter.rb @@ -92,28 +92,3 @@ class PostPresenter end end - -class PostInteractionPresenter - def initialize(post, current_user) - @post = post - @current_user = current_user - end - - def as_json(options={}) - { - likes: as_api(@post.likes), - reshares: PostPresenter.collection_json(@post.reshares, @current_user), - comments: CommentPresenter.as_collection(@post.comments.order("created_at ASC")), - participations: as_api(@post.participations), - comments_count: @post.comments_count, - likes_count: @post.likes_count, - reshares_count: @post.reshares_count - } - end - - def as_api(collection) - collection.includes(:author => :profile).map do |element| - element.as_api_response(:backbone) - end - end -end diff --git a/spec/factories.rb b/spec/factories.rb index c7d5b18c0..42c39caca 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -26,12 +26,14 @@ FactoryGirl.define do image_url_small "http://example.com/image_small.jpg" end - factory :person do - sequence(:diaspora_handle) { |n| "bob-person-#{n}#{r_str}@example.net" } + factory(:person, aliases: %i(author)) do + sequence(:diaspora_handle) {|n| "bob-person-#{n}#{r_str}@example.net" } url AppConfig.pod_uri.to_s serialized_public_key OpenSSL::PKey::RSA.generate(1024).public_key.export after(:build) do |person| - person.profile = FactoryGirl.build(:profile, :person => person) unless person.profile.first_name.present? + unless person.profile.first_name.present? + person.profile = FactoryGirl.build(:profile, person: person) + end end after(:create) do |person| person.profile.save @@ -84,32 +86,50 @@ FactoryGirl.define do user end - factory(:status_message) do - sequence(:text) { |n| "jimmy's #{n} whales" } - association :author, :factory => :person + factory(:status_message, aliases: %i(status_message_without_participation)) do + sequence(:text) {|n| "jimmy's #{n} whales" } + author after(:build) do |sm| sm.diaspora_handle = sm.author.diaspora_handle end - end - factory(:status_message_with_poll, :parent => :status_message) do - after(:build) do |sm| - FactoryGirl.create(:poll, :status_message => sm) + factory(:status_message_with_poll) do + after(:build) do |sm| + FactoryGirl.create(:poll, status_message: sm) + end end - end - factory(:status_message_with_photo, :parent => :status_message) do - sequence(:text) { |n| "There are #{n} ninjas in this photo." } - after(:build) do |sm| - FactoryGirl.create(:photo, :author => sm.author, :status_message => sm, :pending => false, :public => sm.public) + factory(:status_message_with_photo) do + sequence(:text) {|n| "There are #{n} ninjas in this photo." } + after(:build) do |sm| + FactoryGirl.create( + :photo, + author: sm.author, + status_message: sm, + pending: false, + public: sm.public + ) + end end - end - factory(:status_message_in_aspect, parent: :status_message) do - self.public false - after :build do |sm| - sm.author = FactoryGirl.create(:user_with_aspect).person - sm.aspects << sm.author.owner.aspects.first + factory(:status_message_in_aspect) do + public false + after(:build) do |sm| + sm.author = FactoryGirl.create(:user_with_aspect).person + sm.aspects << sm.author.owner.aspects.first + end + end + + factory(:status_message_with_participations) do + transient do + participants [] + end + after(:build) do |sm, ev| + ev.participants.each do |participant| + person = participant.is_a?(User) ? participant.person : participant + sm.participations.build(author: person) + end + end end end diff --git a/spec/presenters/post_ineraction_presenter_spec.rb b/spec/presenters/post_ineraction_presenter_spec.rb new file mode 100644 index 000000000..0018bce10 --- /dev/null +++ b/spec/presenters/post_ineraction_presenter_spec.rb @@ -0,0 +1,36 @@ +require "spec_helper" + +describe PostInteractionPresenter do + let(:status_message_without_participation) { + FactoryGirl.create(:status_message_without_participation) + } + let(:status_message_with_participations) { + FactoryGirl.create(:status_message_with_participations, participants: [alice, bob]) + } + + context "with an user" do + context "without a participation" do + let(:presenter) { PostInteractionPresenter.new(status_message_without_participation, alice) } + + it "returns an empty array for participations" do + expect(presenter.as_json[:participations]).to be_empty + end + end + + context "with a participation" do + let(:presenter) { PostInteractionPresenter.new(status_message_with_participations, alice) } + + it "returns the users own participation only" do + expect(presenter.as_json[:participations]).to eq [alice.participations.first.as_api_response(:backbone)] + end + end + end + + context "without an user" do + let(:presenter) { PostInteractionPresenter.new(status_message_with_participations, nil) } + + it "returns an empty array" do + expect(presenter.as_json[:participations]).to be_empty + end + end +end