Second round of Rspec fixes.

master
multiple creatures 2019-05-09 09:40:09 -05:00
parent 66886d4367
commit e85b8af051
43 changed files with 109 additions and 384 deletions

View File

@ -0,0 +1,5 @@
class DefaultProtocolToActivityPub < ActiveRecord::Migration[5.2]
def change
change_column_default :accounts, :protocol, 1
end
end

View File

@ -0,0 +1,5 @@
class RemoveProtocolFromAccounts < ActiveRecord::Migration[5.2]
def change
safety_assured { remove_column :accounts, :protocol }
end
end

View File

@ -75,44 +75,6 @@ RSpec.describe Admin::AccountsController, type: :controller do
end
end
describe 'POST #subscribe' do
subject { post :subscribe, params: { id: account.id } }
let(:current_user) { Fabricate(:user, admin: admin) }
let(:account) { Fabricate(:account) }
context 'when user is admin' do
let(:admin) { true }
it { is_expected.to redirect_to admin_account_path(account.id) }
end
context 'when user is not admin' do
let(:admin) { false }
it { is_expected.to have_http_status :forbidden }
end
end
describe 'POST #unsubscribe' do
subject { post :unsubscribe, params: { id: account.id } }
let(:current_user) { Fabricate(:user, admin: admin) }
let(:account) { Fabricate(:account) }
context 'when user is admin' do
let(:admin) { true }
it { is_expected.to redirect_to admin_account_path(account.id) }
end
context 'when user is not admin' do
let(:admin) { false }
it { is_expected.to have_http_status :forbidden }
end
end
describe 'POST #memorialize' do
subject { post :memorialize, params: { id: account.id } }

View File

@ -35,14 +35,6 @@ RSpec.describe Api::V1::FollowsController, type: :controller do
expect(user.account.following?(Account.find_by(username: 'gargron', domain: 'quitter.no'))).to be true
end
it 'sends a salmon slap to the remote user' do
expect(a_request(:post, "https://quitter.no/main/salmon/user/7477")).to have_been_made
end
it 'subscribes to remote hub' do
expect(a_request(:post, "https://quitter.no/main/push/hub")).to have_been_made
end
it 'returns http success if already following, too' do
post :create, params: { uri: 'gargron@quitter.no' }
expect(response).to have_http_status(200)

View File

@ -41,7 +41,7 @@ describe ApplicationController, type: :controller do
it 'sets link headers' do
account = Fabricate(:account, username: 'username', user: Fabricate(:user))
get 'success', params: { account_username: 'username' }
expect(response.headers['Link'].to_s).to eq '<http://test.host/.well-known/webfinger?resource=acct%3Ausername%40cb6e6126.ngrok.io>; rel="lrdd"; type="application/xrd+xml", <http://test.host/users/username.atom>; rel="alternate"; type="application/atom+xml", <https://cb6e6126.ngrok.io/users/username>; rel="alternate"; type="application/activity+json"'
expect(response.headers['Link'].to_s).to eq '<http://test.host/.well-known/webfinger?resource=acct%3Ausername%40cb6e6126.ngrok.io>; rel="lrdd"; type="application/xrd+xml", <https://cb6e6126.ngrok.io/users/username>; rel="alternate"; type="application/activity+json"'
end
it 'returns http success' do

View File

@ -36,10 +36,10 @@ describe RelationshipsController do
end
describe 'PATCH #update' do
let(:poopfeast) { Fabricate(:account, username: 'poopfeast', domain: 'example.com', salmon_url: 'http://example.com/salmon') }
let(:poopfeast) { Fabricate(:account, username: 'poopfeast', domain: 'example.com', inbox_url: 'http://example.com/inbox') }
before do
stub_request(:post, 'http://example.com/salmon').to_return(status: 200)
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
end
shared_examples 'redirects back to followers page' do

View File

@ -10,7 +10,7 @@ describe RemoteUnfollowsController do
let(:current_user) { Fabricate(:user, account: current_account) }
let(:current_account) { Fabricate(:account) }
let(:remote_account) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
let(:remote_account) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
before do
sign_in current_user
current_account.follow!(remote_account)

View File

