write specs for dispatcher

This commit is contained in:
Benjamin Neff 2016-06-12 21:03:56 +02:00
parent f95e0faa37
commit dee8bc6f0e
7 changed files with 242 additions and 5 deletions

View file

@ -38,7 +38,7 @@ module Diaspora
local_people, remote_people = object.subscribers.partition(&:local?)
deliver_to_local(local_people) unless local_people.empty?
deliver_to_remote(remote_people) unless remote_people.empty?
deliver_to_remote(remote_people)
end
def deliver_to_local(people)

View file

@ -2,13 +2,15 @@ module Diaspora
module Federation
class Dispatcher
class Private < Dispatcher
private
def deliver_to_remote(people)
return if people.empty?
entity = Entities.build(object)
Workers::SendPrivate.perform_async(sender.id, entity.to_s, targets(people, salmon_slap(entity)))
end
private
def targets(people, salmon_slap)
people.map {|person| [person.receive_url, salmon_slap.generate_xml(person.public_key)] }.to_h
end

View file

@ -2,6 +2,8 @@ module Diaspora
module Federation
class Dispatcher
class Public < Dispatcher
private
def deliver_to_services
deliver_to_hub if object.instance_of?(StatusMessage)
super
@ -10,12 +12,12 @@ module Diaspora
def deliver_to_remote(people)
targets = target_urls(people) + additional_target_urls
return if targets.empty?
entity = Entities.build(object)
Workers::SendPublic.perform_async(sender.id, entity.to_s, targets, salmon_xml(entity))
end
private
def target_urls(people)
Pod.where(id: people.map(&:pod_id).uniq).map {|pod| pod.url_to("/receive/public") }
end

View file

@ -0,0 +1,43 @@
require "spec_helper"
describe Diaspora::Federation::Dispatcher::Private do
let(:post) { FactoryGirl.create(:status_message, author: alice.person, text: "hello", public: false) }
let(:comment) { FactoryGirl.create(:comment, author: alice.person, post: post) }
before do
alice.share_with(remote_raphael, alice.aspects.first)
alice.add_to_streams(post, [alice.aspects.first])
end
describe "#dispatch" do
context "deliver to remote user" do
it "queues a private send job" do
xml = "<diaspora/>"
expect(Workers::SendPrivate).to receive(:perform_async) do |user_id, _entity_string, targets|
expect(user_id).to eq(alice.id)
expect(targets.size).to eq(1)
expect(targets).to have_key(remote_raphael.receive_url)
expect(targets[remote_raphael.receive_url]).to eq(xml)
end
salmon = double
expect(DiasporaFederation::Salmon::EncryptedSlap).to receive(:prepare).and_return(salmon)
expect(salmon).to receive(:generate_xml).and_return(xml)
Diaspora::Federation::Dispatcher.build(alice, post).dispatch
end
it "does not queue a private send job when no remote recipients specified" do
bobs_post = FactoryGirl.create(:status_message, author: alice.person, text: "hello", public: false)
bob.add_to_streams(bobs_post, [bob.aspects.first])
expect(Workers::SendPrivate).not_to receive(:perform_async)
Diaspora::Federation::Dispatcher.build(bob, bobs_post).dispatch
end
end
end
it_behaves_like "a dispatcher"
end

View file

@ -0,0 +1,79 @@
require "spec_helper"
describe Diaspora::Federation::Dispatcher::Public do
let(:post) { FactoryGirl.create(:status_message, author: alice.person, text: "hello", public: true) }
let(:comment) { FactoryGirl.create(:comment, author: alice.person, post: post) }
describe "#dispatch" do
context "pubsubhubbub" do
it "delivers public posts to pubsubhubbub" do
expect(Workers::PublishToHub).to receive(:perform_async).with(alice.atom_url)
Diaspora::Federation::Dispatcher.build(alice, post).dispatch
end
it "does not call pubsubhubbub for comments" do
expect(Workers::PublishToHub).not_to receive(:perform_async)
Diaspora::Federation::Dispatcher.build(alice, comment).dispatch
end
end
context "relay functionality" do
before do
AppConfig.relay.outbound.url = "https://relay.iliketoast.net/receive/public"
end
it "delivers public post to relay when relay is enabled" do
AppConfig.relay.outbound.send = true
expect(Workers::SendPublic).to receive(:perform_async) do |_user_id, _entity_string, urls, _xml|
expect(urls).to include("https://relay.iliketoast.net/receive/public")
end
Diaspora::Federation::Dispatcher.build(alice, post).dispatch
end
it "does not deliver post to relay when relay is disabled" do
AppConfig.relay.outbound.send = false
expect(Workers::SendPublic).not_to receive(:perform_async)
Diaspora::Federation::Dispatcher.build(alice, post).dispatch
end
it "does not deliver comments to relay" do
AppConfig.relay.outbound.send = true
expect(Workers::SendPublic).not_to receive(:perform_async)
Diaspora::Federation::Dispatcher.build(alice, comment).dispatch
end
end
context "deliver to remote user" do
it "queues a public send job" do
alice.share_with(remote_raphael, alice.aspects.first)
salmon_xml = "<diaspora/>"
expect(Workers::SendPublic).to receive(:perform_async) do |user_id, _entity_string, urls, xml|
expect(user_id).to eq(alice.id)
expect(urls.size).to eq(1)
expect(urls[0]).to eq(remote_raphael.pod.url_to("/receive/public"))
expect(xml).to eq(salmon_xml)
end
expect(DiasporaFederation::Salmon::Slap).to receive(:generate_xml).and_return(salmon_xml)
Diaspora::Federation::Dispatcher.build(alice, post).dispatch
end
it "does not queue a private send job when no remote recipients specified" do
expect(Workers::SendPublic).not_to receive(:perform_async)
Diaspora::Federation::Dispatcher.build(alice, post).dispatch
end
end
end
it_behaves_like "a dispatcher"
end

