Commit 5e157dc9 authored by Benjamin Neff's avatar Benjamin Neff Committed by Dennis Schubert

Send participation after receiving a public post

This is to let the author of the post know, that this pod is interested
in updates about this post.

The sending user is only used to verify that the participation was sent
from this pod, but lets use an admin/podmin account if available.

closes #7708
parent 6c5b8b73
......@@ -6,6 +6,7 @@
* Improve password autocomplete with password managers [#7642](https://github.com/diaspora/diaspora/pull/7642)
* Remove the limit of participants in private conversations [#7705](https://github.com/diaspora/diaspora/pull/7705)
* Send blocks to the blocked persons pod for better UX [#7705](https://github.com/diaspora/diaspora/pull/7705)
* Send a dummy participation on all incoming public posts to increase interaction consistency [#7708](https://github.com/diaspora/diaspora/pull/7708)
## Bug fixes
* Fix invite link on the contacts page when the user has no contacts [#7690](https://github.com/diaspora/diaspora/pull/7690)
......
......@@ -153,7 +153,7 @@ module Diaspora
guid: entity.guid,
created_at: entity.created_at,
root_guid: entity.root_guid
)
).tap {|reshare| send_participation_for(reshare) }
end
end
......@@ -193,6 +193,8 @@ module Diaspora
status_message.photos = save_or_load_photos(entity.photos)
status_message.save!
send_participation_for(status_message)
end
end
end
......@@ -328,6 +330,24 @@ module Diaspora
end
end
end
private_class_method def self.send_participation_for(post)
return unless post.public?
user = user_for_participation
participation = Participation.new(target: post, author: user.person)
Diaspora::Federation::Dispatcher.build(user, participation, subscribers: [post.author]).dispatch
rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
logger.warn "failed to send participation for post #{post.guid}: #{e.class}: #{e.message}"
end
# Use configured admin account if available,
# or use first user with admin role if available,
# or use first user who isn't closed
private_class_method def self.user_for_participation
User.find_by(username: AppConfig.admins.account.to_s) ||
Role.admins.first&.person&.owner ||
User.where(locked_at: nil).first
end
end
end
end
......@@ -116,6 +116,11 @@ describe "Receive federation messages feature" do
alice, instance_of(Reshare)
).and_return(double(create!: true))
expect(Diaspora::Federation::Dispatcher).to receive(:build) do |_user, participation, _opts|
expect(participation.target.guid).to eq(reshare.guid)
instance_double(:dispatch)
end
post_message(generate_payload(reshare, sender))
expect(Reshare.exists?(root_guid: post.guid)).to be_truthy
......
......@@ -8,6 +8,15 @@ shared_examples_for "messages which are indifferent about sharing fact" do
it "treats status message receive correctly" do
entity = Fabricate(:status_message_entity, author: sender_id, public: public)
if public
expect(Diaspora::Federation::Dispatcher).to receive(:build) do |_user, participation, _opts|
expect(participation.target.guid).to eq(entity.guid)
instance_double(:dispatch)
end
else
expect(Diaspora::Federation::Dispatcher).not_to receive(:build)
end
post_message(generate_payload(entity, sender, recipient), recipient)
expect(StatusMessage.exists?(guid: entity.guid)).to be_truthy
......
......@@ -541,6 +541,10 @@ describe Diaspora::Federation::Receive do
it_behaves_like "it ignores existing object received twice", Reshare do
let(:entity) { reshare_entity }
end
it_behaves_like "it sends a participation to the author" do
let(:entity) { reshare_entity }
end
end
describe ".retraction" do
......@@ -766,6 +770,18 @@ describe Diaspora::Federation::Receive do
expect(status_message.photos.map(&:guid)).to include(photo1.guid, photo2.guid)
expect(status_message.photos.map(&:text)).to include(received_photo.text, photo2.text)
end
it_behaves_like "it sends a participation to the author" do
let(:entity) { status_message_entity }
end
it "doesn't send participations for a private post" do
status_message_entity = Fabricate(:status_message_entity, author: sender.diaspora_handle, public: false)
expect(Diaspora::Federation::Dispatcher).not_to receive(:build)
Diaspora::Federation::Receive.perform(status_message_entity)
end
end
end
end
......@@ -73,3 +73,76 @@ shared_examples_for "it relays relayables" do |klass|
Diaspora::Federation::Receive.perform(entity)
end
end
shared_examples_for "it sends a participation to the author" do
it "sends a participation for the post to the author" do
dispatcher = double
expect(Diaspora::Federation::Dispatcher).to receive(:build) do |user, participation, opts|
expect(user).to be_a(User)
expect(participation.target.guid).to eq(entity.guid)
subscribers = opts[:subscribers]
expect(subscribers.size).to eq(1)
expect(subscribers.first.diaspora_handle).to eq(entity.author)
dispatcher
end
expect(dispatcher).to receive(:dispatch)
Diaspora::Federation::Receive.perform(entity)
end
it "doesn't save the participation in the database" do
participation_guid = nil
expect(Diaspora::Federation::Dispatcher).to receive(:build) do |_user, participation, _opts|
participation_guid = participation.guid
instance_double(:dispatch)
end
Diaspora::Federation::Receive.perform(entity)
expect(Participation.where(guid: participation_guid)).not_to exist
end
it "uses the configured admin as sender for the participation" do
AppConfig.admins.account = bob.username
expect(Diaspora::Federation::Dispatcher).to receive(:build) do |user, _participation, _opts|
expect(user.username).to eq(bob.username)
instance_double(:dispatch)
end
Diaspora::Federation::Receive.perform(entity)
end
it "uses the first user with an admin role if no admin is configured in the config" do
AppConfig.admins.account = nil
admin_role = FactoryGirl.create(:role, name: "admin")
expect(Diaspora::Federation::Dispatcher).to receive(:build) do |user, _participation, _opts|
expect(user.username).to eq(admin_role.person.owner.username)
instance_double(:dispatch)
end
Diaspora::Federation::Receive.perform(entity)
end
it "uses the first open account if no admin is available" do
AppConfig.admins.account = nil
expect(Role.admins).to be_empty
User.first.close_account!
expect(Diaspora::Federation::Dispatcher).to receive(:build) do |user, _participation, _opts|
expect(user.username).to eq(User.second.username)
instance_double(:dispatch)
end
Diaspora::Federation::Receive.perform(entity)
end
it "still receives the entity successfully if there is an error while sending the participation" do
expect(Diaspora::Federation::Dispatcher).to receive(:build).and_raise "FooBar"
Diaspora::Federation::Receive.perform(entity)
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment