From b0630ddc8261250c5edbf2907648695041649e98 Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 21 Jul 2019 00:53:28 +0200 Subject: Original upstream merge --- spec/services/fetch_atom_service_spec.rb | 90 ------------------------- spec/services/fetch_resource_service_spec.rb | 97 +++++++++++++++++++++++++++ spec/services/import_service_spec.rb | 34 +++++++++- spec/services/resolve_account_service_spec.rb | 25 +++---- spec/services/resolve_url_service_spec.rb | 44 ++---------- spec/services/suspend_account_service_spec.rb | 2 - 6 files changed, 142 insertions(+), 150 deletions(-) delete mode 100644 spec/services/fetch_atom_service_spec.rb create mode 100644 spec/services/fetch_resource_service_spec.rb (limited to 'spec/services') diff --git a/spec/services/fetch_atom_service_spec.rb b/spec/services/fetch_atom_service_spec.rb deleted file mode 100644 index 32c284243..000000000 --- a/spec/services/fetch_atom_service_spec.rb +++ /dev/null @@ -1,90 +0,0 @@ -require 'rails_helper' - -RSpec.describe FetchAtomService, type: :service do - describe '#call' do - let(:url) { 'http://example.com' } - subject { FetchAtomService.new.call(url) } - - context 'url is blank' do - let(:url) { '' } - it { is_expected.to be_nil } - end - - context 'request failed' do - before do - WebMock.stub_request(:get, url).to_return(status: 500, body: '', headers: {}) - end - - it { is_expected.to be_nil } - end - - context 'raise OpenSSL::SSL::SSLError' do - before do - allow(Request).to receive_message_chain(:new, :add_headers, :perform).and_raise(OpenSSL::SSL::SSLError) - end - - it 'output log and return nil' do - expect_any_instance_of(ActiveSupport::Logger).to receive(:debug).with('SSL error: OpenSSL::SSL::SSLError') - is_expected.to be_nil - end - end - - context 'raise HTTP::ConnectionError' do - before do - allow(Request).to receive_message_chain(:new, :add_headers, :perform).and_raise(HTTP::ConnectionError) - end - - it 'output log and return nil' do - expect_any_instance_of(ActiveSupport::Logger).to receive(:debug).with('HTTP ConnectionError: HTTP::ConnectionError') - is_expected.to be_nil - end - end - - context 'response success' do - let(:body) { '' } - let(:headers) { { 'Content-Type' => content_type } } - let(:json) { - { id: 1, - '@context': ActivityPub::TagManager::CONTEXT, - type: 'Note', - }.to_json - } - - before do - WebMock.stub_request(:get, url).to_return(status: 200, body: body, headers: headers) - end - - context 'content_type is activity+json' do - let(:content_type) { 'application/activity+json; charset=utf-8' } - let(:body) { json } - - it { is_expected.to eq [1, { prefetched_body: body, id: true }] } - end - - context 'content_type is ld+json with profile' do - let(:content_type) { 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' } - let(:body) { json } - - it { is_expected.to eq [1, { prefetched_body: body, id: true }] } - end - - before do - WebMock.stub_request(:get, url).to_return(status: 200, body: body, headers: headers) - WebMock.stub_request(:get, 'http://example.com/foo').to_return(status: 200, body: json, headers: { 'Content-Type' => 'application/activity+json' }) - end - - context 'has link header' do - let(:headers) { { 'Link' => '; rel="alternate"; type="application/activity+json"', } } - - it { is_expected.to eq [1, { prefetched_body: json, id: true }] } - end - - context 'content type is text/html' do - let(:content_type) { 'text/html' } - let(:body) { '' } - - it { is_expected.to eq [1, { prefetched_body: json, id: true }] } - end - end - end -end diff --git a/spec/services/fetch_resource_service_spec.rb b/spec/services/fetch_resource_service_spec.rb new file mode 100644 index 000000000..839ad024c --- /dev/null +++ b/spec/services/fetch_resource_service_spec.rb @@ -0,0 +1,97 @@ +require 'rails_helper' + +RSpec.describe FetchResourceService, type: :service do + describe '#call' do + let(:url) { 'http://example.com' } + + subject { described_class.new.call(url) } + + context 'with blank url' do + let(:url) { '' } + it { is_expected.to be_nil } + end + + context 'when request fails' do + before do + stub_request(:get, url).to_return(status: 500, body: '', headers: {}) + end + + it { is_expected.to be_nil } + end + + context 'when OpenSSL::SSL::SSLError is raised' do + before do + allow(Request).to receive_message_chain(:new, :add_headers, :on_behalf_of, :perform).and_raise(OpenSSL::SSL::SSLError) + end + + it { is_expected.to be_nil } + end + + context 'when HTTP::ConnectionError is raised' do + before do + allow(Request).to receive_message_chain(:new, :add_headers, :on_behalf_of, :perform).and_raise(HTTP::ConnectionError) + end + + it { is_expected.to be_nil } + end + + context 'when request succeeds' do + let(:body) { '' } + + let(:content_type) { 'application/json' } + + let(:headers) do + { 'Content-Type' => content_type } + end + + let(:json) do + { + id: 1, + '@context': ActivityPub::TagManager::CONTEXT, + type: 'Note', + }.to_json + end + + before do + stub_request(:get, url).to_return(status: 200, body: body, headers: headers) + end + + it 'signs request' do + subject + expect(a_request(:get, url).with(headers: { 'Signature' => /keyId="#{Regexp.escape(ActivityPub::TagManager.instance.uri_for(Account.representative) + '#main-key')}"/ })).to have_been_made + end + + context 'content_type is activity+json' do + let(:content_type) { 'application/activity+json; charset=utf-8' } + let(:body) { json } + + it { is_expected.to eq [1, { prefetched_body: body, id: true }] } + end + + context 'when content type is ld+json with profile' do + let(:content_type) { 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' } + let(:body) { json } + + it { is_expected.to eq [1, { prefetched_body: body, id: true }] } + end + + before do + stub_request(:get, url).to_return(status: 200, body: body, headers: headers) + stub_request(:get, 'http://example.com/foo').to_return(status: 200, body: json, headers: { 'Content-Type' => 'application/activity+json' }) + end + + context 'when link header is present' do + let(:headers) { { 'Link' => '; rel="alternate"; type="application/activity+json"', } } + + it { is_expected.to eq [1, { prefetched_body: json, id: true }] } + end + + context 'when content type is text/html' do + let(:content_type) { 'text/html' } + let(:body) { '' } + + it { is_expected.to eq [1, { prefetched_body: json, id: true }] } + end + end + end +end diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb index 35a5dbc51..c63907c1f 100644 --- a/spec/services/import_service_spec.rb +++ b/spec/services/import_service_spec.rb @@ -3,10 +3,10 @@ require 'rails_helper' RSpec.describe ImportService, type: :service do let!(:account) { Fabricate(:account, locked: false) } let!(:bob) { Fabricate(:account, username: 'bob', locked: false) } - let!(:foo) { Fabricate(:account, username: 'foo', domain: 'ap.example.com', inbox_url: 'https://ap.example.com/inbox', locked: false) } + let!(:eve) { Fabricate(:account, username: 'eve', domain: 'example.com', locked: false, inbox_url: 'https://example.com/inbox') } before do - stub_request(:post, "https://ap.example.com/inbox").to_return(:status => 200, :body => "", :headers => {}) + stub_request(:post, "https://example.com/inbox").to_return(status: 200) end context 'import old-style list of muted users' do @@ -96,6 +96,10 @@ RSpec.describe ImportService, type: :service do it 'follows the listed accounts, including boosts' do subject.call(import) expect(account.following.count).to eq 1 +<<<<<<< HEAD +======= + expect(account.follow_requests.count).to eq 1 +>>>>>>> f1597e1ab... Merge pull request #1158 from ThibG/glitch-soc/merge-upstream expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil end @@ -108,6 +112,10 @@ RSpec.describe ImportService, type: :service do account.follow!(bob, reblogs: false) subject.call(import) expect(account.following.count).to eq 1 +<<<<<<< HEAD +======= + expect(account.follow_requests.count).to eq 1 +>>>>>>> f1597e1ab... Merge pull request #1158 from ThibG/glitch-soc/merge-upstream expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil end @@ -120,6 +128,10 @@ RSpec.describe ImportService, type: :service do account.follow!(bob, reblogs: false) subject.call(import) expect(account.following.count).to eq 1 +<<<<<<< HEAD +======= + expect(account.follow_requests.count).to eq 1 +>>>>>>> f1597e1ab... Merge pull request #1158 from ThibG/glitch-soc/merge-upstream expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil end @@ -136,8 +148,14 @@ RSpec.describe ImportService, type: :service do it 'follows the listed accounts, respecting boosts' do subject.call(import) expect(account.following.count).to eq 1 +<<<<<<< HEAD expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil +======= + expect(account.follow_requests.count).to eq 1 + expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true + expect(FollowRequest.find_by(account: account, target_account: eve).show_reblogs).to be false +>>>>>>> f1597e1ab... Merge pull request #1158 from ThibG/glitch-soc/merge-upstream end end @@ -148,8 +166,14 @@ RSpec.describe ImportService, type: :service do account.follow!(bob, reblogs: true) subject.call(import) expect(account.following.count).to eq 1 +<<<<<<< HEAD expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil +======= + expect(account.follow_requests.count).to eq 1 + expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true + expect(FollowRequest.find_by(account: account, target_account: eve).show_reblogs).to be false +>>>>>>> f1597e1ab... Merge pull request #1158 from ThibG/glitch-soc/merge-upstream end end @@ -160,8 +184,14 @@ RSpec.describe ImportService, type: :service do account.follow!(bob, reblogs: true) subject.call(import) expect(account.following.count).to eq 1 +<<<<<<< HEAD expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil +======= + expect(account.follow_requests.count).to eq 1 + expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true + expect(FollowRequest.find_by(account: account, target_account: eve).show_reblogs).to be false +>>>>>>> f1597e1ab... Merge pull request #1158 from ThibG/glitch-soc/merge-upstream end end end diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index 709ec4497..9ecf3039f 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -6,19 +6,13 @@ RSpec.describe ResolveAccountService, type: :service do before do stub_request(:get, "https://quitter.no/.well-known/host-meta").to_return(request_fixture('.host-meta.txt')) stub_request(:get, "https://example.com/.well-known/webfinger?resource=acct:catsrgr8@example.com").to_return(status: 404) - stub_request(:get, "https://redirected.com/.well-known/host-meta").to_return(request_fixture('redirected.host-meta.txt')) stub_request(:get, "https://example.com/.well-known/host-meta").to_return(status: 404) - stub_request(:get, "https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no").to_return(request_fixture('webfinger.txt')) - stub_request(:get, "https://redirected.com/.well-known/webfinger?resource=acct:gargron@redirected.com").to_return(request_fixture('webfinger.txt')) - stub_request(:get, "https://redirected.com/.well-known/webfinger?resource=acct:hacker1@redirected.com").to_return(request_fixture('webfinger-hacker1.txt')) - stub_request(:get, "https://redirected.com/.well-known/webfinger?resource=acct:hacker2@redirected.com").to_return(request_fixture('webfinger-hacker2.txt')) - stub_request(:get, "https://quitter.no/.well-known/webfinger?resource=acct:catsrgr8@quitter.no").to_return(status: 404) - stub_request(:get, "https://quitter.no/api/statuses/user_timeline/7477.atom").to_return(request_fixture('feed.txt')) stub_request(:get, "https://quitter.no/avatar/7477-300-20160211190340.png").to_return(request_fixture('avatar.txt')) stub_request(:get, "https://localdomain.com/.well-known/host-meta").to_return(request_fixture('localdomain-hostmeta.txt')) stub_request(:get, "https://localdomain.com/.well-known/webfinger?resource=acct:foo@localdomain.com").to_return(status: 404) stub_request(:get, "https://webdomain.com/.well-known/webfinger?resource=acct:foo@localdomain.com").to_return(request_fixture('localdomain-webfinger.txt')) stub_request(:get, "https://webdomain.com/users/foo.atom").to_return(request_fixture('localdomain-feed.txt')) + stub_request(:get, "https://quitter.no/.well-known/webfinger?resource=acct:catsrgr8@quitter.no").to_return(status: 404) stub_request(:get, "https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com").to_return(request_fixture('activitypub-webfinger.txt')) stub_request(:get, "https://ap.example.com/users/foo").to_return(request_fixture('activitypub-actor.txt')) stub_request(:get, "https://ap.example.com/users/foo.atom").to_return(request_fixture('activitypub-feed.txt')) @@ -33,15 +27,6 @@ RSpec.describe ResolveAccountService, type: :service do expect(subject.call('catsrgr8@example.com')).to be_nil end - #it 'prevents hijacking existing accounts' do - # account = subject.call('hacker1@redirected.com') - # expect(account.salmon_url).to_not eq 'https://hacker.com/main/salmon/user/7477' - #end - - it 'prevents hijacking inexisting accounts' do - expect(subject.call('hacker2@redirected.com')).to be_nil - end - context 'with an ActivityPub account' do it 'returns new remote account' do account = subject.call('foo@ap.example.com') @@ -68,11 +53,17 @@ RSpec.describe ResolveAccountService, type: :service do it 'processes one remote account at a time using locks' do wait_for_start = true fail_occurred = false - return_values = [] + return_values = Concurrent::Array.new + + # Preload classes that throw circular dependency errors in threads + Account + TagManager + DomainBlock threads = Array.new(5) do Thread.new do true while wait_for_start + begin return_values << described_class.new.call('foo@ap.example.com') rescue ActiveRecord::RecordNotUnique diff --git a/spec/services/resolve_url_service_spec.rb b/spec/services/resolve_url_service_spec.rb index 7bb5d1940..aa4204637 100644 --- a/spec/services/resolve_url_service_spec.rb +++ b/spec/services/resolve_url_service_spec.rb @@ -6,48 +6,14 @@ describe ResolveURLService, type: :service do subject { described_class.new } describe '#call' do - it 'returns nil when there is no atom url' do - url = 'http://example.com/missing-atom' + it 'returns nil when there is no resource url' do + url = 'http://example.com/missing-resource' service = double - allow(FetchAtomService).to receive(:new).and_return service - allow(service).to receive(:call).with(url).and_return(nil) - - result = subject.call(url) - expect(result).to be_nil - end - - it 'fetches remote accounts for feed types' do - url = 'http://example.com/atom-feed' - service = double - allow(FetchAtomService).to receive(:new).and_return service - feed_url = 'http://feed-url' - feed_content = 'contents' - allow(service).to receive(:call).with(url).and_return([feed_url, { prefetched_body: feed_content }]) - - account_service = double - allow(FetchRemoteAccountService).to receive(:new).and_return(account_service) - allow(account_service).to receive(:call) - - _result = subject.call(url) - expect(account_service).to have_received(:call).with(feed_url, feed_content, nil) - end - - it 'fetches remote statuses for entry types' do - url = 'http://example.com/atom-entry' - service = double - allow(FetchAtomService).to receive(:new).and_return service - feed_url = 'http://feed-url' - feed_content = 'contents' - allow(service).to receive(:call).with(url).and_return([feed_url, { prefetched_body: feed_content }]) - - account_service = double - allow(FetchRemoteStatusService).to receive(:new).and_return(account_service) - allow(account_service).to receive(:call) - - _result = subject.call(url) + allow(FetchResourceService).to receive(:new).and_return service + allow(service).to receive(:call).with(url).and_return(nil) - expect(account_service).to have_received(:call).with(feed_url, feed_content, nil) + expect(subject.call(url)).to be_nil end end end diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb index 98a224b04..80379829c 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -26,7 +26,6 @@ RSpec.describe SuspendAccountService, type: :service do [ account.statuses, account.media_attachments, - account.stream_entries, account.notifications, account.favourites, account.active_relationships, @@ -67,7 +66,6 @@ RSpec.describe SuspendAccountService, type: :service do [ remote_bob.statuses, remote_bob.media_attachments, - remote_bob.stream_entries, remote_bob.notifications, remote_bob.favourites, remote_bob.active_relationships, -- cgit