View file

@ -0,0 +1,43 @@
require "spec_helper"
describe Diaspora::Federation::Dispatcher do
let(:post) { FactoryGirl.create(:status_message, author: alice.person, text: "hello", public: true) }
let(:opts) { {service_types: "Services::Twitter"} }
describe ".build" do
it "creates a public dispatcher for a public post" do
expect(Diaspora::Federation::Dispatcher::Public).to receive(:new).with(alice, post, opts).and_call_original
dispatcher = described_class.build(alice, post, opts)
expect(dispatcher).to be_instance_of(Diaspora::Federation::Dispatcher::Public)
end
it "creates a private dispatcher for a private post" do
private = FactoryGirl.create(:status_message, author: alice.person, text: "hello", public: false)
expect(Diaspora::Federation::Dispatcher::Private).to receive(:new).with(alice, private, opts).and_call_original
dispatcher = described_class.build(alice, private, opts)
expect(dispatcher).to be_instance_of(Diaspora::Federation::Dispatcher::Private)
end
it "creates a private dispatcher for object with no public flag" do
object = double
expect(Diaspora::Federation::Dispatcher::Private).to receive(:new).with(alice, object, {}).and_call_original
dispatcher = described_class.build(alice, object)
expect(dispatcher).to be_instance_of(Diaspora::Federation::Dispatcher::Private)
end
end
describe ".defer_dispatch" do
it "queues a job for dispatch" do
expect(Workers::DeferredDispatch).to receive(:perform_async).with(alice.id, "StatusMessage", post.id, opts)
described_class.defer_dispatch(alice, post, opts)
end
end
end

View file

@ -0,0 +1,68 @@
shared_examples "a dispatcher" do
describe "#dispatch" do
context "deliver to user services" do
let(:twitter) { Services::Twitter.new(access_token: "twitter") }
let(:facebook) { Services::Facebook.new(access_token: "facebook") }
before do
alice.services << twitter << facebook
end
it "delivers a StatusMessage to specified services" do
opts = {service_types: "Services::Twitter", url: "https://example.org/p/123"}
expect(Workers::PostToService).to receive(:perform_async).with(twitter.id, post.id, "https://example.org/p/123")
Diaspora::Federation::Dispatcher.build(alice, post, opts).dispatch
end
it "delivers a Retraction of a Post to all user services" do
skip # TODO
retraction = Retraction.for(post, alice)
Diaspora::Federation::Dispatcher.build(alice, retraction).dispatch
end
it "does not deliver a Comment to services" do
expect(Workers::PostToService).not_to receive(:perform_async)
Diaspora::Federation::Dispatcher.build(alice, comment).dispatch
end
it "does not deliver a Retraction of a Comment to services" do
expect(Workers::DeletePostFromService).not_to receive(:perform_async)
retraction = Retraction.for(comment, alice)
Diaspora::Federation::Dispatcher.build(alice, retraction).dispatch
end
end
context "deliver to local user" do
it "queues receive local job for all local receivers" do
expect(Workers::ReceiveLocal).to receive(:perform_async).with("StatusMessage", post.id, [bob.id])
Diaspora::Federation::Dispatcher.build(alice, post).dispatch
end
it "gets the object for the receiving user" do
expect(Workers::ReceiveLocal).to receive(:perform_async).with("RSpec::Mocks::Double", 42, [bob.id])
object = double
object_to_receive = double
expect(object).to receive(:subscribers).and_return([bob.person])
expect(object).to receive(:object_to_receive).and_return(object_to_receive)
expect(object).to receive(:public?).and_return(post.public?)
expect(object_to_receive).to receive(:id).and_return(42)
Diaspora::Federation::Dispatcher.build(alice, object).dispatch
end
it "does not queue a job if the object to receive is nil" do
expect(Workers::ReceiveLocal).not_to receive(:perform_async)
object = double
expect(object).to receive(:subscribers).and_return([bob.person])
expect(object).to receive(:object_to_receive).and_return(nil)
expect(object).to receive(:public?).and_return(post.public?)
Diaspora::Federation::Dispatcher.build(alice, object).dispatch
end
end
end
end