@ -1,4 +1,4 @@
bob
eve@example.com
foo@ap.example.com

View File

@ -1,4 +1,4 @@
Account address,Show boosts
bob,true
eve@example.com,false
foo@ap.example.com,false

View File

@ -1,4 +1,4 @@
Account address,Hide notifications
bob,true
eve@example.com,false
foo@ap.example.com,false

View File

@ -14,6 +14,7 @@ Strict-Transport-Security: max-age=31536000; includeSubdomains;
<Alias>https://webdomain.com/@foo</Alias>
<Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="https://webdomain.com/@foo"/>
<Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="https://webdomain.com/users/foo.atom"/>
<Link rel="self" type="application/activity+json" href="https://webdomain.com/users/foo"/>
<Link rel="salmon" href="https://webdomain.com/api/salmon/1"/>
<Link rel="magic-public-key" href="data:application/magic-public-key,RSA.wnIYUQp-jMqH8tzStBoVriiGtbMvH12IU125p-3shZHxJNDi7RHwseKi5ADEGwGwpXLMxqiyNlgCff1hG9DBc8MzHZi1V93F2hCOXK0bqZm2lbsWfjkpsDIdBZ8TltwSejuQCt_rqL-K5XCfknd94P7tHOCBnizQRBanj0IdcSSqh7CmRS5wa1UjwflXVMsgbDc2io1knMeMkXsl0jzwt-CFHprmITzWy9X6Ia4QevkntiXdMlwUf_UoJC7BRns-J-j_dz2LqFl1QfspMhR2R9p8plDSD-jjk8DUVSBFZ7GLWVHEd6dWkLncEVEeRLliCaQQBqF1huSuMDtYWfukWQ==.AQAB"/>
<Link rel="http://ostatus.org/schema/1.0/subscribe" template="https://webdomain.com/authorize_follow?acct={uri}"/>

View File

