From 44b616eda8c57ebb8c2071fe76a2b0b1763c01c7 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem <svbergerem@omgsrsly.net> Date: Sat, 18 Feb 2017 01:04:08 +0100 Subject: [PATCH] Add reshare service --- app/services/reshare_service.rb | 24 +++++++ spec/services/reshare_service.rb | 107 +++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 app/services/reshare_service.rb create mode 100644 spec/services/reshare_service.rb diff --git a/app/services/reshare_service.rb b/app/services/reshare_service.rb new file mode 100644 index 0000000000..01d725647c --- /dev/null +++ b/app/services/reshare_service.rb @@ -0,0 +1,24 @@ +class ReshareService + def initialize(user=nil) + @user = user + end + + def create(post_id) + post = post_service.find!(post_id) + post = post.absolute_root if post.is_a? Reshare + user.reshare!(post) + end + + def find_for_post(post_id) + reshares = post_service.find!(post_id).reshares + user ? reshares.order("author_id = #{user.person.id} DESC") : reshares + end + + private + + attr_reader :user + + def post_service + @post_service ||= PostService.new(user) + end +end diff --git a/spec/services/reshare_service.rb b/spec/services/reshare_service.rb new file mode 100644 index 0000000000..4541b64e2a --- /dev/null +++ b/spec/services/reshare_service.rb @@ -0,0 +1,107 @@ +describe ReshareService do + let(:post) { alice.post(:status_message, text: "hello", public: true) } + + describe "#create" do + it "doesn't create a reshare of my own post" do + expect { + ReshareService.new(alice).create(post.id) + }.not_to raise_error + end + + it "creates a reshare of a post of a contact" do + expect { + ReshareService.new(bob).create(post.id) + }.not_to raise_error + end + + it "attaches the reshare to the post" do + reshare = ReshareService.new(bob).create(post.id) + expect(post.reshares.first.id).to eq(reshare.id) + end + + it "reshares the original post when called with a reshare" do + reshare = ReshareService.new(bob).create(post.id) + reshare2 = ReshareService.new(eve).create(reshare.id) + expect(post.reshares.map(&:id)).to include(reshare2.id) + end + + it "fails if the post does not exist" do + expect { + ReshareService.new(bob).create("unknown id") + }.to raise_error ActiveRecord::RecordNotFound + end + + it "fails if the post is not public" do + post = alice.post(:status_message, text: "hello", to: alice.aspects.first) + + expect { + ReshareService.new(bob).create(post.id) + }.to raise_error ActiveRecord::RecordInvalid + end + + it "fails if the user already reshared the post" do + ReshareService.new(bob).create(post.id) + expect { + ReshareService.new(bob).create(post.id) + }.to raise_error ActiveRecord::RecordInvalid + end + + it "fails if the user already reshared the original post" do + reshare = ReshareService.new(bob).create(post.id) + expect { + ReshareService.new(bob).create(reshare.id) + }.to raise_error ActiveRecord::RecordInvalid + end + end + + describe "#find_for_post" do + context "with user" do + it "returns reshares for a public post" do + reshare = ReshareService.new(bob).create(post.id) + expect(ReshareService.new(eve).find_for_post(post.id)).to include(reshare) + end + + it "returns reshares for a visible private post" do + post = alice.post(:status_message, text: "hello", to: alice.aspects.first) + expect(ReshareService.new(bob).find_for_post(post.id)).to be_empty + end + + it "doesn't return reshares for a private post the user can not see" do + post = alice.post(:status_message, text: "hello", to: alice.aspects.first) + expect { + ReshareService.new(eve).find_for_post(post.id) + }.to raise_error ActiveRecord::RecordNotFound + end + + it "returns the user's reshare first" do + [alice, bob, eve].map {|user| ReshareService.new(user).create(post.id) } + + [alice, bob, eve].each do |user| + expect( + ReshareService.new(user).find_for_post(post.id).first.author.id + ).to be user.person.id + end + end + end + + context "without user" do + it "returns reshares for a public post" do + reshare = ReshareService.new(alice).create(post.id) + expect(ReshareService.new.find_for_post(post.id)).to include(reshare) + end + + it "doesn't return reshares a for private post" do + post = alice.post(:status_message, text: "hello", to: alice.aspects.first) + expect { + ReshareService.new.find_for_post(post.id) + }.to raise_error Diaspora::NonPublic + end + end + + it "returns all reshares of a post" do + reshares = [alice, bob, eve].map {|user| ReshareService.new(user).create(post.id) } + + expect(ReshareService.new.find_for_post(post.id)).to match_array(reshares) + end + end +end -- GitLab