diaspora/spec/models/reshare_spec.rb
Jason Robinson 9a35a0d8dd Add participation to root.author on receiving reshare
When author of the root post receives a reshare to it, no participation is added to the root author on the reshare. This causes any comments on the reshare on remote pods not to be sent to the author. Adding a participation should subscribe to the reshare and thus bring added comments back to the author.

closes #6481
2015-11-22 02:50:38 +01:00

307 lines
10 KiB
Ruby

require 'spec_helper'
describe Reshare, :type => :model do
it 'has a valid Factory' do
expect(FactoryGirl.build(:reshare)).to be_valid
end
it 'requires root' do
reshare = FactoryGirl.build(:reshare, :root => nil)
expect(reshare).not_to be_valid
end
it 'require public root' do
reshare = FactoryGirl.build(:reshare, :root => FactoryGirl.create(:status_message, :public => false))
expect(reshare).not_to be_valid
expect(reshare.errors[:base]).to include('Only posts which are public may be reshared.')
end
it 'forces public' do
expect(FactoryGirl.create(:reshare, :public => false).public).to be true
end
describe "#root_diaspora_id" do
it "should return the root diaspora id" do
reshare = FactoryGirl.create(:reshare, root: FactoryGirl.build(:status_message, author: bob.person, public: true))
expect(reshare.root_diaspora_id).to eq(bob.person.diaspora_handle)
end
it "should be nil if no root found" do
reshare = FactoryGirl.create(:reshare, root: FactoryGirl.build(:status_message, author: bob.person, public: true))
reshare.root = nil
expect(reshare.root_diaspora_id).to be_nil
end
end
describe "#receive" do
let(:receive_reshare) { @reshare.receive(@root.author.owner, @reshare.author) }
before do
@reshare = FactoryGirl.create(:reshare, :root => FactoryGirl.build(:status_message, :author => bob.person, :public => true))
@root = @reshare.root
end
it 'increments the reshare count' do
receive_reshare
expect(@root.resharers.count).to eq(1)
end
it 'adds the resharer to the re-sharers of the post' do
receive_reshare
expect(@root.resharers).to include(@reshare.author)
end
it "does not error if the root author has a contact for the resharer" do
bob.share_with @reshare.author, bob.aspects.first
expect {
Timeout.timeout(5) do
receive_reshare #This doesn't ever terminate on my machine before it was fixed.
end
}.not_to raise_error
end
it "participates root author in the reshare" do
receive_reshare
participations = Participation.where(target_id: @reshare.id, author_id: @root.author_id)
expect(participations.count).to eq(1)
end
end
describe '#nsfw' do
before do
sfw = FactoryGirl.build(:status_message, :author => alice.person, :public => true)
nsfw = FactoryGirl.build(:status_message, :author => alice.person, :public => true, :text => "This is #nsfw")
@sfw_reshare = FactoryGirl.build(:reshare, :root => sfw)
@nsfw_reshare = FactoryGirl.build(:reshare, :root => nsfw)
end
it 'deletates #nsfw to the root post' do
expect(@sfw_reshare.nsfw).not_to be true
expect(@nsfw_reshare.nsfw).to be_truthy
end
end
describe '#poll' do
before do
@root_post = FactoryGirl.create(:status_message_with_poll, public: true)
@reshare = FactoryGirl.create(:reshare, root: @root_post)
end
it 'contains root poll' do
expect(@reshare.poll).to eq @root_post.poll
end
end
describe '#notification_type' do
before do
sm = FactoryGirl.build(:status_message, :author => alice.person, :public => true)
@reshare = FactoryGirl.build(:reshare, :root => sm)
end
it 'does not return anything for non-author of the original post' do
expect(@reshare.notification_type(bob, @reshare.author)).to be_nil
end
it 'returns "Reshared" for the original post author' do
expect(@reshare.notification_type(alice, @reshare.author)).to eq(Notifications::Reshared)
end
it 'does not error out if the root was deleted' do
@reshare.root = nil
expect {
@reshare.notification_type(alice, @reshare.author)
}.to_not raise_error
end
end
describe '#absolute_root' do
before do
@sm = FactoryGirl.build(:status_message, :author => alice.person, :public => true)
rs1 = FactoryGirl.build(:reshare, :root=>@sm)
rs2 = FactoryGirl.build(:reshare, :root=>rs1)
@rs3 = FactoryGirl.build(:reshare, :root=>rs2)
sm = FactoryGirl.create(:status_message, :author => alice.person, :public => true)
rs1 = FactoryGirl.create(:reshare, :root => sm)
@of_deleted = FactoryGirl.build(:reshare, :root => rs1)
sm.destroy
rs1.reload
end
it 'resolves root posts to the top level' do
expect(@rs3.absolute_root).to eq(@sm)
end
it 'can handle deleted reshares' do
expect(@of_deleted.absolute_root).to be_nil
end
it 'is used everywhere' do
expect(@rs3.message).to eq @sm.message
expect(@of_deleted.message).to be_nil
expect(@rs3.photos).to eq @sm.photos
expect(@of_deleted.photos).to be_empty
expect(@rs3.o_embed_cache).to eq @sm.o_embed_cache
expect(@of_deleted.o_embed_cache).to be_nil
expect(@rs3.open_graph_cache).to eq @sm.open_graph_cache
expect(@of_deleted.open_graph_cache).to be_nil
expect(@rs3.mentioned_people).to eq @sm.mentioned_people
expect(@of_deleted.mentioned_people).to be_empty
expect(@rs3.nsfw).to eq @sm.nsfw
expect(@of_deleted.nsfw).to be_nil
expect(@rs3.address).to eq @sm.location.try(:address)
expect(@of_deleted.address).to be_nil
end
end
describe "XML" do
before do
@reshare = FactoryGirl.build(:reshare)
@xml = @reshare.to_xml.to_s
end
context 'serialization' do
it 'serializes root_diaspora_id' do
expect(@xml).to include("root_diaspora_id")
expect(@xml).to include(@reshare.author.diaspora_handle)
end
it 'serializes root_guid' do
expect(@xml).to include("root_guid")
expect(@xml).to include(@reshare.root.guid)
end
end
context 'marshalling' do
context 'local' do
before do
@original_author = @reshare.root.author
@root_object = @reshare.root
end
it 'marshals the guid' do
expect(Reshare.from_xml(@xml).root_guid).to eq(@root_object.guid)
end
it 'fetches the root post from root_guid' do
expect(Reshare.from_xml(@xml).root).to eq(@root_object)
end
it 'fetches the root author from root_diaspora_id' do
expect(Reshare.from_xml(@xml).root.author).to eq(@original_author)
end
end
describe 'destroy' do
it 'allows you to destroy the reshare if the root post is missing' do
reshare = FactoryGirl.build(:reshare)
reshare.root = nil
expect{
reshare.destroy
}.to_not raise_error
end
end
context 'remote' do
before do
@root_object = @reshare.root
@root_object.delete
@response = double
allow(@response).to receive(:status).and_return(200)
allow(@response).to receive(:success?).and_return(true)
end
it 'fetches the root author from root_diaspora_id' do
@original_profile = @reshare.root.author.profile.dup
@reshare.root.author.profile.delete
@original_author = @reshare.root.author.dup
@reshare.root.author.delete
@original_author.profile = @original_profile
expect(Person).to receive(:find_or_fetch_by_identifier).and_return(@original_author)
allow(@response).to receive(:body).and_return(@root_object.to_diaspora_xml)
expect(Faraday.default_connection).to receive(:get).with(
URI.join(
@original_author.url,
Rails.application.routes.url_helpers.short_post_path(
@root_object.guid,
format: "xml"
)
)
).and_return(@response)
Reshare.from_xml(@xml)
end
context "fetching post" do
it "raises if the post is not found" do
allow(@response).to receive(:status).and_return(404)
expect(Faraday.default_connection).to receive(:get).and_return(@response)
expect {
Reshare.from_xml(@xml)
}.to raise_error(Diaspora::PostNotFetchable)
end
it "raises if there's another error receiving the post" do
allow(@response).to receive(:status).and_return(500)
allow(@response).to receive(:success?).and_return(false)
expect(Faraday.default_connection).to receive(:get).and_return(@response)
expect {
Reshare.from_xml(@xml)
}.to raise_error RuntimeError
end
end
context 'saving the post' do
before do
allow(@response).to receive(:body).and_return(@root_object.to_diaspora_xml)
allow(Faraday.default_connection).to receive(:get).with(
URI.join(
@reshare.root.author.url,
Rails.application.routes.url_helpers.short_post_path(
@root_object.guid,
format: "xml"
)
)
).and_return(@response)
end
it 'fetches the root post from root_guid' do
root = Reshare.from_xml(@xml).root
[:text, :guid, :diaspora_handle, :type, :public].each do |attr|
expect(root.send(attr)).to eq(@reshare.root.send(attr))
end
end
it 'correctly saves the type' do
expect(Reshare.from_xml(@xml).root.reload.type).to eq("StatusMessage")
end
it 'correctly sets the author' do
@original_author = @reshare.root.author
expect(Reshare.from_xml(@xml).root.reload.author.reload).to eq(@original_author)
end
it 'verifies that the author of the post received is the same as the author in the reshare xml' do
@original_author = @reshare.root.author.dup
@xml = @reshare.to_xml.to_s
different_person = FactoryGirl.build(:person)
expect(Person).to receive(:find_or_fetch_by_identifier).and_return(different_person)
allow(different_person).to receive(:url).and_return(@original_author.url)
expect{
Reshare.from_xml(@xml)
}.to raise_error /^Diaspora ID \(.+\) in the root does not match the Diaspora ID \(.+\) specified in the reshare!$/
end
end
end
end
end
end