diff --git a/spec/lib/diaspora/federated/retraction_spec.rb b/spec/lib/diaspora/federated/retraction_spec.rb index 25e6b85bd..0ebd48501 100644 --- a/spec/lib/diaspora/federated/retraction_spec.rb +++ b/spec/lib/diaspora/federated/retraction_spec.rb @@ -2,60 +2,100 @@ # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. -require 'spec_helper' +require "spec_helper" describe Retraction do - before do - skip # TODO - @aspect = alice.aspects.first - alice.contacts.create(:person => eve.person, :aspects => [@aspect]) - @post = alice.post(:status_message, :public => true, :text => "Destroy!", :to => @aspect.id) - end + let(:post) { alice.post(:status_message, text: "destroy!", public: true) } + let(:retraction) { Retraction.for(post, alice) } - describe 'serialization' do - it 'should have a post id after serialization' do - retraction = described_class.for(@post) - xml = retraction.to_xml.to_s - expect(xml.include?(@post.guid.to_s)).to eq(true) + describe "#subscribers" do + it "contains all remote-subscribers of target object" do + post = local_luke.post(:status_message, text: "destroy!", public: true) + + retraction = Retraction.for(post, local_luke) + + expect(retraction.subscribers).to eq([remote_raphael]) end end - describe '#subscribers' do - context 'posts' do - before do - @retraction = described_class.for(@post) - @obj = @retraction.instance_variable_get(:@object) - @wanted_subscribers = @obj.subscribers - end + describe "#data" do + it "contains the hash with all data from the federation-retraction" do + federation_retraction = Diaspora::Federation::Entities.signed_retraction(post, alice) - it 'returns the subscribers to the post for all objects other than person' do - expect(@retraction.subscribers.map(&:id)).to match_array(@wanted_subscribers.map(&:id)) - end + expect(retraction.data).to eq(federation_retraction.to_h) + end + end - it 'does not return the authors of reshares' do - @post.reshares << FactoryGirl.build(:reshare, :root => @post, :author => bob.person) - @post.save! + describe ".for" do + it "creates a retraction for a post" do + expect(Diaspora::Federation::Entities).to receive(:signed_retraction).with(post, alice) - @wanted_subscribers -= [bob.person] - expect(@retraction.subscribers.map(&:id)).to match_array(@wanted_subscribers.map(&:id)) - end + Retraction.for(post, alice) end - context 'setting subscribers' do - it 'barfs if the type is a person, and subscribers instance varabile is not set' do - retraction = described_class.for(alice) - obj = retraction.instance_variable_get(:@object) + it "creates a retraction for a relayable" do + comment = FactoryGirl.create(:comment, author: alice.person, post: post) - expect { - retraction.subscribers - }.to raise_error RuntimeError, "HAX: you must set the subscribers manaully before unfriending" # TODO - end + expect(Diaspora::Federation::Entities).to receive(:relayable_retraction).with(comment, alice) - it "returns manually set subscribers" do - retraction = described_class.for(alice) - retraction.subscribers = "fooey" - expect(retraction.subscribers).to eq("fooey") - end + Retraction.for(comment, alice) + end + + it "creates a retraction for a contact" do + contact = FactoryGirl.create(:contact) + + expect(Diaspora::Federation::Entities).to receive(:retraction).with(contact) + + Retraction.for(contact, contact.user) + end + end + + describe ".defer_dispatch" do + it "queues a job to send the retraction later" do + post = local_luke.post(:status_message, text: "destroy!", public: true) + federation_retraction = Diaspora::Federation::Entities.signed_retraction(post, alice) + + expect(Workers::DeferredRetraction) + .to receive(:perform_async).with(alice.id, federation_retraction.to_h, [remote_raphael.id]) + + Retraction.for(post, alice).defer_dispatch(alice) + end + + it "does not queue a job if subscribers is empty" do + federation_retraction = Diaspora::Federation::Entities.signed_retraction(post, alice) + + expect(Workers::DeferredRetraction).not_to receive(:perform_async).with(alice.id, federation_retraction.to_h, []) + + Retraction.for(post, alice).defer_dispatch(alice) + end + end + + describe "#perform" do + it "destroys the target object" do + expect(post).to receive(:destroy!) + Retraction.for(post, alice).perform + end + end + + describe "#public?" do + it "returns true for a public target" do + expect(Retraction.for(post, alice).public?).to be_truthy + end + + it "returns false for a private target" do + private_post = alice.post(:status_message, text: "destroy!", to: alice.aspects.first.id) + expect(Retraction.for(private_post, alice).public?).to be_falsey + end + end + + describe "#target_type" do + it "returns the type of the target as String" do + expect(Retraction.for(post, alice).target_type).to eq("Post") + end + + it "is Person for a Contact-retraction" do + contact = FactoryGirl.create(:contact) + expect(Retraction.for(contact, contact.user).target_type).to eq("Person") end end end diff --git a/spec/lib/diaspora/federation/receive_spec.rb b/spec/lib/diaspora/federation/receive_spec.rb index c4a8a7e9c..b7dc03902 100644 --- a/spec/lib/diaspora/federation/receive_spec.rb +++ b/spec/lib/diaspora/federation/receive_spec.rb @@ -420,6 +420,49 @@ describe Diaspora::Federation::Receive do expect(contact).not_to be_nil expect(contact.sharing).to be_falsey end + + context "Relayable" do + it "relays the retraction and destroys the relayable when the parent-author is local" do + local_post = FactoryGirl.create(:status_message, author: alice.person, public: true) + remote_comment = FactoryGirl.create(:comment, author: sender, post: local_post) + + retraction = FactoryGirl.build( + :retraction_entity, + author: sender.diaspora_handle, + target_guid: remote_comment.guid, + target_type: "Comment" + ) + + comment_retraction = Retraction.for(remote_comment, alice) + + expect(Retraction).to receive(:for).with(instance_of(Comment), alice).and_return(comment_retraction) + expect(comment_retraction).to receive(:defer_dispatch).with(alice) + expect(comment_retraction).to receive(:perform).and_call_original + expect_any_instance_of(Comment).to receive(:destroy!).and_call_original + + Diaspora::Federation::Receive.retraction(retraction, nil) + + expect(StatusMessage.exists?(guid: remote_comment.guid)).to be_falsey + end + + it "destroys the relayable when the parent-author is not local" do + remote_post = FactoryGirl.create(:status_message, author: sender, public: true) + remote_comment = FactoryGirl.create(:comment, author: sender, post: remote_post) + + retraction = FactoryGirl.build( + :retraction_entity, + author: sender.diaspora_handle, + target_guid: remote_comment.guid, + target_type: "Comment" + ) + + expect_any_instance_of(Comment).to receive(:destroy!).and_call_original + + Diaspora::Federation::Receive.retraction(retraction, nil) + + expect(StatusMessage.exists?(guid: remote_comment.guid)).to be_falsey + end + end end describe ".status_message" do