@ -1,7 +1,7 @@
require 'rails_helper'
RSpec.describe ActivityPub::Activity::Create do
let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers', domain: 'example.com', uri: 'https://example.com/actor') }
let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers', domain: 'example.com', uri: 'https://example.com/actor', inbox_url: 'https://example.com/inbox') }
let(:json) do
{
@ -18,6 +18,7 @@ RSpec.describe ActivityPub::Activity::Create do
stub_request(:get, 'http://example.com/attachment.png').to_return(request_fixture('avatar.txt'))
stub_request(:get, 'http://example.com/emoji.png').to_return(body: attachment_fixture('emojo.png'))
stub_request(:post, 'https://example.com/inbox')
end
describe '#perform' do

View File

@ -31,7 +31,7 @@ RSpec.describe ActivityPub::Activity::Delete do
describe '#perform' do
subject { described_class.new(json, sender) }
let!(:reblogger) { Fabricate(:account) }
let!(:follower) { Fabricate(:account, username: 'follower', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let!(:follower) { Fabricate(:account, username: 'follower', domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let!(:reblog) { Fabricate(:status, account: reblogger, reblog: status) }
before do

View File

@ -8,8 +8,8 @@ RSpec.describe ActivityPub::Activity::Move do
before do
follower.follow!(old_account)
old_account.update!(uri: 'https://example.org/alice', domain: 'example.org', protocol: :activitypub, inbox_url: 'https://example.org/inbox')
new_account.update!(uri: 'https://example.com/alice', domain: 'example.com', protocol: :activitypub, inbox_url: 'https://example.com/inbox', also_known_as: [old_account.uri])
old_account.update!(uri: 'https://example.org/alice', domain: 'example.org', inbox_url: 'https://example.org/inbox')
new_account.update!(uri: 'https://example.com/alice', domain: 'example.com', inbox_url: 'https://example.com/inbox', also_known_as: [old_account.uri])
stub_request(:post, 'https://example.org/inbox').to_return(status: 200)
stub_request(:post, 'https://example.com/inbox').to_return(status: 200)

View File

@ -22,9 +22,13 @@ RSpec.describe FeedManager do
describe '#filter?' do
let(:alice) { Fabricate(:account, username: 'alice') }
let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') }
let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'https://example.com/inbox') }
let(:jeff) { Fabricate(:account, username: 'jeff') }
before do
stub_request(:post, bob.inbox_url)
end
context 'for home feed' do
it 'returns false for followee\'s status' do
status = Fabricate(:status, text: 'Hello world', account: alice)

View File

@ -379,10 +379,10 @@ RSpec.describe Account, type: :model do
expect(results).to eq [match]
end
it 'limits by 10 by default' do
11.times.each { Fabricate(:account, display_name: "Display Name") }
it 'limits by 15 by default' do
16.times.each { Fabricate(:account, display_name: "Display Name") }
results = Account.search_for("display")
expect(results.size).to eq 10
expect(results.size).to eq 15
end
it 'accepts arbitrary limits' do
@ -582,20 +582,20 @@ RSpec.describe Account, type: :model do
expect(account).to model_have_error_on_field(:username)
end
it 'is invalid if the username is longer then 30 characters' do
account = Fabricate.build(:account, username: Faker::Lorem.characters(31))
it 'is invalid if the username is longer then 66 characters' do
account = Fabricate.build(:account, username: Faker::Lorem.characters(67))
account.valid?
expect(account).to model_have_error_on_field(:username)
end
it 'is invalid if the display name is longer than 30 characters' do
account = Fabricate.build(:account, display_name: Faker::Lorem.characters(31))
it 'is invalid if the display name is longer than 66 characters' do
account = Fabricate.build(:account, display_name: Faker::Lorem.characters(67))
account.valid?
expect(account).to model_have_error_on_field(:display_name)
end
it 'is invalid if the note is longer than 500 characters' do
account = Fabricate.build(:account, note: Faker::Lorem.characters(501))
it 'is invalid if the note is longer than 6666 characters' do
account = Fabricate.build(:account, note: Faker::Lorem.characters(6667))
account.valid?
expect(account).to model_have_error_on_field(:note)
end

View File

@ -124,8 +124,8 @@ describe Report do
expect(report).to be_valid
end
it 'is invalid if comment is longer than 1000 characters' do
report = Fabricate.build(:report, comment: Faker::Lorem.characters(1001))
it 'is invalid if comment is longer than 6666 characters' do
report = Fabricate.build(:report, comment: Faker::Lorem.characters(6667))
report.valid?
expect(report).to model_have_error_on_field(:comment)
end

View File

@ -17,13 +17,6 @@ describe 'Link headers' do
expect(link_header.attr_pairs.first).to eq %w(rel lrdd)
end
it 'contains atom url in link header' do
link_header = link_header_with_type('application/atom+xml')
expect(link_header.href).to eq 'http://www.example.com/users/test.atom'
expect(link_header.attr_pairs.first).to eq %w(rel alternate)
end
def link_header_with_type(type)
response.headers['Link'].links.find do |link|
link.attr_pairs.any? { |pair| pair == ['type', type] }

View File

@ -12,23 +12,6 @@ describe 'The webfinger route' do
end
end
describe 'asking for xml format' do
it 'returns an xml response for xml format' do
get webfinger_url(resource: alice.to_webfinger_s, format: :xml)
expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/xrd+xml'
end
it 'returns an xml response for xml accept header' do
headers = { 'HTTP_ACCEPT' => 'application/xrd+xml' }
get webfinger_url(resource: alice.to_webfinger_s), headers: headers
expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/xrd+xml'
end
end
describe 'asking for json format' do
it 'returns a json response for json format' do
get webfinger_url(resource: alice.to_webfinger_s, format: :json)

View File

@ -1,7 +1,7 @@
require 'rails_helper'
RSpec.describe AfterBlockDomainFromAccountService, type: :service do
let!(:wolf) { Fabricate(:account, username: 'wolf', domain: 'evil.org', inbox_url: 'https://evil.org/inbox', protocol: :activitypub) }
let!(:wolf) { Fabricate(:account, username: 'wolf', domain: 'evil.org', inbox_url: 'https://evil.org/inbox') }
let!(:alice) { Fabricate(:account, username: 'alice') }
subject { AfterBlockDomainFromAccountService.new }

View File

@ -23,7 +23,7 @@ RSpec.describe AuthorizeFollowService, type: :service do
end
describe 'remote ActivityPub' do
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox')).account }
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
before do
FollowRequest.create(account: bob, target_account: sender)

View File

@ -4,8 +4,9 @@ RSpec.describe BatchedRemoveStatusService, type: :service do
subject { BatchedRemoveStatusService.new }
let!(:alice) { Fabricate(:account) }
let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let!(:jeff) { Fabricate(:user).account }
let!(:hank) { Fabricate(:account, username: 'hank', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let!(:hank) { Fabricate(:account, username: 'hank', domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let(:status1) { PostStatusService.new.call(alice, text: 'Hello @bob@example.com') }
let(:status2) { PostStatusService.new.call(alice, text: 'Another status') }

View File

@ -17,28 +17,8 @@ RSpec.describe BlockService, type: :service do
end
end
describe 'remote OStatus' 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(OStatus::TagManager::VERBS[:block])
}).to have_been_made.once
end
end
describe 'remote ActivityPub' do
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
before do
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)

View File

@ -19,7 +19,7 @@ RSpec.describe FavouriteService, type: :service do
end
describe 'remote ActivityPub' do
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, protocol: :activitypub, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
let(:status) { Fabricate(:status, account: bob) }
before do

View File

@ -97,7 +97,7 @@ RSpec.describe FollowService, type: :service do
end
context 'remote ActivityPub account' do
let(:bob) { Fabricate(:user, account: Fabricate(:account, username: 'bob', domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox')).account }
let(:bob) { Fabricate(:user, account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
before do
stub_request(:post, "http://example.com/inbox").to_return(:status => 200, :body => "", :headers => {})

View File

@ -3,7 +3,11 @@ require 'rails_helper'
RSpec.describe ImportService, type: :service do
let!(:account) { Fabricate(:account, locked: false) }
let!(:bob) { Fabricate(:account, username: 'bob', locked: false) }
let!(:eve) { Fabricate(:account, username: 'eve', domain: 'example.com', locked: false) }
let!(:foo) { Fabricate(:account, username: 'foo', domain: 'ap.example.com', inbox_url: 'https://ap.example.com/inbox', locked: false) }
before do
stub_request(:post, "https://ap.example.com/inbox").to_return(:status => 200, :body => "", :headers => {})
end
context 'import old-style list of muted users' do
subject { ImportService.new }
@ -53,7 +57,7 @@ RSpec.describe ImportService, type: :service do
subject.call(import)
expect(account.muting.count).to eq 2
expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
expect(Mute.find_by(account: account, target_account: eve).hide_notifications).to be false
expect(Mute.find_by(account: account, target_account: foo).hide_notifications).to be false
end
end
@ -65,7 +69,7 @@ RSpec.describe ImportService, type: :service do
subject.call(import)
expect(account.muting.count).to eq 2
expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
expect(Mute.find_by(account: account, target_account: eve).hide_notifications).to be false
expect(Mute.find_by(account: account, target_account: foo).hide_notifications).to be false
end
end
@ -77,7 +81,7 @@ RSpec.describe ImportService, type: :service do
subject.call(import)
expect(account.muting.count).to eq 2
expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
expect(Mute.find_by(account: account, target_account: eve).hide_notifications).to be false
expect(Mute.find_by(account: account, target_account: foo).hide_notifications).to be false
end
end
end
@ -87,16 +91,13 @@ RSpec.describe ImportService, type: :service do
let(:csv) { attachment_fixture('mute-imports.txt') }
before do
allow(NotificationWorker).to receive(:perform_async)
end
describe 'when no accounts are followed' do
let(:import) { Import.create(account: account, type: 'following', data: csv) }
it 'follows the listed accounts, including boosts' do
subject.call(import)
expect(account.following.count).to eq 2
expect(account.following.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: foo)).to_not be_nil
end
end
@ -106,8 +107,9 @@ RSpec.describe ImportService, type: :service do
it 'follows the listed accounts, including notifications' do
account.follow!(bob, reblogs: false)
subject.call(import)
expect(account.following.count).to eq 2
expect(account.following.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: foo)).to_not be_nil
end
end
@ -117,8 +119,9 @@ RSpec.describe ImportService, type: :service do
it 'mutes the listed accounts, including notifications' do
account.follow!(bob, reblogs: false)
subject.call(import)
expect(account.following.count).to eq 2
expect(account.following.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: foo)).to_not be_nil
end
end
end
@ -128,17 +131,13 @@ RSpec.describe ImportService, type: :service do
let(:csv) { attachment_fixture('new-following-imports.txt') }
before do
allow(NotificationWorker).to receive(:perform_async)
end
describe 'when no accounts are followed' do
let(:import) { Import.create(account: account, type: 'following', data: csv) }
it 'follows the listed accounts, respecting boosts' do
subject.call(import)
expect(account.following.count).to eq 2
expect(account.following.count).to eq 1
expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
expect(Follow.find_by(account: account, target_account: eve).show_reblogs).to be false
expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil
end
end
@ -148,9 +147,9 @@ RSpec.describe ImportService, type: :service do
it 'mutes the listed accounts, respecting notifications' do
account.follow!(bob, reblogs: true)
subject.call(import)
expect(account.following.count).to eq 2
expect(account.following.count).to eq 1
expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
expect(Follow.find_by(account: account, target_account: eve).show_reblogs).to be false
expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil
end
end
@ -160,9 +159,9 @@ RSpec.describe ImportService, type: :service do
it 'mutes the listed accounts, respecting notifications' do
account.follow!(bob, reblogs: true)
subject.call(import)
expect(account.following.count).to eq 2
expect(account.following.count).to eq 1
expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
expect(Follow.find_by(account: account, target_account: eve).show_reblogs).to be false
expect(FollowRequest.find_by(account: account, target_account: foo)).to_not be_nil
end
end
end

View File

@ -139,12 +139,11 @@ RSpec.describe PostStatusService, type: :service do
status = subject.call(account, text: "test status update")
expect(ProcessHashtagsService).to have_received(:new)
expect(hashtags_service).to have_received(:call).with(status)
expect(hashtags_service).to have_received(:call).with(status, nil)
end
it 'gets distributed' do
allow(DistributionWorker).to receive(:perform_async)
allow(Pubsubhubbub::DistributionWorker).to receive(:perform_async)
allow(ActivityPub::DistributionWorker).to receive(:perform_async)
account = Fabricate(:account)
@ -152,7 +151,6 @@ RSpec.describe PostStatusService, type: :service do
status = subject.call(account, text: "test status update")
expect(DistributionWorker).to have_received(:perform_async).with(status.id)
expect(Pubsubhubbub::DistributionWorker).to have_received(:perform_async).with(status.stream_entry.id)
expect(ActivityPub::DistributionWorker).to have_received(:perform_async).with(status.id)
end
@ -191,7 +189,7 @@ RSpec.describe PostStatusService, type: :service do
expect(media.reload.status).to eq nil
end
it 'does not allow attaching more than 4 files' do
it 'does not allow attaching more than 6 files' do
account = Fabricate(:account)
expect do
@ -204,6 +202,8 @@ RSpec.describe PostStatusService, type: :service do
Fabricate(:media_attachment, account: account),
Fabricate(:media_attachment, account: account),
Fabricate(:media_attachment, account: account),
Fabricate(:media_attachment, account: account),
Fabricate(:media_attachment, account: account),
].map(&:id),
)
end.to raise_error(

View File

@ -6,7 +6,7 @@ RSpec.describe ProcessMentionsService, type: :service do
let(:status) { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct}", visibility: visibility) }
context 'ActivityPub' do
let(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let(:remote_user) { Fabricate(:account, username: 'remote_user', domain: 'example.com', inbox_url: 'http://example.com/inbox') }
subject { ProcessMentionsService.new }
@ -25,7 +25,7 @@ RSpec.describe ProcessMentionsService, type: :service do
end
context 'Temporarily-unreachable ActivityPub user' do
let(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox', last_webfingered_at: nil) }
let(:remote_user) { Fabricate(:account, username: 'remote_user', domain: 'example.com', inbox_url: 'http://example.com/inbox', last_webfingered_at: nil) }
subject { ProcessMentionsService.new }

View File

@ -1,71 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
describe Pubsubhubbub::SubscribeService, type: :service do
describe '#call' do
subject { described_class.new }
let(:user_account) { Fabricate(:account) }
context 'with a nil account' do
it 'returns the invalid topic status results' do
result = service_call(account: nil)
expect(result).to eq invalid_topic_status
end
end
context 'with an invalid callback url' do
it 'returns invalid callback status when callback is blank' do
result = service_call(callback: '')
expect(result).to eq invalid_callback_status
end
it 'returns invalid callback status when callback is not a URI' do
result = service_call(callback: 'invalid-hostname')
expect(result).to eq invalid_callback_status
end
end
context 'with a blocked domain in the callback' do
it 'returns callback not allowed' do
Fabricate(:domain_block, domain: 'test.host', severity: :suspend)
result = service_call(callback: 'https://test.host/api')
expect(result).to eq not_allowed_callback_status
end
end
context 'with a valid account and callback' do
it 'returns success status and confirms subscription' do
allow(Pubsubhubbub::ConfirmationWorker).to receive(:perform_async).and_return(nil)
subscription = Fabricate(:subscription, account: user_account)
result = service_call(callback: subscription.callback_url)
expect(result).to eq success_status
expect(Pubsubhubbub::ConfirmationWorker).to have_received(:perform_async).with(subscription.id, 'subscribe', 'asdf', 3600)
end
end
end
def service_call(account: user_account, callback: 'https://callback.host', secret: 'asdf', lease_seconds: 3600)
subject.call(account, callback, secret, lease_seconds)
end
def invalid_topic_status
['Invalid topic URL', 422]
end
def invalid_callback_status
['Invalid callback URL', 422]
end
def not_allowed_callback_status
['Callback URL not allowed', 403]
end
def success_status
['', 202]
end
end

View File

@ -1,46 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
describe Pubsubhubbub::UnsubscribeService, type: :service do
describe '#call' do
subject { described_class.new }
context 'with a nil account' do
it 'returns an invalid topic status' do
result = subject.call(nil, 'callback.host')
expect(result).to eq invalid_topic_status
end
end
context 'with a valid account' do
let(:account) { Fabricate(:account) }
it 'returns a valid topic status and does not run confirm when no subscription' do
allow(Pubsubhubbub::ConfirmationWorker).to receive(:perform_async).and_return(nil)
result = subject.call(account, 'callback.host')
expect(result).to eq valid_topic_status
expect(Pubsubhubbub::ConfirmationWorker).not_to have_received(:perform_async)
end
it 'returns a valid topic status and does run confirm when there is a subscription' do
subscription = Fabricate(:subscription, account: account, callback_url: 'callback.host')
allow(Pubsubhubbub::ConfirmationWorker).to receive(:perform_async).and_return(nil)
result = subject.call(account, 'callback.host')
expect(result).to eq valid_topic_status
expect(Pubsubhubbub::ConfirmationWorker).to have_received(:perform_async).with(subscription.id, 'unsubscribe')
end
end
def invalid_topic_status
['Invalid topic URL', 422]
end
def valid_topic_status
['', 202]
end
end
end

View File

@ -33,7 +33,7 @@ RSpec.describe ReblogService, type: :service do
end
context 'ActivityPub' do
let(:bob) { Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let(:status) { Fabricate(:status, account: bob) }
subject { ReblogService.new }

View File

@ -23,7 +23,7 @@ RSpec.describe RejectFollowService, type: :service do
end
describe 'remote ActivityPub' do
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox')).account }
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
before do
FollowRequest.create(account: bob, target_account: sender)

View File

@ -4,9 +4,10 @@ RSpec.describe RemoveStatusService, type: :service do
subject { RemoveStatusService.new }
let!(:alice) { Fabricate(:account) }
let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://example.com/salmon') }
let!(:jeff) { Fabricate(:account) }
let!(:hank) { Fabricate(:account, username: 'hank', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let!(:bill) { Fabricate(:account, username: 'bill', protocol: :activitypub, domain: 'example2.com', inbox_url: 'http://example2.com/inbox') }
let!(:hank) { Fabricate(:account, username: 'hank', domain: 'example.com', inbox_url: 'http://example.com/inbox') }
let!(:bill) { Fabricate(:account, username: 'bill', domain: 'example2.com', inbox_url: 'http://example2.com/inbox') }
before do
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)

View File

@ -6,7 +6,7 @@ RSpec.describe ReportService, type: :service do
let(:source_account) { Fabricate(:user).account }
context 'for a remote account' do
let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
let(:remote_account) { Fabricate(:account, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
before do
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)

View File

@ -19,6 +19,10 @@ RSpec.describe ResolveAccountService, type: :service do
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://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'))
stub_request(:get, %r{https://ap.example.com/users/foo/\w+}).to_return(status: 404)
end
it 'raises error if no such user can be resolved via webfinger' do
@ -29,27 +33,19 @@ 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 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
before do
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'))
stub_request(:get, %r{https://ap.example.com/users/foo/\w+}).to_return(status: 404)
end
it 'returns new remote account' do
account = subject.call('foo@ap.example.com')
expect(account.activitypub?).to eq true
expect(account.domain).to eq 'ap.example.com'
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
end
@ -62,7 +58,6 @@ RSpec.describe ResolveAccountService, type: :service do
it 'returns new remote account' do
account = subject.call('foo@ap.example.com')
expect(account.activitypub?).to eq true
expect(account.domain).to eq 'ap.example.com'
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
expect(account.actor_type).to eq 'Person'
@ -79,7 +74,7 @@ RSpec.describe ResolveAccountService, type: :service do
Thread.new do
true while wait_for_start
begin
return_values << described_class.new.call('foo@localdomain.com')
return_values << described_class.new.call('foo@ap.example.com')
rescue ActiveRecord::RecordNotUnique
fail_occurred = true
end

View File

@ -1,43 +0,0 @@
require 'rails_helper'
RSpec.describe SubscribeService, type: :service do
let(:account) { Fabricate(:account, username: 'bob', domain: 'example.com', hub_url: 'http://hub.example.com') }
subject { SubscribeService.new }
it 'sends subscription request to PuSH hub' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 202)
subject.call(account)
expect(a_request(:post, 'http://hub.example.com/')).to have_been_made.once
end
it 'generates and keeps PuSH secret on successful call' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 202)
subject.call(account)
expect(account.secret).to_not be_blank
end
it 'fails silently if PuSH hub forbids subscription' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 403)
subject.call(account)
end
it 'fails silently if PuSH hub is not found' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 404)
subject.call(account)
end
it 'fails loudly if there is a network error' do
stub_request(:post, 'http://hub.example.com/').to_raise(HTTP::Error)
expect { subject.call(account) }.to raise_error HTTP::Error
end
it 'fails loudly if PuSH hub is unavailable' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 503)
expect { subject.call(account) }.to raise_error Mastodon::UnexpectedResponseError
end
it 'fails loudly if rate limited' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 429)
expect { subject.call(account) }.to raise_error Mastodon::UnexpectedResponseError
end
end

View File

@ -19,8 +19,8 @@ RSpec.describe SuspendAccountService, type: :service do
let!(:active_relationship) { Fabricate(:follow, account: account) }
let!(:passive_relationship) { Fabricate(:follow, target_account: account) }
let!(:subscription) { Fabricate(:subscription, account: account) }
let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) }
let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox') }
let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox') }
it 'deletes associated records' do
is_expected.to change {
@ -55,8 +55,8 @@ RSpec.describe SuspendAccountService, type: :service do
end
let!(:account) { Fabricate(:account) }
let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) }
let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox') }
let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox') }
let!(:status) { Fabricate(:status, account: remote_bob) }
let!(:media_attachment) { Fabricate(:media_attachment, account: remote_bob) }
let!(:notification) { Fabricate(:notification, account: remote_bob) }
@ -77,7 +77,7 @@ RSpec.describe SuspendAccountService, type: :service do
remote_bob.passive_relationships,
remote_bob.subscriptions
].map(&:count)
}.from([1, 1, 1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0, 0, 0])
}.from([1, 1, 0, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0, 0, 0])
end
it 'sends a reject follow to follwer inboxes' do

View File

@ -19,7 +19,7 @@ RSpec.describe UnblockService, type: :service do
end
describe 'remote ActivityPub' do
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
before do
sender.block!(bob)

View File

@ -19,7 +19,7 @@ RSpec.describe UnfollowService, type: :service do
end
describe 'remote ActivityPub' do
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
before do
sender.follow!(bob)
@ -37,7 +37,7 @@ RSpec.describe UnfollowService, type: :service do
end
describe 'remote ActivityPub (reverse)' do
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
before do
bob.follow!(sender)

View File

@ -1,37 +0,0 @@
require 'rails_helper'
RSpec.describe UnsubscribeService, type: :service do
let(:account) { Fabricate(:account, username: 'bob', domain: 'example.com', hub_url: 'http://hub.example.com') }
subject { UnsubscribeService.new }
it 'removes the secret and resets expiration on account' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 204)
subject.call(account)
account.reload
expect(account.secret).to be_blank
expect(account.subscription_expires_at).to be_blank
end
it 'logs error on subscription failure' do
logger = stub_logger
stub_request(:post, 'http://hub.example.com/').to_return(status: 404)
subject.call(account)
expect(logger).to have_received(:debug).with(/unsubscribe for bob@example.com failed/)
end
it 'logs error on connection failure' do
logger = stub_logger
stub_request(:post, 'http://hub.example.com/').to_raise(HTTP::Error)
subject.call(account)
expect(logger).to have_received(:debug).with(/unsubscribe for bob@example.com failed/)
end
def stub_logger
double(debug: nil).tap do |logger|
allow(Rails).to receive(:logger).and_return(logger)
end
end
end

View File

@ -3,12 +3,12 @@
shared_examples 'ScopedSettings' do
describe '[]' do
it 'inherits default settings' do
expect(Setting.boost_modal).to eq false
expect(Setting.boost_modal).to eq true
expect(Setting.interactions['must_be_follower']).to eq false
settings = create!
expect(settings['boost_modal']).to eq false
expect(settings['boost_modal']).to eq true
expect(settings['interactions']['must_be_follower']).to eq false
end
end
@ -17,15 +17,15 @@ shared_examples 'ScopedSettings' do
# expecting [] and []= works
it 'returns records merged with default values except hashes' do
expect(Setting.boost_modal).to eq false
expect(Setting.boost_modal).to eq true
expect(Setting.delete_modal).to eq true
settings = create!
settings['boost_modal'] = true
settings['boost_modal'] = false
records = settings.all_as_records
expect(records['boost_modal'].value).to eq true
expect(records['boost_modal'].value).to eq false
expect(records['delete_modal'].value).to eq true
end
end
@ -34,32 +34,32 @@ shared_examples 'ScopedSettings' do
# expecting [] and []= works.
it 'reads settings' do
expect(Setting.boost_modal).to eq false
expect(Setting.boost_modal).to eq true
settings = create!
expect(settings.boost_modal).to eq false
expect(settings.boost_modal).to eq true
end
it 'updates settings' do
settings = fabricate
settings.boost_modal = true
expect(settings['boost_modal']).to eq true
settings.boost_modal = false
expect(settings['boost_modal']).to eq false
end
end
it 'can update settings with [] and can read with []=' do
settings = fabricate
settings['boost_modal'] = true
settings['boost_modal'] = false
settings['interactions'] = settings['interactions'].merge('must_be_follower' => true)
Setting.save!
expect(settings['boost_modal']).to eq true
expect(settings['boost_modal']).to eq false
expect(settings['interactions']['must_be_follower']).to eq true
Rails.cache.clear
expect(settings['boost_modal']).to eq true
expect(settings['boost_modal']).to eq false
expect(settings['interactions']['must_be_follower']).to eq true
end

View File

@ -4,7 +4,7 @@ describe ActivityPub::DistributionWorker do
subject { described_class.new }
let(:status) { Fabricate(:status) }
let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') }
let(:follower) { Fabricate(:account, inbox_url: 'http://example.com') }
describe '#perform' do
before do

View File

@ -4,7 +4,7 @@ describe ActivityPub::UpdateDistributionWorker do
subject { described_class.new }
let(:account) { Fabricate(:account) }
let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') }
let(:follower) { Fabricate(:account, inbox_url: 'http://example.com') }
describe '#perform' do
before do