Merge branch 'stable-4.3' into glitch-soc/backports-4.3
commit
94c69bba25
|
@ -1,7 +1,6 @@
|
||||||
name: Crowdin / Upload translations
|
name: Crowdin / Upload translations
|
||||||
|
|
||||||
on:
|
on:
|
||||||
merge_group:
|
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'main'
|
- 'main'
|
||||||
|
|
|
@ -85,6 +85,7 @@
|
||||||
"alert.rate_limited.title": "Ліміт перавышаны",
|
"alert.rate_limited.title": "Ліміт перавышаны",
|
||||||
"alert.unexpected.message": "Узнікла нечаканая памылка.",
|
"alert.unexpected.message": "Узнікла нечаканая памылка.",
|
||||||
"alert.unexpected.title": "Вой!",
|
"alert.unexpected.title": "Вой!",
|
||||||
|
"alt_text_badge.title": "Альтернативный текст",
|
||||||
"announcement.announcement": "Аб'ява",
|
"announcement.announcement": "Аб'ява",
|
||||||
"attachments_list.unprocessed": "(неапрацаваны)",
|
"attachments_list.unprocessed": "(неапрацаваны)",
|
||||||
"audio.hide": "Схаваць аўдыя",
|
"audio.hide": "Схаваць аўдыя",
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
"account.requested_follow": "{name} möchte dir folgen",
|
"account.requested_follow": "{name} möchte dir folgen",
|
||||||
"account.share": "Profil von @{name} teilen",
|
"account.share": "Profil von @{name} teilen",
|
||||||
"account.show_reblogs": "Geteilte Beiträge von @{name} anzeigen",
|
"account.show_reblogs": "Geteilte Beiträge von @{name} anzeigen",
|
||||||
"account.statuses_counter": "{count, plural, one {{counter} post} other {{counter} posts}}",
|
"account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
|
||||||
"account.unblock": "Blockierung von @{name} aufheben",
|
"account.unblock": "Blockierung von @{name} aufheben",
|
||||||
"account.unblock_domain": "Blockierung von {domain} aufheben",
|
"account.unblock_domain": "Blockierung von {domain} aufheben",
|
||||||
"account.unblock_short": "Blockierung aufheben",
|
"account.unblock_short": "Blockierung aufheben",
|
||||||
|
|
|
@ -516,6 +516,7 @@
|
||||||
"notification.label.private_reply": "Répondre en privé",
|
"notification.label.private_reply": "Répondre en privé",
|
||||||
"notification.label.reply": "Réponse",
|
"notification.label.reply": "Réponse",
|
||||||
"notification.mention": "Mention",
|
"notification.mention": "Mention",
|
||||||
|
"notification.mentioned_you": "{name} vous a mentionné·e",
|
||||||
"notification.moderation-warning.learn_more": "En savoir plus",
|
"notification.moderation-warning.learn_more": "En savoir plus",
|
||||||
"notification.moderation_warning": "Vous avez reçu un avertissement de modération",
|
"notification.moderation_warning": "Vous avez reçu un avertissement de modération",
|
||||||
"notification.moderation_warning.action_delete_statuses": "Certains de vos messages ont été supprimés.",
|
"notification.moderation_warning.action_delete_statuses": "Certains de vos messages ont été supprimés.",
|
||||||
|
|
|
@ -516,6 +516,7 @@
|
||||||
"notification.label.private_reply": "Répondre en privé",
|
"notification.label.private_reply": "Répondre en privé",
|
||||||
"notification.label.reply": "Réponse",
|
"notification.label.reply": "Réponse",
|
||||||
"notification.mention": "Mention",
|
"notification.mention": "Mention",
|
||||||
|
"notification.mentioned_you": "{name} vous a mentionné·e",
|
||||||
"notification.moderation-warning.learn_more": "En savoir plus",
|
"notification.moderation-warning.learn_more": "En savoir plus",
|
||||||
"notification.moderation_warning": "Vous avez reçu un avertissement de modération",
|
"notification.moderation_warning": "Vous avez reçu un avertissement de modération",
|
||||||
"notification.moderation_warning.action_delete_statuses": "Certains de vos messages ont été supprimés.",
|
"notification.moderation_warning.action_delete_statuses": "Certains de vos messages ont été supprimés.",
|
||||||
|
|
|
@ -27,39 +27,35 @@ RSpec.describe AccountStatusesCleanupService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when given a normal budget of 10' do
|
context 'when given a normal budget of 10' do
|
||||||
it 'reports 3 deleted statuses' do
|
it 'reports 3 deleted statuses and records last deleted id, deletes statuses, preserves recent unrelated statuses' do
|
||||||
expect(subject.call(account_policy, 10)).to eq 3
|
expect(subject.call(account_policy, 10))
|
||||||
end
|
.to eq(3)
|
||||||
|
|
||||||
it 'records the last deleted id' do
|
expect(account_policy.last_inspected)
|
||||||
subject.call(account_policy, 10)
|
.to eq [old_status.id, another_old_status.id].max
|
||||||
expect(account_policy.last_inspected).to eq [old_status.id, another_old_status.id].max
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'actually deletes the statuses' do
|
expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id]))
|
||||||
subject.call(account_policy, 10)
|
.to be_nil
|
||||||
expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id])).to be_nil
|
expect { recent_status.reload }
|
||||||
expect { recent_status.reload }.to_not raise_error
|
.to_not raise_error
|
||||||
end
|
expect { unrelated_status.reload }
|
||||||
|
.to_not raise_error
|
||||||
it 'preserves recent and unrelated statuses' do
|
expect { recent_status.reload }
|
||||||
subject.call(account_policy, 10)
|
.to_not raise_error
|
||||||
expect { unrelated_status.reload }.to_not raise_error
|
|
||||||
expect { recent_status.reload }.to_not raise_error
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when called repeatedly with a budget of 2' do
|
context 'when called repeatedly with a budget of 2' do
|
||||||
it 'reports 2 then 1 deleted statuses' do
|
it 'reports 2 then 1 deleted statuses and deletes in expected order' do
|
||||||
expect(subject.call(account_policy, 2)).to eq 2
|
expect(subject.call(account_policy, 2))
|
||||||
expect(subject.call(account_policy, 2)).to eq 1
|
.to eq(2)
|
||||||
end
|
expect(Status.find_by(id: very_old_status.id))
|
||||||
|
.to be_nil
|
||||||
|
|
||||||
it 'actually deletes the statuses in the expected order' do
|
expect(subject.call(account_policy, 2))
|
||||||
subject.call(account_policy, 2)
|
.to eq(1)
|
||||||
expect(Status.find_by(id: very_old_status.id)).to be_nil
|
expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id]))
|
||||||
subject.call(account_policy, 2)
|
.to be_nil
|
||||||
expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id])).to be_nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -90,19 +86,24 @@ RSpec.describe AccountStatusesCleanupService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'reports 0 deleted statuses then 0 then 3 then 0 again' do
|
it 'reports 0 deleted statuses then 0 then 3 then 0 again, and keeps id under oldest deletable record' do
|
||||||
expect(subject.call(account_policy, 10)).to eq 0
|
expect(subject.call(account_policy, 10))
|
||||||
expect(subject.call(account_policy, 10)).to eq 0
|
.to eq(0)
|
||||||
expect(subject.call(account_policy, 10)).to eq 3
|
expect(subject.call(account_policy, 10))
|
||||||
expect(subject.call(account_policy, 10)).to eq 0
|
.to eq(0)
|
||||||
|
expect(subject.call(account_policy, 10))
|
||||||
|
.to eq(3)
|
||||||
|
expect(subject.call(account_policy, 10))
|
||||||
|
.to eq(0)
|
||||||
|
expect(account_policy.last_inspected)
|
||||||
|
.to be < oldest_deletable_record_id
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'never causes the recorded id to get higher than oldest deletable toot' do
|
def oldest_deletable_record_id
|
||||||
subject.call(account_policy, 10)
|
Mastodon::Snowflake.id_at(
|
||||||
subject.call(account_policy, 10)
|
account_policy.min_status_age.seconds.ago,
|
||||||
subject.call(account_policy, 10)
|
with_random: false
|
||||||
subject.call(account_policy, 10)
|
)
|
||||||
expect(account_policy.last_inspected).to be < Mastodon::Snowflake.id_at(account_policy.min_status_age.seconds.ago, with_random: false)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
def poll_option_json(name, votes)
|
|
||||||
{ type: 'Note', name: name, replies: { type: 'Collection', totalItems: votes } }
|
|
||||||
end
|
|
||||||
|
|
||||||
RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
subject { described_class.new }
|
subject { described_class.new }
|
||||||
|
|
||||||
|
@ -294,7 +290,6 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
context 'when originally without media attachments' do
|
context 'when originally without media attachments' do
|
||||||
before do
|
before do
|
||||||
stub_request(:get, 'https://example.com/foo.png').to_return(body: attachment_fixture('emojo.png'))
|
stub_request(:get, 'https://example.com/foo.png').to_return(body: attachment_fixture('emojo.png'))
|
||||||
subject.call(status, json, json)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:payload) do
|
let(:payload) do
|
||||||
|
@ -310,19 +305,18 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates media attachments' do
|
it 'updates media attachments, fetches attachment, records media change in edit' do
|
||||||
media_attachment = status.reload.ordered_media_attachments.first
|
subject.call(status, json, json)
|
||||||
|
|
||||||
expect(media_attachment).to_not be_nil
|
expect(status.reload.ordered_media_attachments.first)
|
||||||
expect(media_attachment.remote_url).to eq 'https://example.com/foo.png'
|
.to be_present
|
||||||
end
|
.and(have_attributes(remote_url: 'https://example.com/foo.png'))
|
||||||
|
|
||||||
it 'fetches the attachment' do
|
expect(a_request(:get, 'https://example.com/foo.png'))
|
||||||
expect(a_request(:get, 'https://example.com/foo.png')).to have_been_made
|
.to have_been_made
|
||||||
end
|
|
||||||
|
|
||||||
it 'records media change in edit' do
|
expect(status.edits.reload.last.ordered_media_attachment_ids)
|
||||||
expect(status.edits.reload.last.ordered_media_attachment_ids).to_not be_empty
|
.to_not be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -344,27 +338,26 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(RedownloadMediaWorker).to receive(:perform_async)
|
allow(RedownloadMediaWorker).to receive(:perform_async)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates the existing media attachment in-place, does not queue redownload, updates media, records media change' do
|
||||||
subject.call(status, json, json)
|
subject.call(status, json, json)
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates the existing media attachment in-place' do
|
expect(status.media_attachments.ordered.reload.first)
|
||||||
media_attachment = status.media_attachments.ordered.reload.first
|
.to be_present
|
||||||
|
.and have_attributes(
|
||||||
|
remote_url: 'https://example.com/foo.png',
|
||||||
|
description: 'A picture'
|
||||||
|
)
|
||||||
|
|
||||||
expect(media_attachment).to_not be_nil
|
expect(RedownloadMediaWorker)
|
||||||
expect(media_attachment.remote_url).to eq 'https://example.com/foo.png'
|
.to_not have_received(:perform_async)
|
||||||
expect(media_attachment.description).to eq 'A picture'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not queue redownload for the existing media attachment' do
|
expect(status.ordered_media_attachments.map(&:remote_url))
|
||||||
expect(RedownloadMediaWorker).to_not have_received(:perform_async)
|
.to eq %w(https://example.com/foo.png)
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates media attachments' do
|
expect(status.edits.reload.last.ordered_media_attachment_ids)
|
||||||
expect(status.ordered_media_attachments.map(&:remote_url)).to eq %w(https://example.com/foo.png)
|
.to_not be_empty
|
||||||
end
|
|
||||||
|
|
||||||
it 'records media change in edit' do
|
|
||||||
expect(status.edits.reload.last.ordered_media_attachment_ids).to_not be_empty
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -372,10 +365,11 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
before do
|
before do
|
||||||
poll = Fabricate(:poll, status: status)
|
poll = Fabricate(:poll, status: status)
|
||||||
status.update(preloadable_poll: poll)
|
status.update(preloadable_poll: poll)
|
||||||
subject.call(status, json, json)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'removes poll and records media change in edit' do
|
it 'removes poll and records media change in edit' do
|
||||||
|
subject.call(status, json, json)
|
||||||
|
|
||||||
expect(status.reload.poll).to be_nil
|
expect(status.reload.poll).to be_nil
|
||||||
expect(status.edits.reload.last.poll_options).to be_nil
|
expect(status.edits.reload.last.poll_options).to be_nil
|
||||||
end
|
end
|
||||||
|
@ -398,15 +392,13 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
|
||||||
subject.call(status, json, json)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a poll and records media change in edit' do
|
it 'creates a poll and records media change in edit' do
|
||||||
poll = status.reload.poll
|
subject.call(status, json, json)
|
||||||
|
|
||||||
|
expect(status.reload.poll)
|
||||||
|
.to be_present
|
||||||
|
.and have_attributes(options: %w(Foo Bar Baz))
|
||||||
|
|
||||||
expect(poll).to_not be_nil
|
|
||||||
expect(poll.options).to eq %w(Foo Bar Baz)
|
|
||||||
expect(status.edits.reload.last.poll_options).to eq %w(Foo Bar Baz)
|
expect(status.edits.reload.last.poll_options).to eq %w(Foo Bar Baz)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -419,4 +411,8 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
||||||
.to eq '2021-09-08 22:39:25 UTC'
|
.to eq '2021-09-08 22:39:25 UTC'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def poll_option_json(name, votes)
|
||||||
|
{ type: 'Note', name: name, replies: { type: 'Collection', totalItems: votes } }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,15 +12,15 @@ RSpec.describe AuthorizeFollowService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
FollowRequest.create(account: bob, target_account: sender)
|
FollowRequest.create(account: bob, target_account: sender)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes follow request and creates follow relation' do
|
||||||
subject.call(bob, sender)
|
subject.call(bob, sender)
|
||||||
end
|
|
||||||
|
|
||||||
it 'removes follow request' do
|
expect(bob)
|
||||||
expect(bob.requested?(sender)).to be false
|
.to_not be_requested(sender)
|
||||||
end
|
expect(bob)
|
||||||
|
.to be_following(sender)
|
||||||
it 'creates follow relation' do
|
|
||||||
expect(bob.following?(sender)).to be true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -30,19 +30,17 @@ RSpec.describe AuthorizeFollowService do
|
||||||
before do
|
before do
|
||||||
FollowRequest.create(account: bob, target_account: sender)
|
FollowRequest.create(account: bob, target_account: sender)
|
||||||
stub_request(:post, bob.inbox_url).to_return(status: 200)
|
stub_request(:post, bob.inbox_url).to_return(status: 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes follow request, creates follow relation, send accept activity', :inline_jobs do
|
||||||
subject.call(bob, sender)
|
subject.call(bob, sender)
|
||||||
end
|
|
||||||
|
|
||||||
it 'removes follow request' do
|
expect(bob)
|
||||||
expect(bob.requested?(sender)).to be false
|
.to_not be_requested(sender)
|
||||||
end
|
expect(bob)
|
||||||
|
.to be_following(sender)
|
||||||
it 'creates follow relation' do
|
expect(a_request(:post, bob.inbox_url))
|
||||||
expect(bob.following?(sender)).to be true
|
.to have_been_made.once
|
||||||
end
|
|
||||||
|
|
||||||
it 'sends an accept activity', :inline_jobs do
|
|
||||||
expect(a_request(:post, bob.inbox_url)).to have_been_made.once
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,32 +24,38 @@ RSpec.describe BatchedRemoveStatusService, :inline_jobs do
|
||||||
|
|
||||||
status_alice_hello
|
status_alice_hello
|
||||||
status_alice_other
|
status_alice_other
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes status records, removes from author and local follower feeds, notifies stream, sends delete' do
|
||||||
subject.call([status_alice_hello, status_alice_other])
|
subject.call([status_alice_hello, status_alice_other])
|
||||||
|
|
||||||
|
expect { Status.find(status_alice_hello.id) }
|
||||||
|
.to raise_error ActiveRecord::RecordNotFound
|
||||||
|
expect { Status.find(status_alice_other.id) }
|
||||||
|
.to raise_error ActiveRecord::RecordNotFound
|
||||||
|
|
||||||
|
expect(feed_ids_for(alice))
|
||||||
|
.to_not include(status_alice_hello.id, status_alice_other.id)
|
||||||
|
|
||||||
|
expect(feed_ids_for(jeff))
|
||||||
|
.to_not include(status_alice_hello.id, status_alice_other.id)
|
||||||
|
|
||||||
|
expect(redis)
|
||||||
|
.to have_received(:publish)
|
||||||
|
.with("timeline:#{jeff.id}", any_args).at_least(:once)
|
||||||
|
|
||||||
|
expect(redis)
|
||||||
|
.to have_received(:publish)
|
||||||
|
.with('timeline:public', any_args).at_least(:once)
|
||||||
|
|
||||||
|
expect(a_request(:post, 'http://example.com/inbox'))
|
||||||
|
.to have_been_made.at_least_once
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'removes statuses' do
|
def feed_ids_for(account)
|
||||||
expect { Status.find(status_alice_hello.id) }.to raise_error ActiveRecord::RecordNotFound
|
HomeFeed
|
||||||
expect { Status.find(status_alice_other.id) }.to raise_error ActiveRecord::RecordNotFound
|
.new(account)
|
||||||
end
|
.get(10)
|
||||||
|
.pluck(:id)
|
||||||
it 'removes statuses from author\'s home feed' do
|
|
||||||
expect(HomeFeed.new(alice).get(10).pluck(:id)).to_not include(status_alice_hello.id, status_alice_other.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'removes statuses from local follower\'s home feed' do
|
|
||||||
expect(HomeFeed.new(jeff).get(10).pluck(:id)).to_not include(status_alice_hello.id, status_alice_other.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'notifies streaming API of followers' do
|
|
||||||
expect(redis).to have_received(:publish).with("timeline:#{jeff.id}", any_args).at_least(:once)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'notifies streaming API of public timeline' do
|
|
||||||
expect(redis).to have_received(:publish).with('timeline:public', any_args).at_least(:once)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'sends delete activity to followers' do
|
|
||||||
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.at_least_once
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,15 +26,16 @@ RSpec.describe BlockService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates a blocking relation and send block activity', :inline_jobs do
|
||||||
subject.call(sender, bob)
|
subject.call(sender, bob)
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a blocking relation' do
|
expect(sender)
|
||||||
expect(sender.blocking?(bob)).to be true
|
.to be_blocking(bob)
|
||||||
end
|
|
||||||
|
|
||||||
it 'sends a block activity', :inline_jobs do
|
expect(a_request(:post, 'http://example.com/inbox'))
|
||||||
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
|
.to have_been_made.once
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,30 +24,19 @@ RSpec.describe BulkImportService do
|
||||||
].map { |data| import.rows.create!(data: data) }
|
].map { |data| import.rows.create!(data: data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before { account.follow!(Fabricate(:account)) }
|
||||||
account.follow!(Fabricate(:account))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not immediately change who the account follows' do
|
it 'does not immediately change who the account follows, enqueues workers, sends follow requests after worker run' do
|
||||||
expect { subject.call(import) }.to_not(change { account.reload.active_relationships.to_a })
|
expect { subject.call(import) }
|
||||||
end
|
.to_not(change { account.reload.active_relationships.to_a })
|
||||||
|
|
||||||
it 'enqueues workers for the expected rows' do
|
expect(row_worker_job_args)
|
||||||
subject.call(import)
|
.to match_array(rows.map(&:id))
|
||||||
expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'requests to follow all the listed users once the workers have run' do
|
stub_resolve_account_and_drain_workers
|
||||||
subject.call(import)
|
|
||||||
|
|
||||||
resolve_account_service_double = instance_double(ResolveAccountService)
|
expect(FollowRequest.includes(:target_account).where(account: account).map { |follow_request| follow_request.target_account.acct })
|
||||||
allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double)
|
.to contain_exactly('user@foo.bar', 'unknown@unknown.bar')
|
||||||
allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) }
|
|
||||||
allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) }
|
|
||||||
|
|
||||||
Import::RowWorker.drain
|
|
||||||
|
|
||||||
expect(FollowRequest.includes(:target_account).where(account: account).map { |follow_request| follow_request.target_account.acct }).to contain_exactly('user@foo.bar', 'unknown@unknown.bar')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -71,31 +60,20 @@ RSpec.describe BulkImportService do
|
||||||
account.follow!(to_be_unfollowed)
|
account.follow!(to_be_unfollowed)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'unfollows user not present on list' do
|
it 'updates the existing follow relationship as expected and unfollows user not on list, enqueues workers, sends follow reqs after worker run' do
|
||||||
subject.call(import)
|
expect { subject.call(import) }
|
||||||
expect(account.following?(to_be_unfollowed)).to be false
|
.to change { Follow.where(account: account, target_account: followed).pick(:show_reblogs, :notify, :languages) }.from([true, false, nil]).to([false, true, ['en']])
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates the existing follow relationship as expected' do
|
expect(account)
|
||||||
expect { subject.call(import) }.to change { Follow.where(account: account, target_account: followed).pick(:show_reblogs, :notify, :languages) }.from([true, false, nil]).to([false, true, ['en']])
|
.to_not be_following(to_be_unfollowed)
|
||||||
end
|
|
||||||
|
|
||||||
it 'enqueues workers for the expected rows' do
|
expect(row_worker_job_args)
|
||||||
subject.call(import)
|
.to match_array(rows[1..].map(&:id))
|
||||||
expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'requests to follow all the expected users once the workers have run' do
|
stub_resolve_account_and_drain_workers
|
||||||
subject.call(import)
|
|
||||||
|
|
||||||
resolve_account_service_double = instance_double(ResolveAccountService)
|
expect(FollowRequest.includes(:target_account).where(account: account).map { |follow_request| follow_request.target_account.acct })
|
||||||
allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double)
|
.to contain_exactly('user@foo.bar', 'unknown@unknown.bar')
|
||||||
allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) }
|
|
||||||
allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) }
|
|
||||||
|
|
||||||
Import::RowWorker.drain
|
|
||||||
|
|
||||||
expect(FollowRequest.includes(:target_account).where(account: account).map { |follow_request| follow_request.target_account.acct }).to contain_exactly('user@foo.bar', 'unknown@unknown.bar')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -110,30 +88,19 @@ RSpec.describe BulkImportService do
|
||||||
].map { |data| import.rows.create!(data: data) }
|
].map { |data| import.rows.create!(data: data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before { account.block!(Fabricate(:account, username: 'already_blocked', domain: 'remote.org')) }
|
||||||
account.block!(Fabricate(:account, username: 'already_blocked', domain: 'remote.org'))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not immediately change who the account blocks' do
|
it 'does not immediately change who the account blocks, enqueues worker, blocks after run' do
|
||||||
expect { subject.call(import) }.to_not(change { account.reload.blocking.to_a })
|
expect { subject.call(import) }
|
||||||
end
|
.to_not(change { account.reload.blocking.to_a })
|
||||||
|
|
||||||
it 'enqueues workers for the expected rows' do
|
expect(row_worker_job_args)
|
||||||
subject.call(import)
|
.to match_array(rows.map(&:id))
|
||||||
expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'blocks all the listed users once the workers have run' do
|
stub_resolve_account_and_drain_workers
|
||||||
subject.call(import)
|
|
||||||
|
|
||||||
resolve_account_service_double = instance_double(ResolveAccountService)
|
expect(account.reload.blocking.map(&:acct))
|
||||||
allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double)
|
.to contain_exactly('already_blocked@remote.org', 'user@foo.bar', 'unknown@unknown.bar')
|
||||||
allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) }
|
|
||||||
allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) }
|
|
||||||
|
|
||||||
Import::RowWorker.drain
|
|
||||||
|
|
||||||
expect(account.blocking.map(&:acct)).to contain_exactly('already_blocked@remote.org', 'user@foo.bar', 'unknown@unknown.bar')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -157,27 +124,18 @@ RSpec.describe BulkImportService do
|
||||||
account.block!(to_be_unblocked)
|
account.block!(to_be_unblocked)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'unblocks user not present on list' do
|
it 'unblocks user not present on list, enqueues worker, requests follow after run' do
|
||||||
subject.call(import)
|
subject.call(import)
|
||||||
|
|
||||||
expect(account.blocking?(to_be_unblocked)).to be false
|
expect(account.blocking?(to_be_unblocked)).to be false
|
||||||
end
|
|
||||||
|
|
||||||
it 'enqueues workers for the expected rows' do
|
expect(row_worker_job_args)
|
||||||
subject.call(import)
|
.to match_array(rows[1..].map(&:id))
|
||||||
expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'requests to follow all the expected users once the workers have run' do
|
stub_resolve_account_and_drain_workers
|
||||||
subject.call(import)
|
|
||||||
|
|
||||||
resolve_account_service_double = instance_double(ResolveAccountService)
|
expect(account.blocking.map(&:acct))
|
||||||
allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double)
|
.to contain_exactly('blocked@foo.bar', 'user@foo.bar', 'unknown@unknown.bar')
|
||||||
allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) }
|
|
||||||
allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) }
|
|
||||||
|
|
||||||
Import::RowWorker.drain
|
|
||||||
|
|
||||||
expect(account.blocking.map(&:acct)).to contain_exactly('blocked@foo.bar', 'user@foo.bar', 'unknown@unknown.bar')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -192,30 +150,19 @@ RSpec.describe BulkImportService do
|
||||||
].map { |data| import.rows.create!(data: data) }
|
].map { |data| import.rows.create!(data: data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before { account.mute!(Fabricate(:account, username: 'already_muted', domain: 'remote.org')) }
|
||||||
account.mute!(Fabricate(:account, username: 'already_muted', domain: 'remote.org'))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not immediately change who the account blocks' do
|
it 'does not immediately change who the account blocks, enqueures worker, mutes users after worker run' do
|
||||||
expect { subject.call(import) }.to_not(change { account.reload.muting.to_a })
|
expect { subject.call(import) }
|
||||||
end
|
.to_not(change { account.reload.muting.to_a })
|
||||||
|
|
||||||
it 'enqueues workers for the expected rows' do
|
expect(row_worker_job_args)
|
||||||
subject.call(import)
|
.to match_array(rows.map(&:id))
|
||||||
expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'mutes all the listed users once the workers have run' do
|
stub_resolve_account_and_drain_workers
|
||||||
subject.call(import)
|
|
||||||
|
|
||||||
resolve_account_service_double = instance_double(ResolveAccountService)
|
expect(account.reload.muting.map(&:acct))
|
||||||
allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double)
|
.to contain_exactly('already_muted@remote.org', 'user@foo.bar', 'unknown@unknown.bar')
|
||||||
allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) }
|
|
||||||
allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) }
|
|
||||||
|
|
||||||
Import::RowWorker.drain
|
|
||||||
|
|
||||||
expect(account.muting.map(&:acct)).to contain_exactly('already_muted@remote.org', 'user@foo.bar', 'unknown@unknown.bar')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -239,31 +186,19 @@ RSpec.describe BulkImportService do
|
||||||
account.mute!(to_be_unmuted)
|
account.mute!(to_be_unmuted)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates the existing mute as expected' do
|
it 'updates the existing mute as expected and unblocks user not on list, and enqueues worker, and requests follow after worker run' do
|
||||||
expect { subject.call(import) }.to change { Mute.where(account: account, target_account: muted).pick(:hide_notifications) }.from(false).to(true)
|
expect { subject.call(import) }
|
||||||
end
|
.to change { Mute.where(account: account, target_account: muted).pick(:hide_notifications) }.from(false).to(true)
|
||||||
|
|
||||||
it 'unblocks user not present on list' do
|
|
||||||
subject.call(import)
|
|
||||||
expect(account.muting?(to_be_unmuted)).to be false
|
expect(account.muting?(to_be_unmuted)).to be false
|
||||||
end
|
|
||||||
|
|
||||||
it 'enqueues workers for the expected rows' do
|
expect(row_worker_job_args)
|
||||||
subject.call(import)
|
.to match_array(rows[1..].map(&:id))
|
||||||
expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'requests to follow all the expected users once the workers have run' do
|
stub_resolve_account_and_drain_workers
|
||||||
subject.call(import)
|
|
||||||
|
|
||||||
resolve_account_service_double = instance_double(ResolveAccountService)
|
expect(account.muting.map(&:acct))
|
||||||
allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double)
|
.to contain_exactly('muted@foo.bar', 'user@foo.bar', 'unknown@unknown.bar')
|
||||||
allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) }
|
|
||||||
allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) }
|
|
||||||
|
|
||||||
Import::RowWorker.drain
|
|
||||||
|
|
||||||
expect(account.muting.map(&:acct)).to contain_exactly('muted@foo.bar', 'user@foo.bar', 'unknown@unknown.bar')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -284,13 +219,11 @@ RSpec.describe BulkImportService do
|
||||||
account.block_domain!('blocked.com')
|
account.block_domain!('blocked.com')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'blocks all the new domains' do
|
it 'blocks all the new domains and marks import finished' do
|
||||||
subject.call(import)
|
subject.call(import)
|
||||||
expect(account.domain_blocks.pluck(:domain)).to contain_exactly('alreadyblocked.com', 'blocked.com', 'to-block.com')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'marks the import as finished' do
|
expect(account.domain_blocks.pluck(:domain))
|
||||||
subject.call(import)
|
.to contain_exactly('alreadyblocked.com', 'blocked.com', 'to-block.com')
|
||||||
expect(import.reload.state_finished?).to be true
|
expect(import.reload.state_finished?).to be true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -312,14 +245,13 @@ RSpec.describe BulkImportService do
|
||||||
account.block_domain!('blocked.com')
|
account.block_domain!('blocked.com')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'blocks all the new domains' do
|
it 'blocks all the new domains and marks import finished' do
|
||||||
subject.call(import)
|
subject.call(import)
|
||||||
expect(account.domain_blocks.pluck(:domain)).to contain_exactly('blocked.com', 'to-block.com')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'marks the import as finished' do
|
expect(account.domain_blocks.pluck(:domain))
|
||||||
subject.call(import)
|
.to contain_exactly('blocked.com', 'to-block.com')
|
||||||
expect(import.reload.state_finished?).to be true
|
expect(import.reload.state_finished?)
|
||||||
|
.to be true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -347,22 +279,16 @@ RSpec.describe BulkImportService do
|
||||||
account.bookmarks.create!(status: bookmarked)
|
account.bookmarks.create!(status: bookmarked)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'enqueues workers for the expected rows' do
|
it 'enqueues workers for the expected rows and updates bookmarks after worker run' do
|
||||||
subject.call(import)
|
|
||||||
expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates the bookmarks as expected once the workers have run' do
|
|
||||||
subject.call(import)
|
subject.call(import)
|
||||||
|
|
||||||
service_double = instance_double(ActivityPub::FetchRemoteStatusService)
|
expect(row_worker_job_args)
|
||||||
allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service_double)
|
.to match_array(rows.map(&:id))
|
||||||
allow(service_double).to receive(:call).with('https://domain.unknown/foo') { Fabricate(:status, uri: 'https://domain.unknown/foo') }
|
|
||||||
allow(service_double).to receive(:call).with('https://domain.unknown/private') { Fabricate(:status, uri: 'https://domain.unknown/private', visibility: :direct) }
|
|
||||||
|
|
||||||
Import::RowWorker.drain
|
stub_fetch_remote_and_drain_workers
|
||||||
|
|
||||||
expect(account.bookmarks.map { |bookmark| bookmark.status.uri }).to contain_exactly(already_bookmarked.uri, status.uri, bookmarked.uri, 'https://domain.unknown/foo')
|
expect(account.bookmarks.map { |bookmark| bookmark.status.uri })
|
||||||
|
.to contain_exactly(already_bookmarked.uri, status.uri, bookmarked.uri, 'https://domain.unknown/foo')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -390,23 +316,48 @@ RSpec.describe BulkImportService do
|
||||||
account.bookmarks.create!(status: bookmarked)
|
account.bookmarks.create!(status: bookmarked)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'enqueues workers for the expected rows' do
|
it 'enqueues workers for the expected rows and updates bookmarks' do
|
||||||
subject.call(import)
|
subject.call(import)
|
||||||
expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id))
|
|
||||||
|
expect(row_worker_job_args)
|
||||||
|
.to match_array(rows.map(&:id))
|
||||||
|
|
||||||
|
stub_fetch_remote_and_drain_workers
|
||||||
|
|
||||||
|
expect(account.bookmarks.map { |bookmark| bookmark.status.uri })
|
||||||
|
.to contain_exactly(status.uri, bookmarked.uri, 'https://domain.unknown/foo')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates the bookmarks as expected once the workers have run' do
|
def row_worker_job_args
|
||||||
subject.call(import)
|
Import::RowWorker
|
||||||
|
.jobs
|
||||||
|
.pluck('args')
|
||||||
|
.flatten
|
||||||
|
end
|
||||||
|
|
||||||
|
def stub_resolve_account_and_drain_workers
|
||||||
|
resolve_account_service_double = instance_double(ResolveAccountService)
|
||||||
|
allow(ResolveAccountService)
|
||||||
|
.to receive(:new)
|
||||||
|
.and_return(resolve_account_service_double)
|
||||||
|
allow(resolve_account_service_double)
|
||||||
|
.to receive(:call)
|
||||||
|
.with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) }
|
||||||
|
allow(resolve_account_service_double)
|
||||||
|
.to receive(:call)
|
||||||
|
.with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) }
|
||||||
|
|
||||||
|
Import::RowWorker.drain
|
||||||
|
end
|
||||||
|
|
||||||
|
def stub_fetch_remote_and_drain_workers
|
||||||
service_double = instance_double(ActivityPub::FetchRemoteStatusService)
|
service_double = instance_double(ActivityPub::FetchRemoteStatusService)
|
||||||
allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service_double)
|
allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service_double)
|
||||||
allow(service_double).to receive(:call).with('https://domain.unknown/foo') { Fabricate(:status, uri: 'https://domain.unknown/foo') }
|
allow(service_double).to receive(:call).with('https://domain.unknown/foo') { Fabricate(:status, uri: 'https://domain.unknown/foo') }
|
||||||
allow(service_double).to receive(:call).with('https://domain.unknown/private') { Fabricate(:status, uri: 'https://domain.unknown/private', visibility: :direct) }
|
allow(service_double).to receive(:call).with('https://domain.unknown/private') { Fabricate(:status, uri: 'https://domain.unknown/private', visibility: :direct) }
|
||||||
|
|
||||||
Import::RowWorker.drain
|
Import::RowWorker.drain
|
||||||
|
|
||||||
expect(account.bookmarks.map { |bookmark| bookmark.status.uri }).to contain_exactly(status.uri, bookmarked.uri, 'https://domain.unknown/foo')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,11 +11,9 @@ RSpec.describe FavouriteService do
|
||||||
let(:bob) { Fabricate(:account) }
|
let(:bob) { Fabricate(:account) }
|
||||||
let(:status) { Fabricate(:status, account: bob) }
|
let(:status) { Fabricate(:status, account: bob) }
|
||||||
|
|
||||||
before do
|
|
||||||
subject.call(sender, status)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a favourite' do
|
it 'creates a favourite' do
|
||||||
|
subject.call(sender, status)
|
||||||
|
|
||||||
expect(status.favourites.first).to_not be_nil
|
expect(status.favourites.first).to_not be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -26,15 +24,16 @@ RSpec.describe FavouriteService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {})
|
stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates a favourite and sends like activity', :inline_jobs do
|
||||||
subject.call(sender, status)
|
subject.call(sender, status)
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a favourite' do
|
expect(status.favourites.first)
|
||||||
expect(status.favourites.first).to_not be_nil
|
.to_not be_nil
|
||||||
end
|
|
||||||
|
|
||||||
it 'sends a like activity', :inline_jobs do
|
expect(a_request(:post, 'http://example.com/inbox'))
|
||||||
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
|
.to have_been_made.once
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -143,15 +143,16 @@ RSpec.describe FollowService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {})
|
stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates follow request and sends an activity to inbox', :inline_jobs do
|
||||||
subject.call(sender, bob)
|
subject.call(sender, bob)
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates follow request' do
|
expect(FollowRequest.find_by(account: sender, target_account: bob))
|
||||||
expect(FollowRequest.find_by(account: sender, target_account: bob)).to_not be_nil
|
.to_not be_nil
|
||||||
end
|
|
||||||
|
|
||||||
it 'sends a follow activity to the inbox', :inline_jobs do
|
expect(a_request(:post, 'http://example.com/inbox'))
|
||||||
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
|
.to have_been_made.once
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,20 +16,25 @@ RSpec.describe ProcessMentionsService do
|
||||||
before do
|
before do
|
||||||
account.block!(individually_blocked_account)
|
account.block!(individually_blocked_account)
|
||||||
account.domain_blocks.create!(domain: domain_blocked_account.domain)
|
account.domain_blocks.create!(domain: domain_blocked_account.domain)
|
||||||
|
|
||||||
subject.call(status)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a mention to the non-blocked account' do
|
it 'creates a mention to the non-blocked account but not the individually or domain blocked accounts' do
|
||||||
expect(non_blocked_account.mentions.where(status: status).count).to eq 1
|
expect { subject.call(status) }
|
||||||
|
.to create_mention_for_non_blocked
|
||||||
|
.and skip_mention_for_individual
|
||||||
|
.and skip_mention_for_domain_blocked
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not create a mention to the individually blocked account' do
|
def create_mention_for_non_blocked
|
||||||
expect(individually_blocked_account.mentions.where(status: status).count).to eq 0
|
change { non_blocked_account.mentions.where(status: status).count }.to(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not create a mention to the domain-blocked account' do
|
def skip_mention_for_individual
|
||||||
expect(domain_blocked_account.mentions.where(status: status).count).to eq 0
|
not_change { individually_blocked_account.mentions.where(status: status).count }.from(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip_mention_for_domain_blocked
|
||||||
|
not_change { domain_blocked_account.mentions.where(status: status).count }.from(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,11 +45,9 @@ RSpec.describe ProcessMentionsService do
|
||||||
context 'with a valid remote user' do
|
context 'with a valid remote user' 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', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
|
||||||
|
|
||||||
before do
|
|
||||||
subject.call(status)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a mention' do
|
it 'creates a mention' do
|
||||||
|
subject.call(status)
|
||||||
|
|
||||||
expect(remote_user.mentions.where(status: status).count).to eq 1
|
expect(remote_user.mentions.where(status: status).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -53,11 +56,9 @@ RSpec.describe ProcessMentionsService 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', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
|
||||||
let(:status) { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct} @#{remote_user.acct} @#{remote_user.acct}", visibility: :public) }
|
let(:status) { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct} @#{remote_user.acct} @#{remote_user.acct}", visibility: :public) }
|
||||||
|
|
||||||
before do
|
|
||||||
subject.call(status, save_records: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates exactly one mention' do
|
it 'creates exactly one mention' do
|
||||||
|
subject.call(status, save_records: false)
|
||||||
|
|
||||||
expect(status.mentions.size).to eq 1
|
expect(status.mentions.size).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -66,11 +67,9 @@ RSpec.describe ProcessMentionsService do
|
||||||
let!(:remote_user) { Fabricate(:account, username: 'sneak', protocol: :activitypub, domain: 'xn--hresiar-mxa.ch', inbox_url: 'http://example.com/inbox') }
|
let!(:remote_user) { Fabricate(:account, username: 'sneak', protocol: :activitypub, domain: 'xn--hresiar-mxa.ch', inbox_url: 'http://example.com/inbox') }
|
||||||
let!(:status) { Fabricate(:status, account: account, text: 'Hello @sneak@hæresiar.ch') }
|
let!(:status) { Fabricate(:status, account: account, text: 'Hello @sneak@hæresiar.ch') }
|
||||||
|
|
||||||
before do
|
|
||||||
subject.call(status)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a mention' do
|
it 'creates a mention' do
|
||||||
|
subject.call(status)
|
||||||
|
|
||||||
expect(remote_user.mentions.where(status: status).count).to eq 1
|
expect(remote_user.mentions.where(status: status).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -79,11 +78,9 @@ RSpec.describe ProcessMentionsService do
|
||||||
let!(:remote_user) { Fabricate(:account, username: 'foo', protocol: :activitypub, domain: 'xn--y9a3aq.xn--y9a3aq', inbox_url: 'http://example.com/inbox') }
|
let!(:remote_user) { Fabricate(:account, username: 'foo', protocol: :activitypub, domain: 'xn--y9a3aq.xn--y9a3aq', inbox_url: 'http://example.com/inbox') }
|
||||||
let!(:status) { Fabricate(:status, account: account, text: 'Hello @foo@հայ.հայ') }
|
let!(:status) { Fabricate(:status, account: account, text: 'Hello @foo@հայ.հայ') }
|
||||||
|
|
||||||
before do
|
|
||||||
subject.call(status)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a mention' do
|
it 'creates a mention' do
|
||||||
|
subject.call(status)
|
||||||
|
|
||||||
expect(remote_user.mentions.where(status: status).count).to eq 1
|
expect(remote_user.mentions.where(status: status).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -95,10 +92,11 @@ RSpec.describe ProcessMentionsService do
|
||||||
before do
|
before do
|
||||||
stub_request(:get, 'https://example.com/.well-known/host-meta').to_return(status: 404)
|
stub_request(:get, 'https://example.com/.well-known/host-meta').to_return(status: 404)
|
||||||
stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:remote_user@example.com').to_return(status: 500)
|
stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:remote_user@example.com').to_return(status: 500)
|
||||||
subject.call(status)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a mention' do
|
it 'creates a mention' do
|
||||||
|
subject.call(status)
|
||||||
|
|
||||||
expect(remote_user.mentions.where(status: status).count).to eq 1
|
expect(remote_user.mentions.where(status: status).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,17 +10,15 @@ RSpec.describe RejectFollowService do
|
||||||
describe 'local' do
|
describe 'local' do
|
||||||
let(:bob) { Fabricate(:account) }
|
let(:bob) { Fabricate(:account) }
|
||||||
|
|
||||||
before do
|
before { FollowRequest.create(account: bob, target_account: sender) }
|
||||||
FollowRequest.create(account: bob, target_account: sender)
|
|
||||||
|
it 'removes follow request and does not create relation' do
|
||||||
subject.call(bob, sender)
|
subject.call(bob, sender)
|
||||||
end
|
|
||||||
|
|
||||||
it 'removes follow request' do
|
expect(bob)
|
||||||
expect(bob.requested?(sender)).to be false
|
.to_not be_requested(sender)
|
||||||
end
|
expect(bob)
|
||||||
|
.to_not be_following(sender)
|
||||||
it 'does not create follow relation' do
|
|
||||||
expect(bob.following?(sender)).to be false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -30,19 +28,17 @@ RSpec.describe RejectFollowService do
|
||||||
before do
|
before do
|
||||||
FollowRequest.create(account: bob, target_account: sender)
|
FollowRequest.create(account: bob, target_account: sender)
|
||||||
stub_request(:post, bob.inbox_url).to_return(status: 200)
|
stub_request(:post, bob.inbox_url).to_return(status: 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes follow request, does not create relation, sends reject activity', :inline_jobs do
|
||||||
subject.call(bob, sender)
|
subject.call(bob, sender)
|
||||||
end
|
|
||||||
|
|
||||||
it 'removes follow request' do
|
expect(bob)
|
||||||
expect(bob.requested?(sender)).to be false
|
.to_not be_requested(sender)
|
||||||
end
|
expect(bob)
|
||||||
|
.to_not be_following(sender)
|
||||||
it 'does not create follow relation' do
|
expect(a_request(:post, bob.inbox_url))
|
||||||
expect(bob.following?(sender)).to be false
|
.to have_been_made.once
|
||||||
end
|
|
||||||
|
|
||||||
it 'sends a reject activity', :inline_jobs do
|
|
||||||
expect(a_request(:post, bob.inbox_url)).to have_been_made.once
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,13 +10,13 @@ RSpec.describe RemoveFromFollowersService do
|
||||||
describe 'local' do
|
describe 'local' do
|
||||||
let(:sender) { Fabricate(:account, username: 'alice') }
|
let(:sender) { Fabricate(:account, username: 'alice') }
|
||||||
|
|
||||||
before do
|
before { Follow.create(account: sender, target_account: bob) }
|
||||||
Follow.create(account: sender, target_account: bob)
|
|
||||||
subject.call(bob, sender)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not create follow relation' do
|
it 'does not create follow relation' do
|
||||||
expect(bob.followed_by?(sender)).to be false
|
subject.call(bob, sender)
|
||||||
|
|
||||||
|
expect(bob)
|
||||||
|
.to_not be_followed_by(sender)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,15 +26,16 @@ RSpec.describe RemoveFromFollowersService do
|
||||||
before do
|
before do
|
||||||
Follow.create(account: sender, target_account: bob)
|
Follow.create(account: sender, target_account: bob)
|
||||||
stub_request(:post, sender.inbox_url).to_return(status: 200)
|
stub_request(:post, sender.inbox_url).to_return(status: 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not create follow relation and sends reject activity', :inline_jobs do
|
||||||
subject.call(bob, sender)
|
subject.call(bob, sender)
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not create follow relation' do
|
expect(bob)
|
||||||
expect(bob.followed_by?(sender)).to be false
|
.to_not be_followed_by(sender)
|
||||||
end
|
|
||||||
|
|
||||||
it 'sends a reject activity', :inline_jobs do
|
expect(a_request(:post, sender.inbox_url))
|
||||||
expect(a_request(:post, sender.inbox_url)).to have_been_made.once
|
.to have_been_made.once
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,42 +28,38 @@ RSpec.describe RemoveStatusService, :inline_jobs do
|
||||||
Fabricate(:status, account: bill, reblog: status, uri: 'hoge')
|
Fabricate(:status, account: bill, reblog: status, uri: 'hoge')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'removes status from author\'s home feed' do
|
it 'removes status from notifications and from author and local follower home feeds, publishes to media timeline, sends delete activities' do
|
||||||
subject.call(status)
|
|
||||||
expect(HomeFeed.new(alice).get(10).pluck(:id)).to_not include(status.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'removes status from local follower\'s home feed' do
|
|
||||||
subject.call(status)
|
|
||||||
expect(HomeFeed.new(jeff).get(10).pluck(:id)).to_not include(status.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'publishes to public media timeline' do
|
|
||||||
allow(redis).to receive(:publish).with(any_args)
|
allow(redis).to receive(:publish).with(any_args)
|
||||||
|
|
||||||
subject.call(status)
|
expect { subject.call(status) }
|
||||||
|
.to remove_status_from_notifications
|
||||||
|
|
||||||
expect(redis).to have_received(:publish).with('timeline:public:media', Oj.dump(event: :delete, payload: status.id.to_s))
|
expect(home_feed_ids(alice))
|
||||||
end
|
.to_not include(status.id)
|
||||||
|
expect(home_feed_ids(jeff))
|
||||||
|
.to_not include(status.id)
|
||||||
|
|
||||||
it 'sends Delete activity to followers' do
|
expect(redis)
|
||||||
subject.call(status)
|
.to have_received(:publish).with('timeline:public:media', Oj.dump(event: :delete, payload: status.id.to_s))
|
||||||
|
|
||||||
expect(delete_delivery(hank, status))
|
expect(delete_delivery(hank, status))
|
||||||
.to have_been_made.once
|
.to have_been_made.once
|
||||||
end
|
|
||||||
|
|
||||||
it 'sends Delete activity to rebloggers' do
|
|
||||||
subject.call(status)
|
|
||||||
|
|
||||||
expect(delete_delivery(bill, status))
|
expect(delete_delivery(bill, status))
|
||||||
.to have_been_made.once
|
.to have_been_made.once
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'remove status from notifications' do
|
def home_feed_ids(personage)
|
||||||
expect { subject.call(status) }.to change {
|
HomeFeed
|
||||||
Notification.where(activity_type: 'Favourite', from_account: jeff, account: alice).count
|
.new(personage)
|
||||||
}.from(1).to(0)
|
.get(10)
|
||||||
|
.pluck(:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_status_from_notifications
|
||||||
|
change { Notification.where(activity_type: 'Favourite', from_account: jeff, account: alice).count }
|
||||||
|
.from(1)
|
||||||
|
.to(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_delivery(target, status)
|
def delete_delivery(target, status)
|
||||||
|
|
|
@ -31,14 +31,13 @@ RSpec.describe ReportService do
|
||||||
context 'when forward is true', :inline_jobs do
|
context 'when forward is true', :inline_jobs do
|
||||||
let(:forward) { true }
|
let(:forward) { true }
|
||||||
|
|
||||||
it 'sends ActivityPub payload when forward is true' do
|
it 'has a URI and sends ActivityPub payload' do
|
||||||
subject.call(source_account, remote_account, forward: forward)
|
|
||||||
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'has an uri' do
|
|
||||||
report = subject.call(source_account, remote_account, forward: forward)
|
report = subject.call(source_account, remote_account, forward: forward)
|
||||||
expect(report.uri).to_not be_nil
|
|
||||||
|
expect(report.uri)
|
||||||
|
.to_not be_nil
|
||||||
|
expect(a_request(:post, 'http://example.com/inbox'))
|
||||||
|
.to have_been_made
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when reporting a reply on a different remote server' do
|
context 'when reporting a reply on a different remote server' do
|
||||||
|
@ -122,13 +121,12 @@ RSpec.describe ReportService do
|
||||||
status.mentions.create(account: source_account)
|
status.mentions.create(account: source_account)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a report' do
|
it 'creates a report and attaches the DM to the report' do
|
||||||
expect { subject.call }.to change { target_account.targeted_reports.count }.from(0).to(1)
|
expect { subject.call }
|
||||||
end
|
.to change { target_account.targeted_reports.count }.from(0).to(1)
|
||||||
|
|
||||||
it 'attaches the DM to the report' do
|
expect(target_account.targeted_reports.pluck(:status_ids))
|
||||||
subject.call
|
.to eq [[status.id]]
|
||||||
expect(target_account.targeted_reports.pluck(:status_ids)).to eq [[status.id]]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -146,13 +144,12 @@ RSpec.describe ReportService do
|
||||||
status.mentions.create(account: source_account)
|
status.mentions.create(account: source_account)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a report' do
|
it 'creates a report and attaches DM to report' do
|
||||||
expect { subject.call }.to change { target_account.targeted_reports.count }.from(0).to(1)
|
expect { subject.call }
|
||||||
end
|
.to change { target_account.targeted_reports.count }.from(0).to(1)
|
||||||
|
|
||||||
it 'attaches the DM to the report' do
|
expect(target_account.targeted_reports.pluck(:status_ids))
|
||||||
subject.call
|
.to eq [[status.id]]
|
||||||
expect(target_account.targeted_reports.pluck(:status_ids)).to eq [[status.id]]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -22,37 +22,38 @@ RSpec.describe ResolveAccountService do
|
||||||
context 'when domain is banned' do
|
context 'when domain is banned' do
|
||||||
before { Fabricate(:domain_block, domain: 'ap.example.com', severity: :suspend) }
|
before { Fabricate(:domain_block, domain: 'ap.example.com', severity: :suspend) }
|
||||||
|
|
||||||
it 'does not return an account' do
|
it 'does not return an account or make a webfinger query' do
|
||||||
expect(subject.call('foo@ap.example.com', skip_webfinger: true)).to be_nil
|
expect(subject.call('foo@ap.example.com', skip_webfinger: true))
|
||||||
end
|
.to be_nil
|
||||||
|
expect(webfinger_discovery_request)
|
||||||
it 'does not make a webfinger query' do
|
.to_not have_been_made
|
||||||
subject.call('foo@ap.example.com', skip_webfinger: true)
|
|
||||||
expect(a_request(:get, 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com')).to_not have_been_made
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when domain is not banned' do
|
context 'when domain is not banned' do
|
||||||
it 'returns the expected account' do
|
it 'returns the expected account and does not make a webfinger query' do
|
||||||
expect(subject.call('foo@ap.example.com', skip_webfinger: true)).to eq remote_account
|
expect(subject.call('foo@ap.example.com', skip_webfinger: true))
|
||||||
end
|
.to eq remote_account
|
||||||
|
expect(webfinger_discovery_request)
|
||||||
it 'does not make a webfinger query' do
|
.to_not have_been_made
|
||||||
subject.call('foo@ap.example.com', skip_webfinger: true)
|
|
||||||
expect(a_request(:get, 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com')).to_not have_been_made
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when account is not known' do
|
context 'when account is not known' do
|
||||||
it 'does not return an account' do
|
it 'does not return an account and does not make webfinger query' do
|
||||||
expect(subject.call('foo@ap.example.com', skip_webfinger: true)).to be_nil
|
expect(subject.call('foo@ap.example.com', skip_webfinger: true))
|
||||||
|
.to be_nil
|
||||||
|
expect(webfinger_discovery_request)
|
||||||
|
.to_not have_been_made
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not make a webfinger query' do
|
def webfinger_discovery_request
|
||||||
subject.call('foo@ap.example.com', skip_webfinger: true)
|
a_request(
|
||||||
expect(a_request(:get, 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com')).to_not have_been_made
|
:get,
|
||||||
end
|
'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com'
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -84,13 +85,11 @@ RSpec.describe ResolveAccountService do
|
||||||
allow(AccountDeletionWorker).to receive(:perform_async)
|
allow(AccountDeletionWorker).to receive(:perform_async)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns nil' do
|
it 'returns nil and queues deletion worker' do
|
||||||
expect(subject.call('hoge@example.com')).to be_nil
|
expect(subject.call('hoge@example.com'))
|
||||||
end
|
.to be_nil
|
||||||
|
expect(AccountDeletionWorker)
|
||||||
it 'queues account deletion worker' do
|
.to have_received(:perform_async)
|
||||||
subject.call('hoge@example.com')
|
|
||||||
expect(AccountDeletionWorker).to have_received(:perform_async)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -110,9 +109,12 @@ RSpec.describe ResolveAccountService do
|
||||||
it 'returns new remote account' do
|
it 'returns new remote account' do
|
||||||
account = subject.call('Foo@redirected.example.com')
|
account = subject.call('Foo@redirected.example.com')
|
||||||
|
|
||||||
expect(account.activitypub?).to be true
|
expect(account)
|
||||||
expect(account.acct).to eq 'foo@ap.example.com'
|
.to have_attributes(
|
||||||
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
|
activitypub?: true,
|
||||||
|
acct: 'foo@ap.example.com',
|
||||||
|
inbox_url: 'https://ap.example.com/users/foo/inbox'
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -125,9 +127,12 @@ RSpec.describe ResolveAccountService do
|
||||||
it 'returns new remote account' do
|
it 'returns new remote account' do
|
||||||
account = subject.call('Foo@redirected.example.com')
|
account = subject.call('Foo@redirected.example.com')
|
||||||
|
|
||||||
expect(account.activitypub?).to be true
|
expect(account)
|
||||||
expect(account.acct).to eq 'foo@ap.example.com'
|
.to have_attributes(
|
||||||
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
|
activitypub?: true,
|
||||||
|
acct: 'foo@ap.example.com',
|
||||||
|
inbox_url: 'https://ap.example.com/users/foo/inbox'
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -161,9 +166,12 @@ RSpec.describe ResolveAccountService do
|
||||||
it 'returns new remote account' do
|
it 'returns new remote account' do
|
||||||
account = subject.call('foo@ap.example.com')
|
account = subject.call('foo@ap.example.com')
|
||||||
|
|
||||||
expect(account.activitypub?).to be true
|
expect(account)
|
||||||
expect(account.domain).to eq 'ap.example.com'
|
.to have_attributes(
|
||||||
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
|
activitypub?: true,
|
||||||
|
domain: 'ap.example.com',
|
||||||
|
inbox_url: 'https://ap.example.com/users/foo/inbox'
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with multiple types' do
|
context 'with multiple types' do
|
||||||
|
@ -174,10 +182,13 @@ RSpec.describe ResolveAccountService do
|
||||||
it 'returns new remote account' do
|
it 'returns new remote account' do
|
||||||
account = subject.call('foo@ap.example.com')
|
account = subject.call('foo@ap.example.com')
|
||||||
|
|
||||||
expect(account.activitypub?).to be true
|
expect(account)
|
||||||
expect(account.domain).to eq 'ap.example.com'
|
.to have_attributes(
|
||||||
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
|
activitypub?: true,
|
||||||
expect(account.actor_type).to eq 'Person'
|
domain: 'ap.example.com',
|
||||||
|
inbox_url: 'https://ap.example.com/users/foo/inbox',
|
||||||
|
actor_type: 'Person'
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -186,20 +197,21 @@ RSpec.describe ResolveAccountService do
|
||||||
let!(:duplicate) { Fabricate(:account, username: 'foo', domain: 'old.example.com', uri: 'https://ap.example.com/users/foo') }
|
let!(:duplicate) { Fabricate(:account, username: 'foo', domain: 'old.example.com', uri: 'https://ap.example.com/users/foo') }
|
||||||
let!(:status) { Fabricate(:status, account: duplicate, text: 'foo') }
|
let!(:status) { Fabricate(:status, account: duplicate, text: 'foo') }
|
||||||
|
|
||||||
it 'returns new remote account' do
|
it 'returns new remote account and merges accounts', :inline_jobs do
|
||||||
account = subject.call('foo@ap.example.com')
|
account = subject.call('foo@ap.example.com')
|
||||||
|
|
||||||
expect(account.activitypub?).to be true
|
expect(account)
|
||||||
expect(account.domain).to eq 'ap.example.com'
|
.to have_attributes(
|
||||||
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
|
activitypub?: true,
|
||||||
expect(account.uri).to eq 'https://ap.example.com/users/foo'
|
domain: 'ap.example.com',
|
||||||
end
|
inbox_url: 'https://ap.example.com/users/foo/inbox',
|
||||||
|
uri: 'https://ap.example.com/users/foo'
|
||||||
|
)
|
||||||
|
|
||||||
it 'merges accounts', :inline_jobs do
|
expect(status.reload.account_id)
|
||||||
account = subject.call('foo@ap.example.com')
|
.to eq account.id
|
||||||
|
expect(Account.where(uri: account.uri).count)
|
||||||
expect(status.reload.account_id).to eq account.id
|
.to eq 1
|
||||||
expect(Account.where(uri: account.uri).count).to eq 1
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -210,11 +222,15 @@ RSpec.describe ResolveAccountService do
|
||||||
it 'returns new remote account' do
|
it 'returns new remote account' do
|
||||||
account = subject.call('foo@ap.example.com')
|
account = subject.call('foo@ap.example.com')
|
||||||
|
|
||||||
expect(account.activitypub?).to be true
|
expect(account)
|
||||||
expect(account.domain).to eq 'ap.example.com'
|
.to have_attributes(
|
||||||
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
|
activitypub?: true,
|
||||||
expect(account.uri).to eq 'https://ap.example.com/users/foo'
|
domain: 'ap.example.com',
|
||||||
expect(status.reload.account).to eq(account)
|
inbox_url: 'https://ap.example.com/users/foo/inbox',
|
||||||
|
uri: 'https://ap.example.com/users/foo'
|
||||||
|
)
|
||||||
|
expect(status.reload.account)
|
||||||
|
.to eq(account)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,11 @@ RSpec.describe ResolveURLService do
|
||||||
let(:url) { 'https://example.com/@foo/42' }
|
let(:url) { 'https://example.com/@foo/42' }
|
||||||
let(:uri) { 'https://example.com/users/foo/statuses/42' }
|
let(:uri) { 'https://example.com/users/foo/statuses/42' }
|
||||||
|
|
||||||
it 'returns status by url' do
|
it 'returns status by URL or URI' do
|
||||||
expect(subject.call(url, on_behalf_of: account)).to eq(status)
|
expect(subject.call(url, on_behalf_of: account))
|
||||||
end
|
.to eq(status)
|
||||||
|
expect(subject.call(uri, on_behalf_of: account))
|
||||||
it 'returns status by uri' do
|
.to eq(status)
|
||||||
expect(subject.call(uri, on_behalf_of: account)).to eq(status)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -75,12 +74,11 @@ RSpec.describe ResolveURLService do
|
||||||
let(:url) { 'https://example.com/@foo/42' }
|
let(:url) { 'https://example.com/@foo/42' }
|
||||||
let(:uri) { 'https://example.com/users/foo/statuses/42' }
|
let(:uri) { 'https://example.com/users/foo/statuses/42' }
|
||||||
|
|
||||||
it 'does not return the status by url' do
|
it 'does not return the status by URL or URI' do
|
||||||
expect(subject.call(url, on_behalf_of: account)).to be_nil
|
expect(subject.call(url, on_behalf_of: account))
|
||||||
end
|
.to be_nil
|
||||||
|
expect(subject.call(uri, on_behalf_of: account))
|
||||||
it 'does not return the status by uri' do
|
.to be_nil
|
||||||
expect(subject.call(uri, on_behalf_of: account)).to be_nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -107,22 +105,20 @@ RSpec.describe ResolveURLService do
|
||||||
account.follow!(poster)
|
account.follow!(poster)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns status by url' do
|
it 'returns status by URL or URI' do
|
||||||
expect(subject.call(url, on_behalf_of: account)).to eq(status)
|
expect(subject.call(url, on_behalf_of: account))
|
||||||
end
|
.to eq(status)
|
||||||
|
expect(subject.call(uri, on_behalf_of: account))
|
||||||
it 'returns status by uri' do
|
.to eq(status)
|
||||||
expect(subject.call(uri, on_behalf_of: account)).to eq(status)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the account does not follow the poster' do
|
context 'when the account does not follow the poster' do
|
||||||
it 'does not return the status by url' do
|
it 'does not return the status by URL or URI' do
|
||||||
expect(subject.call(url, on_behalf_of: account)).to be_nil
|
expect(subject.call(url, on_behalf_of: account))
|
||||||
end
|
.to be_nil
|
||||||
|
expect(subject.call(uri, on_behalf_of: account))
|
||||||
it 'does not return the status by uri' do
|
.to be_nil
|
||||||
expect(subject.call(uri, on_behalf_of: account)).to be_nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,20 +32,14 @@ RSpec.describe TranslateStatusService do
|
||||||
allow(TranslationService).to receive_messages(configured?: true, configured: translation_service)
|
allow(TranslationService).to receive_messages(configured?: true, configured: translation_service)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns translated status content' do
|
it 'returns translated status content and source language and provider and original status' do
|
||||||
expect(service.call(status, 'es').content).to eq '<p>Hola</p>'
|
expect(service.call(status, 'es'))
|
||||||
end
|
.to have_attributes(
|
||||||
|
content: '<p>Hola</p>',
|
||||||
it 'returns source language' do
|
detected_source_language: 'en',
|
||||||
expect(service.call(status, 'es').detected_source_language).to eq 'en'
|
provider: 'Dummy',
|
||||||
end
|
status: status
|
||||||
|
)
|
||||||
it 'returns translation provider' do
|
|
||||||
expect(service.call(status, 'es').provider).to eq 'Dummy'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns original status' do
|
|
||||||
expect(service.call(status, 'es').status).to eq status
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'status has content with custom emoji' do
|
describe 'status has content with custom emoji' do
|
||||||
|
@ -155,26 +149,16 @@ RSpec.describe TranslateStatusService do
|
||||||
let!(:source_texts) { service.send(:source_texts) }
|
let!(:source_texts) { service.send(:source_texts) }
|
||||||
|
|
||||||
it 'returns formatted poll options' do
|
it 'returns formatted poll options' do
|
||||||
expect(source_texts.size).to eq 3
|
expect(source_texts)
|
||||||
expect(source_texts.values).to eq %w(<p>Hello</p> Blue Green)
|
.to have_attributes(
|
||||||
end
|
size: 3,
|
||||||
|
values: %w(<p>Hello</p> Blue Green),
|
||||||
it 'has a first key with content' do
|
keys: contain_exactly(
|
||||||
expect(source_texts.keys.first).to eq :content
|
eq(:content),
|
||||||
end
|
be_a(Poll::Option).and(have_attributes(id: '0', title: 'Blue')),
|
||||||
|
be_a(Poll::Option).and(have_attributes(id: '1', title: 'Green'))
|
||||||
it 'has the first option in the second key with correct options' do
|
)
|
||||||
option1 = source_texts.keys.second
|
)
|
||||||
expect(option1).to be_a Poll::Option
|
|
||||||
expect(option1.id).to eq '0'
|
|
||||||
expect(option1.title).to eq 'Blue'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'has the second option in the third key with correct options' do
|
|
||||||
option2 = source_texts.keys.third
|
|
||||||
expect(option2).to be_a Poll::Option
|
|
||||||
expect(option2.id).to eq '1'
|
|
||||||
expect(option2.title).to eq 'Green'
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,21 +12,26 @@ RSpec.describe UnblockDomainService do
|
||||||
let!(:silenced) { Fabricate(:account, domain: 'example.com', silenced_at: domain_block.created_at) }
|
let!(:silenced) { Fabricate(:account, domain: 'example.com', silenced_at: domain_block.created_at) }
|
||||||
let!(:suspended) { Fabricate(:account, domain: 'example.com', suspended_at: domain_block.created_at) }
|
let!(:suspended) { Fabricate(:account, domain: 'example.com', suspended_at: domain_block.created_at) }
|
||||||
|
|
||||||
it 'unsilences accounts and removes block' do
|
context 'with severity of silence' do
|
||||||
domain_block.update(severity: :silence)
|
before { domain_block.update(severity: :silence) }
|
||||||
|
|
||||||
|
it 'unsilences accounts and removes block' do
|
||||||
subject.call(domain_block)
|
subject.call(domain_block)
|
||||||
|
|
||||||
expect_deleted_domain_block
|
expect_deleted_domain_block
|
||||||
expect(silenced.reload.silenced?).to be false
|
expect(silenced.reload.silenced?).to be false
|
||||||
expect(suspended.reload.suspended?).to be true
|
expect(suspended.reload.suspended?).to be true
|
||||||
expect(independently_suspended.reload.suspended?).to be true
|
expect(independently_suspended.reload.suspended?).to be true
|
||||||
expect(independently_silenced.reload.silenced?).to be true
|
expect(independently_silenced.reload.silenced?).to be true
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with severity of suspend' do
|
||||||
|
before { domain_block.update(severity: :suspend) }
|
||||||
|
|
||||||
it 'unsuspends accounts and removes block' do
|
it 'unsuspends accounts and removes block' do
|
||||||
domain_block.update(severity: :suspend)
|
|
||||||
|
|
||||||
subject.call(domain_block)
|
subject.call(domain_block)
|
||||||
|
|
||||||
expect_deleted_domain_block
|
expect_deleted_domain_block
|
||||||
expect(suspended.reload.suspended?).to be false
|
expect(suspended.reload.suspended?).to be false
|
||||||
expect(silenced.reload.silenced?).to be false
|
expect(silenced.reload.silenced?).to be false
|
||||||
|
@ -34,6 +39,7 @@ RSpec.describe UnblockDomainService do
|
||||||
expect(independently_silenced.reload.silenced?).to be true
|
expect(independently_silenced.reload.silenced?).to be true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def expect_deleted_domain_block
|
def expect_deleted_domain_block
|
||||||
expect { domain_block.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
expect { domain_block.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||||
|
|
|
@ -10,13 +10,13 @@ RSpec.describe UnblockService do
|
||||||
describe 'local' do
|
describe 'local' do
|
||||||
let(:bob) { Fabricate(:account) }
|
let(:bob) { Fabricate(:account) }
|
||||||
|
|
||||||
before do
|
before { sender.block!(bob) }
|
||||||
sender.block!(bob)
|
|
||||||
subject.call(sender, bob)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'destroys the blocking relation' do
|
it 'destroys the blocking relation' do
|
||||||
expect(sender.blocking?(bob)).to be false
|
subject.call(sender, bob)
|
||||||
|
|
||||||
|
expect(sender)
|
||||||
|
.to_not be_blocking(bob)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,15 +26,15 @@ RSpec.describe UnblockService do
|
||||||
before do
|
before do
|
||||||
sender.block!(bob)
|
sender.block!(bob)
|
||||||
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'destroys the blocking relation and sends unblock activity', :inline_jobs do
|
||||||
subject.call(sender, bob)
|
subject.call(sender, bob)
|
||||||
end
|
|
||||||
|
|
||||||
it 'destroys the blocking relation' do
|
expect(sender)
|
||||||
expect(sender.blocking?(bob)).to be false
|
.to_not be_blocking(bob)
|
||||||
end
|
expect(a_request(:post, 'http://example.com/inbox'))
|
||||||
|
.to have_been_made.once
|
||||||
it 'sends an unblock activity', :inline_jobs do
|
|
||||||
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,13 +10,13 @@ RSpec.describe UnfollowService do
|
||||||
describe 'local' do
|
describe 'local' do
|
||||||
let(:bob) { Fabricate(:account, username: 'bob') }
|
let(:bob) { Fabricate(:account, username: 'bob') }
|
||||||
|
|
||||||
before do
|
before { sender.follow!(bob) }
|
||||||
sender.follow!(bob)
|
|
||||||
subject.call(sender, bob)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'destroys the following relation' do
|
it 'destroys the following relation' do
|
||||||
expect(sender.following?(bob)).to be false
|
subject.call(sender, bob)
|
||||||
|
|
||||||
|
expect(sender)
|
||||||
|
.to_not be_following(bob)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,15 +26,15 @@ RSpec.describe UnfollowService do
|
||||||
before do
|
before do
|
||||||
sender.follow!(bob)
|
sender.follow!(bob)
|
||||||
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'destroys the following relation and sends unfollow activity' do
|
||||||
subject.call(sender, bob)
|
subject.call(sender, bob)
|
||||||
end
|
|
||||||
|
|
||||||
it 'destroys the following relation' do
|
expect(sender)
|
||||||
expect(sender.following?(bob)).to be false
|
.to_not be_following(bob)
|
||||||
end
|
expect(a_request(:post, 'http://example.com/inbox'))
|
||||||
|
.to have_been_made.once
|
||||||
it 'sends an unfollow activity' do
|
|
||||||
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,15 +44,15 @@ RSpec.describe UnfollowService do
|
||||||
before do
|
before do
|
||||||
bob.follow!(sender)
|
bob.follow!(sender)
|
||||||
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'destroys the following relation and sends a reject activity' do
|
||||||
subject.call(bob, sender)
|
subject.call(bob, sender)
|
||||||
end
|
|
||||||
|
|
||||||
it 'destroys the following relation' do
|
expect(sender)
|
||||||
expect(bob.following?(sender)).to be false
|
.to_not be_following(bob)
|
||||||
end
|
expect(a_request(:post, 'http://example.com/inbox'))
|
||||||
|
.to have_been_made.once
|
||||||
it 'sends a reject activity' do
|
|
||||||
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,23 +18,19 @@ RSpec.describe UpdateAccountService do
|
||||||
FollowService.new.call(alice, account)
|
FollowService.new.call(alice, account)
|
||||||
FollowService.new.call(bob, account)
|
FollowService.new.call(bob, account)
|
||||||
FollowService.new.call(eve, account)
|
FollowService.new.call(eve, account)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'auto accepts pending follow requests from appropriate accounts' do
|
||||||
subject.call(account, { locked: false })
|
subject.call(account, { locked: false })
|
||||||
end
|
|
||||||
|
|
||||||
it 'auto-accepts pending follow requests' do
|
expect(alice).to be_following(account)
|
||||||
expect(alice.following?(account)).to be true
|
expect(alice).to_not be_requested(account)
|
||||||
expect(alice.requested?(account)).to be false
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not auto-accept pending follow requests from silenced users' do
|
expect(bob).to_not be_following(account)
|
||||||
expect(bob.following?(account)).to be false
|
expect(bob).to be_requested(account)
|
||||||
expect(bob.requested?(account)).to be true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'auto-accepts pending follow requests from muted users so as to not leak mute' do
|
expect(eve).to be_following(account)
|
||||||
expect(eve.following?(account)).to be true
|
expect(eve).to_not be_requested(account)
|
||||||
expect(eve.requested?(account)).to be false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,15 +10,15 @@ RSpec.describe UpdateStatusService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(ActivityPub::DistributionWorker).to receive(:perform_async)
|
allow(ActivityPub::DistributionWorker).to receive(:perform_async)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not create an edit or notify anyone' do
|
||||||
subject.call(status, status.account_id, text: 'Foo')
|
subject.call(status, status.account_id, text: 'Foo')
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not create an edit' do
|
expect(status.reload.edits)
|
||||||
expect(status.reload.edits).to be_empty
|
.to be_empty
|
||||||
end
|
expect(ActivityPub::DistributionWorker)
|
||||||
|
.to_not have_received(:perform_async)
|
||||||
it 'does not notify anyone' do
|
|
||||||
expect(ActivityPub::DistributionWorker).to_not have_received(:perform_async)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -28,18 +28,16 @@ RSpec.describe UpdateStatusService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
PreviewCardsStatus.create(status: status, preview_card: preview_card)
|
PreviewCardsStatus.create(status: status, preview_card: preview_card)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates text, resets card, saves edit history' do
|
||||||
subject.call(status, status.account_id, text: 'Bar')
|
subject.call(status, status.account_id, text: 'Bar')
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates text' do
|
expect(status.reload)
|
||||||
expect(status.reload.text).to eq 'Bar'
|
.to have_attributes(
|
||||||
end
|
text: 'Bar',
|
||||||
|
preview_card: be_nil
|
||||||
it 'resets preview card' do
|
)
|
||||||
expect(status.reload.preview_card).to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'saves edit history' do
|
|
||||||
expect(status.edits.ordered.pluck(:text)).to eq %w(Foo Bar)
|
expect(status.edits.ordered.pluck(:text)).to eq %w(Foo Bar)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -50,15 +48,15 @@ RSpec.describe UpdateStatusService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
PreviewCardsStatus.create(status: status, preview_card: preview_card)
|
PreviewCardsStatus.create(status: status, preview_card: preview_card)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates content warning and saves history' do
|
||||||
subject.call(status, status.account_id, text: 'Foo', spoiler_text: 'Bar')
|
subject.call(status, status.account_id, text: 'Foo', spoiler_text: 'Bar')
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates content warning' do
|
expect(status.reload.spoiler_text)
|
||||||
expect(status.reload.spoiler_text).to eq 'Bar'
|
.to eq 'Bar'
|
||||||
end
|
expect(status.edits.ordered.pluck(:text, :spoiler_text))
|
||||||
|
.to eq [['Foo', ''], ['Foo', 'Bar']]
|
||||||
it 'saves edit history' do
|
|
||||||
expect(status.edits.ordered.pluck(:text, :spoiler_text)).to eq [['Foo', ''], ['Foo', 'Bar']]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -69,23 +67,19 @@ RSpec.describe UpdateStatusService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
status.media_attachments << detached_media_attachment
|
status.media_attachments << detached_media_attachment
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates media attachments, handles attachments, saves history' do
|
||||||
subject.call(status, status.account_id, text: 'Foo', media_ids: [attached_media_attachment.id.to_s])
|
subject.call(status, status.account_id, text: 'Foo', media_ids: [attached_media_attachment.id.to_s])
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates media attachments' do
|
expect(status.ordered_media_attachments)
|
||||||
expect(status.ordered_media_attachments).to eq [attached_media_attachment]
|
.to eq [attached_media_attachment]
|
||||||
end
|
expect(detached_media_attachment.reload.status_id)
|
||||||
|
.to eq status.id
|
||||||
it 'does not detach detached media attachments' do
|
expect(attached_media_attachment.reload.status_id)
|
||||||
expect(detached_media_attachment.reload.status_id).to eq status.id
|
.to eq status.id
|
||||||
end
|
expect(status.edits.ordered.pluck(:ordered_media_attachment_ids))
|
||||||
|
.to eq [[detached_media_attachment.id], [attached_media_attachment.id]]
|
||||||
it 'attaches attached media attachments' do
|
|
||||||
expect(attached_media_attachment.reload.status_id).to eq status.id
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'saves edit history' do
|
|
||||||
expect(status.edits.ordered.pluck(:ordered_media_attachment_ids)).to eq [[detached_media_attachment.id], [attached_media_attachment.id]]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -95,19 +89,18 @@ RSpec.describe UpdateStatusService do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
status.media_attachments << media_attachment
|
status.media_attachments << media_attachment
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not detach media attachment, updates description, and saves history' do
|
||||||
subject.call(status, status.account_id, text: 'Foo', media_ids: [media_attachment.id.to_s], media_attributes: [{ id: media_attachment.id, description: 'New description' }])
|
subject.call(status, status.account_id, text: 'Foo', media_ids: [media_attachment.id.to_s], media_attributes: [{ id: media_attachment.id, description: 'New description' }])
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not detach media attachment' do
|
expect(media_attachment.reload)
|
||||||
expect(media_attachment.reload.status_id).to eq status.id
|
.to have_attributes(
|
||||||
end
|
status_id: status.id,
|
||||||
|
description: 'New description'
|
||||||
it 'updates the media attachment description' do
|
)
|
||||||
expect(media_attachment.reload.description).to eq 'New description'
|
expect(status.edits.ordered.map { |edit| edit.ordered_media_attachments.map(&:description) })
|
||||||
end
|
.to eq [['Old description'], ['New description']]
|
||||||
|
|
||||||
it 'saves edit history' do
|
|
||||||
expect(status.edits.ordered.map { |edit| edit.ordered_media_attachments.map(&:description) }).to eq [['Old description'], ['New description']]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -120,28 +113,27 @@ RSpec.describe UpdateStatusService do
|
||||||
before do
|
before do
|
||||||
status.update(poll: poll)
|
status.update(poll: poll)
|
||||||
VoteService.new.call(voter, poll, [0])
|
VoteService.new.call(voter, poll, [0])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates poll, resets votes, saves history, requeues notifications' do
|
||||||
subject.call(status, status.account_id, text: 'Foo', poll: { options: %w(Bar Baz Foo), expires_in: 5.days.to_i })
|
subject.call(status, status.account_id, text: 'Foo', poll: { options: %w(Bar Baz Foo), expires_in: 5.days.to_i })
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates poll' do
|
|
||||||
poll = status.poll.reload
|
poll = status.poll.reload
|
||||||
expect(poll.options).to eq %w(Bar Baz Foo)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'resets votes' do
|
expect(poll)
|
||||||
poll = status.poll.reload
|
.to have_attributes(
|
||||||
expect(poll.votes_count).to eq 0
|
options: %w(Bar Baz Foo),
|
||||||
expect(poll.votes.count).to eq 0
|
votes_count: 0,
|
||||||
expect(poll.cached_tallies).to eq [0, 0, 0]
|
cached_tallies: [0, 0, 0]
|
||||||
end
|
)
|
||||||
|
expect(poll.votes.count)
|
||||||
|
.to eq(0)
|
||||||
|
|
||||||
it 'saves edit history' do
|
expect(status.edits.ordered.pluck(:poll_options))
|
||||||
expect(status.edits.ordered.pluck(:poll_options)).to eq [%w(Foo Bar), %w(Bar Baz Foo)]
|
.to eq [%w(Foo Bar), %w(Bar Baz Foo)]
|
||||||
end
|
|
||||||
|
|
||||||
it 'requeues expiration notification' do
|
expect(PollExpirationNotifyWorker)
|
||||||
poll = status.poll.reload
|
.to have_enqueued_sidekiq_job(poll.id).at(poll.expires_at + 5.minutes)
|
||||||
expect(PollExpirationNotifyWorker).to have_enqueued_sidekiq_job(poll.id).at(poll.expires_at + 5.minutes)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -151,16 +143,13 @@ RSpec.describe UpdateStatusService do
|
||||||
let!(:bob) { Fabricate(:account, username: 'bob') }
|
let!(:bob) { Fabricate(:account, username: 'bob') }
|
||||||
let!(:status) { PostStatusService.new.call(account, text: 'Hello @alice') }
|
let!(:status) { PostStatusService.new.call(account, text: 'Hello @alice') }
|
||||||
|
|
||||||
before do
|
it 'changes mentions and keeps old as silent' do
|
||||||
subject.call(status, status.account_id, text: 'Hello @bob')
|
subject.call(status, status.account_id, text: 'Hello @bob')
|
||||||
end
|
|
||||||
|
|
||||||
it 'changes mentions' do
|
expect(status.active_mentions.pluck(:account_id))
|
||||||
expect(status.active_mentions.pluck(:account_id)).to eq [bob.id]
|
.to eq [bob.id]
|
||||||
end
|
expect(status.mentions.pluck(:account_id))
|
||||||
|
.to contain_exactly(alice.id, bob.id)
|
||||||
it 'keeps old mentions as silent mentions' do
|
|
||||||
expect(status.mentions.pluck(:account_id)).to contain_exactly(alice.id, bob.id)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -168,11 +157,9 @@ RSpec.describe UpdateStatusService do
|
||||||
let!(:account) { Fabricate(:account) }
|
let!(:account) { Fabricate(:account) }
|
||||||
let!(:status) { PostStatusService.new.call(account, text: 'Hello #foo') }
|
let!(:status) { PostStatusService.new.call(account, text: 'Hello #foo') }
|
||||||
|
|
||||||
before do
|
|
||||||
subject.call(status, status.account_id, text: 'Hello #bar')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'changes tags' do
|
it 'changes tags' do
|
||||||
|
subject.call(status, status.account_id, text: 'Hello #bar')
|
||||||
|
|
||||||
expect(status.tags.pluck(:name)).to eq %w(bar)
|
expect(status.tags.pluck(:name)).to eq %w(bar)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue