From 720ff55262fec0abc630a613a4f3564b98b689dc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 12 Feb 2017 17:28:15 +0100 Subject: [PATCH] Adding more unit tests. Fixing Salmon slaps XML --- app/helpers/atom_builder_helper.rb | 86 ++++++++++--------- app/services/favourite_service.rb | 8 +- app/services/fetch_atom_service.rb | 2 + app/services/unfavourite_service.rb | 8 +- .../after_remote_follow_request_worker.rb | 2 +- app/workers/after_remote_follow_worker.rb | 2 +- .../services/authorize_follow_service_spec.rb | 49 +++++++++++ spec/services/block_service_spec.rb | 34 ++++++++ spec/services/favourite_service_spec.rb | 36 ++++++++ spec/services/follow_service_spec.rb | 72 +++++++++++++++- spec/services/reject_follow_service_spec.rb | 49 +++++++++++ spec/services/unblock_service_spec.rb | 36 ++++++++ spec/services/unfollow_service_spec.rb | 37 +++++++- 13 files changed, 363 insertions(+), 58 deletions(-) create mode 100644 spec/services/authorize_follow_service_spec.rb create mode 100644 spec/services/reject_follow_service_spec.rb diff --git a/app/helpers/atom_builder_helper.rb b/app/helpers/atom_builder_helper.rb index 08d70b7ac..484cf0793 100644 --- a/app/helpers/atom_builder_helper.rb +++ b/app/helpers/atom_builder_helper.rb @@ -167,6 +167,52 @@ module AtomBuilderHelper end end + def include_target(xml, target) + simple_id xml, TagManager.instance.uri_for(target) + + if target.object_type == :person + include_author xml, target + else + object_type xml, target.object_type + verb xml, target.verb + title xml, target.title + link_alternate xml, TagManager.instance.url_for(target) + end + + # Statuses have content and author + return unless target.is_a?(Status) + + rich_content xml, target + verb xml, target.verb + published_at xml, target.created_at + updated_at xml, target.updated_at + + author(xml) do + include_author xml, target.account + end + + if target.reply? + in_reply_to xml, TagManager.instance.uri_for(target.thread), TagManager.instance.url_for(target.thread) + end + + link_visibility xml, target + + target.mentions.each do |mention| + link_mention xml, mention.account + end + + target.media_attachments.each do |media| + link_enclosure xml, media + end + + target.tags.each do |tag| + category xml, tag.name + end + + category(xml, 'nsfw') if target.sensitive? + privacy_scope(xml, target.visibility) + end + def include_entry(xml, stream_entry) unique_id xml, stream_entry.created_at, stream_entry.activity_id, stream_entry.activity_type published_at xml, stream_entry.created_at @@ -185,45 +231,7 @@ module AtomBuilderHelper if stream_entry.targeted? target(xml) do - simple_id xml, TagManager.instance.uri_for(stream_entry.target) - - if stream_entry.target.object_type == :person - include_author xml, stream_entry.target - else - object_type xml, stream_entry.target.object_type - verb xml, stream_entry.target.verb - title xml, stream_entry.target.title - link_alternate xml, TagManager.instance.url_for(stream_entry.target) - end - - # Statuses have content and author - if stream_entry.target.is_a?(Status) - rich_content xml, stream_entry.target - verb xml, stream_entry.target.verb - published_at xml, stream_entry.target.created_at - updated_at xml, stream_entry.target.updated_at - - author(xml) do - include_author xml, stream_entry.target.account - end - - link_visibility xml, stream_entry.target - - stream_entry.target.mentions.each do |mention| - link_mention xml, mention.account - end - - stream_entry.target.media_attachments.each do |media| - link_enclosure xml, media - end - - stream_entry.target.tags.each do |tag| - category xml, tag.name - end - - category(xml, 'nsfw') if stream_entry.target.sensitive? - privacy_scope(xml, stream_entry.target.visibility) - end + include_target(xml, stream_entry.target) end end diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb index 11585250f..7038bc222 100644 --- a/app/services/favourite_service.rb +++ b/app/services/favourite_service.rb @@ -31,14 +31,10 @@ class FavouriteService < BaseService end object_type xml, :activity - verb xml, :favourite + verb xml, :favorite target(xml) do - author(xml) do - include_author xml, favourite.status.account - end - - include_entry xml, favourite.status.stream_entry + include_target xml, favourite.status end end end.to_xml diff --git a/app/services/fetch_atom_service.rb b/app/services/fetch_atom_service.rb index 98ee1db84..f7e9c150a 100644 --- a/app/services/fetch_atom_service.rb +++ b/app/services/fetch_atom_service.rb @@ -2,6 +2,8 @@ class FetchAtomService < BaseService def call(url) + return if url.blank? + response = http_client.head(url) Rails.logger.debug "Remote status HEAD request returned code #{response.code}" diff --git a/app/services/unfavourite_service.rb b/app/services/unfavourite_service.rb index b79b8a938..7ad1778f6 100644 --- a/app/services/unfavourite_service.rb +++ b/app/services/unfavourite_service.rb @@ -22,14 +22,10 @@ class UnfavouriteService < BaseService end object_type xml, :activity - verb xml, :unfavourite + verb xml, :unfavorite target(xml) do - author(xml) do - include_author xml, favourite.status.account - end - - include_entry xml, favourite.status.stream_entry + include_target xml, favourite.status end end end.to_xml diff --git a/app/workers/after_remote_follow_request_worker.rb b/app/workers/after_remote_follow_request_worker.rb index ad94d2769..f1d6869cc 100644 --- a/app/workers/after_remote_follow_request_worker.rb +++ b/app/workers/after_remote_follow_request_worker.rb @@ -9,7 +9,7 @@ class AfterRemoteFollowRequestWorker follow_request = FollowRequest.find(follow_request_id) updated_account = FetchRemoteAccountService.new.call(follow_request.target_account.remote_url) - return if updated_account.locked? + return if updated_account.nil? || updated_account.locked? follow_request.destroy FollowService.new.call(follow_request.account, updated_account.acct) diff --git a/app/workers/after_remote_follow_worker.rb b/app/workers/after_remote_follow_worker.rb index 496aaf73e..0d04456a9 100644 --- a/app/workers/after_remote_follow_worker.rb +++ b/app/workers/after_remote_follow_worker.rb @@ -9,7 +9,7 @@ class AfterRemoteFollowWorker follow = Follow.find(follow_id) updated_account = FetchRemoteAccountService.new.call(follow.target_account.remote_url) - return unless updated_account.locked? + return if updated_account.nil? || !updated_account.locked? follow.destroy FollowService.new.call(follow.account, updated_account.acct) diff --git a/spec/services/authorize_follow_service_spec.rb b/spec/services/authorize_follow_service_spec.rb new file mode 100644 index 000000000..3f3a2bc56 --- /dev/null +++ b/spec/services/authorize_follow_service_spec.rb @@ -0,0 +1,49 @@ +require 'rails_helper' + +RSpec.describe AuthorizeFollowService do + let(:sender) { Fabricate(:account, username: 'alice') } + + subject { AuthorizeFollowService.new } + + describe 'local' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + + before do + FollowRequest.create(account: bob, target_account: sender) + subject.call(bob, sender) + end + + it 'removes follow request' do + expect(bob.requested?(sender)).to be false + end + + it 'creates follow relation' do + expect(bob.following?(sender)).to be true + end + end + + describe 'remote' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com')).account } + + before do + FollowRequest.create(account: bob, target_account: sender) + stub_request(:post, "http://salmon.example.com/").to_return(:status => 200, :body => "", :headers => {}) + subject.call(bob, sender) + end + + it 'removes follow request' do + expect(bob.requested?(sender)).to be false + end + + it 'creates follow relation' do + expect(bob.following?(sender)).to be true + end + + it 'sends a follow request authorization salmon slap' do + expect(a_request(:post, "http://salmon.example.com/").with { |req| + xml = OStatus2::Salmon.new.unpack(req.body) + xml.match(TagManager::VERBS[:authorize]) + }).to have_been_made.once + end + end +end diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb index f6f07fa20..2a54e032e 100644 --- a/spec/services/block_service_spec.rb +++ b/spec/services/block_service_spec.rb @@ -1,5 +1,39 @@ require 'rails_helper' RSpec.describe BlockService do + let(:sender) { Fabricate(:account, username: 'alice') } + subject { BlockService.new } + + describe 'local' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + + before do + subject.call(sender, bob) + end + + it 'creates a blocking relation' do + expect(sender.blocking?(bob)).to be true + end + end + + describe 'remote' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com')).account } + + before do + stub_request(:post, "http://salmon.example.com/").to_return(:status => 200, :body => "", :headers => {}) + subject.call(sender, bob) + end + + it 'creates a blocking relation' do + expect(sender.blocking?(bob)).to be true + end + + it 'sends a block salmon slap' do + expect(a_request(:post, "http://salmon.example.com/").with { |req| + xml = OStatus2::Salmon.new.unpack(req.body) + xml.match(TagManager::VERBS[:block]) + }).to have_been_made.once + end + end end diff --git a/spec/services/favourite_service_spec.rb b/spec/services/favourite_service_spec.rb index eb961c28e..36f1b64d4 100644 --- a/spec/services/favourite_service_spec.rb +++ b/spec/services/favourite_service_spec.rb @@ -1,5 +1,41 @@ require 'rails_helper' RSpec.describe FavouriteService do + let(:sender) { Fabricate(:account, username: 'alice') } + subject { FavouriteService.new } + + describe 'local' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + let(:status) { Fabricate(:status, account: bob) } + + before do + subject.call(sender, status) + end + + it 'creates a favourite' do + expect(status.favourites.first).to_not be_nil + end + end + + describe 'remote' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com')).account } + let(:status) { Fabricate(:status, account: bob, uri: 'tag:example.com:blahblah') } + + before do + stub_request(:post, "http://salmon.example.com/").to_return(:status => 200, :body => "", :headers => {}) + subject.call(sender, status) + end + + it 'creates a favourite' do + expect(status.favourites.first).to_not be_nil + end + + it 'sends a salmon slap' do + expect(a_request(:post, "http://salmon.example.com/").with { |req| + xml = OStatus2::Salmon.new.unpack(req.body) + xml.match(TagManager::VERBS[:favorite]) + }).to have_been_made.once + end + end end diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb index 304e0cf71..2ce0fa464 100644 --- a/spec/services/follow_service_spec.rb +++ b/spec/services/follow_service_spec.rb @@ -1,9 +1,75 @@ require 'rails_helper' RSpec.describe FollowService do + let(:sender) { Fabricate(:account, username: 'alice') } + subject { FollowService.new } - it 'creates a following relation' - it 'creates local account for remote user' - it 'sends follow to the remote user' + context 'local account' do + describe 'locked account' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, locked: true, username: 'bob')).account } + + before do + subject.call(sender, bob.acct) + end + + it 'creates a follow request' do + expect(FollowRequest.find_by(account: sender, target_account: bob)).to_not be_nil + end + end + + describe 'unlocked account' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + + before do + subject.call(sender, bob.acct) + end + + it 'creates a following relation' do + expect(sender.following?(bob)).to be true + end + end + end + + context 'remote account' do + describe 'locked account' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, locked: true, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com')).account } + + before do + stub_request(:post, "http://salmon.example.com/").to_return(:status => 200, :body => "", :headers => {}) + subject.call(sender, bob.acct) + end + + it 'creates a follow request' do + expect(FollowRequest.find_by(account: sender, target_account: bob)).to_not be_nil + end + + it 'sends a follow request salmon slap' do + expect(a_request(:post, "http://salmon.example.com/").with { |req| + xml = OStatus2::Salmon.new.unpack(req.body) + xml.match(TagManager::VERBS[:request_friend]) + }).to have_been_made.once + end + end + + describe 'unlocked account' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com')).account } + + before do + stub_request(:post, "http://salmon.example.com/").to_return(:status => 200, :body => "", :headers => {}) + subject.call(sender, bob.acct) + end + + it 'creates a following relation' do + expect(sender.following?(bob)).to be true + end + + it 'sends a follow salmon slap' do + expect(a_request(:post, "http://salmon.example.com/").with { |req| + xml = OStatus2::Salmon.new.unpack(req.body) + xml.match(TagManager::VERBS[:follow]) + }).to have_been_made.once + end + end + end end diff --git a/spec/services/reject_follow_service_spec.rb b/spec/services/reject_follow_service_spec.rb new file mode 100644 index 000000000..50749b633 --- /dev/null +++ b/spec/services/reject_follow_service_spec.rb @@ -0,0 +1,49 @@ +require 'rails_helper' + +RSpec.describe RejectFollowService do + let(:sender) { Fabricate(:account, username: 'alice') } + + subject { RejectFollowService.new } + + describe 'local' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + + before do + FollowRequest.create(account: bob, target_account: sender) + subject.call(bob, sender) + end + + it 'removes follow request' do + expect(bob.requested?(sender)).to be false + end + + it 'does not create follow relation' do + expect(bob.following?(sender)).to be false + end + end + + describe 'remote' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com')).account } + + before do + FollowRequest.create(account: bob, target_account: sender) + stub_request(:post, "http://salmon.example.com/").to_return(:status => 200, :body => "", :headers => {}) + subject.call(bob, sender) + end + + it 'removes follow request' do + expect(bob.requested?(sender)).to be false + end + + it 'does not create follow relation' do + expect(bob.following?(sender)).to be false + end + + it 'sends a follow request rejection salmon slap' do + expect(a_request(:post, "http://salmon.example.com/").with { |req| + xml = OStatus2::Salmon.new.unpack(req.body) + xml.match(TagManager::VERBS[:reject]) + }).to have_been_made.once + end + end +end diff --git a/spec/services/unblock_service_spec.rb b/spec/services/unblock_service_spec.rb index 126f70ff1..1b9ae1239 100644 --- a/spec/services/unblock_service_spec.rb +++ b/spec/services/unblock_service_spec.rb @@ -1,5 +1,41 @@ require 'rails_helper' RSpec.describe UnblockService do + let(:sender) { Fabricate(:account, username: 'alice') } + subject { UnblockService.new } + + describe 'local' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + + before do + sender.block!(bob) + subject.call(sender, bob) + end + + it 'destroys the blocking relation' do + expect(sender.blocking?(bob)).to be false + end + end + + describe 'remote' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com')).account } + + before do + sender.block!(bob) + stub_request(:post, "http://salmon.example.com/").to_return(:status => 200, :body => "", :headers => {}) + subject.call(sender, bob) + end + + it 'destroys the blocking relation' do + expect(sender.following?(bob)).to be false + end + + it 'sends an unblock salmon slap' do + expect(a_request(:post, "http://salmon.example.com/").with { |req| + xml = OStatus2::Salmon.new.unpack(req.body) + xml.match(TagManager::VERBS[:unblock]) + }).to have_been_made.once + end + end end diff --git a/spec/services/unfollow_service_spec.rb b/spec/services/unfollow_service_spec.rb index 6541415d0..8ec2148a1 100644 --- a/spec/services/unfollow_service_spec.rb +++ b/spec/services/unfollow_service_spec.rb @@ -1,8 +1,41 @@ require 'rails_helper' RSpec.describe UnfollowService do + let(:sender) { Fabricate(:account, username: 'alice') } + subject { UnfollowService.new } - it 'destroys the following relation' - it 'sends remote interaction for remote user' + describe 'local' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } + + before do + sender.follow!(bob) + subject.call(sender, bob) + end + + it 'destroys the following relation' do + expect(sender.following?(bob)).to be false + end + end + + describe 'remote' do + let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com')).account } + + before do + sender.follow!(bob) + stub_request(:post, "http://salmon.example.com/").to_return(:status => 200, :body => "", :headers => {}) + subject.call(sender, bob) + end + + it 'destroys the following relation' do + expect(sender.following?(bob)).to be false + end + + it 'sends an unfollow salmon slap' do + expect(a_request(:post, "http://salmon.example.com/").with { |req| + xml = OStatus2::Salmon.new.unpack(req.body) + xml.match(TagManager::VERBS[:unfollow]) + }).to have_been_made.once + end + end end