Merge remote-tracking branch 'parent/main' into upstream-20231120

This commit is contained in:
KMY 2023-11-20 12:50:02 +09:00
commit abec232dd7
85 changed files with 1314 additions and 458 deletions

View file

@ -0,0 +1,52 @@
# frozen_string_literal: true
require 'rails_helper'
describe AccountRefreshWorker do
let(:worker) { described_class.new }
let(:service) { instance_double(ResolveAccountService, call: true) }
describe '#perform' do
before do
allow(ResolveAccountService).to receive(:new).and_return(service)
end
context 'when account does not exist' do
it 'returns immediately without processing' do
worker.perform(123_123_123)
expect(service).to_not have_received(:call)
end
end
context 'when account exists' do
context 'when account does not need refreshing' do
let(:account) { Fabricate(:account, last_webfingered_at: recent_webfinger_at) }
it 'returns immediately without processing' do
worker.perform(account.id)
expect(service).to_not have_received(:call)
end
end
context 'when account needs refreshing' do
let(:account) { Fabricate(:account, last_webfingered_at: outdated_webfinger_at) }
it 'schedules an account update' do
worker.perform(account.id)
expect(service).to have_received(:call)
end
end
def recent_webfinger_at
(Account::BACKGROUND_REFRESH_INTERVAL - 3.days).ago
end
def outdated_webfinger_at
(Account::BACKGROUND_REFRESH_INTERVAL + 3.days).ago
end
end
end
end

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
require 'rails_helper'
describe ActivityPub::PostUpgradeWorker do
let(:worker) { described_class.new }
describe '#perform' do
let(:domain) { 'host.example' }
it 'updates relevant values' do
account = Fabricate(:account, domain: domain, last_webfingered_at: 1.day.ago, protocol: :ostatus)
worker.perform(domain)
expect(account.reload.last_webfingered_at).to be_nil
end
end
end

View file

@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'rails_helper'
describe ActivityPub::SynchronizeFeaturedTagsCollectionWorker do
let(:worker) { described_class.new }
let(:service) { instance_double(ActivityPub::FetchFeaturedTagsCollectionService, call: true) }
describe '#perform' do
before do
allow(ActivityPub::FetchFeaturedTagsCollectionService).to receive(:new).and_return(service)
end
let(:account) { Fabricate(:account) }
let(:url) { 'https://host.example' }
it 'sends the account and url to the service' do
worker.perform(account.id, url)
expect(service).to have_received(:call).with(account, url)
end
it 'returns true for non-existent record' do
result = worker.perform(123_123_123, url)
expect(result).to be(true)
end
end
end

View file

@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'rails_helper'
describe Admin::SuspensionWorker do
let(:worker) { described_class.new }
let(:service) { instance_double(SuspendAccountService, call: true) }
describe '#perform' do
before do
allow(SuspendAccountService).to receive(:new).and_return(service)
end
let(:account) { Fabricate(:account) }
it 'sends the account to the service' do
worker.perform(account.id)
expect(service).to have_received(:call).with(account)
end
it 'returns true for non-existent record' do
result = worker.perform(123_123_123)
expect(result).to be(true)
end
end
end

View file

@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'rails_helper'
describe AfterAccountDomainBlockWorker do
let(:worker) { described_class.new }
let(:service) { instance_double(AfterBlockDomainFromAccountService, call: true) }
describe '#perform' do
before do
allow(AfterBlockDomainFromAccountService).to receive(:new).and_return(service)
end
let(:account) { Fabricate(:account) }
let(:domain) { 'host.example' }
it 'sends the account and domain to the service' do
worker.perform(account.id, domain)
expect(service).to have_received(:call).with(account, domain)
end
it 'returns true for non-existent record' do
result = worker.perform(123_123_123, domain)
expect(result).to be(true)
end
end
end

View file

@ -0,0 +1,36 @@
# frozen_string_literal: true
require 'rails_helper'
describe BackupWorker do
let(:worker) { described_class.new }
let(:service) { instance_double(BackupService, call: true) }
describe '#perform' do
before do
allow(BackupService).to receive(:new).and_return(service)
end
let(:backup) { Fabricate(:backup) }
let!(:other_backup) { Fabricate(:backup, user: backup.user) }
it 'sends the backup to the service and removes other backups' do
expect do
worker.perform(backup.id)
end.to change(UserMailer.deliveries, :size).by(1)
expect(service).to have_received(:call).with(backup)
expect { other_backup.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
context 'when sidekiq retries are exhausted' do
it 'destroys the backup' do
described_class.within_sidekiq_retries_exhausted_block({ 'args' => [backup.id] }) do
worker.perform(backup.id)
end
expect { backup.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
end

View file

@ -0,0 +1,42 @@
# frozen_string_literal: true
require 'rails_helper'
describe DeleteMuteWorker do
let(:worker) { described_class.new }
let(:service) { instance_double(UnmuteService, call: true) }
describe '#perform' do
before do
allow(UnmuteService).to receive(:new).and_return(service)
end
context 'with an expired mute' do
let(:mute) { Fabricate(:mute, expires_at: 1.day.ago) }
it 'sends the mute to the service' do
worker.perform(mute.id)
expect(service).to have_received(:call).with(mute.account, mute.target_account)
end
end
context 'with an unexpired mute' do
let(:mute) { Fabricate(:mute, expires_at: 1.day.from_now) }
it 'does not send the mute to the service' do
worker.perform(mute.id)
expect(service).to_not have_received(:call)
end
end
context 'with a non-existent mute' do
it 'does not send the mute to the service' do
worker.perform(123_123_123)
expect(service).to_not have_received(:call)
end
end
end
end

View file

@ -12,6 +12,7 @@ describe FeedInsertWorker do
describe 'perform' do
let(:follower) { Fabricate(:account) }
let(:status) { Fabricate(:status) }
let(:list) { Fabricate(:list) }
context 'when there are no records' do
it 'skips push with missing status' do
@ -46,11 +47,29 @@ describe FeedInsertWorker do
it 'pushes the status onto the home timeline without filter' do
instance = instance_double(FeedManager, push_to_home: nil, filter?: false)
allow(FeedManager).to receive(:instance).and_return(instance)
result = subject.perform(status.id, follower.id)
result = subject.perform(status.id, follower.id, :home)
expect(result).to be_nil
expect(instance).to have_received(:push_to_home).with(follower, status, update: nil)
end
it 'pushes the status onto the tags timeline without filter' do
instance = instance_double(FeedManager, push_to_home: nil, filter?: false)
allow(FeedManager).to receive(:instance).and_return(instance)
result = subject.perform(status.id, follower.id, :tags)
expect(result).to be_nil
expect(instance).to have_received(:push_to_home).with(follower, status, update: nil)
end
it 'pushes the status onto the list timeline without filter' do
instance = instance_double(FeedManager, push_to_list: nil, filter?: false)
allow(FeedManager).to receive(:instance).and_return(instance)
result = subject.perform(status.id, list.id, :list)
expect(result).to be_nil
expect(instance).to have_received(:push_to_list).with(list, status, update: nil)
end
end
context 'with notification' do

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
require 'rails_helper'
describe ImportWorker do
let(:worker) { described_class.new }
let(:service) { instance_double(ImportService, call: true) }
describe '#perform' do
before do
allow(ImportService).to receive(:new).and_return(service)
end
let(:import) { Fabricate(:import) }
it 'sends the import to the service' do
worker.perform(import.id)
expect(service).to have_received(:call).with(import)
expect { import.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end

View file

@ -2,12 +2,38 @@
require 'rails_helper'
describe PostProcessMediaWorker do
describe PostProcessMediaWorker, :paperclip_processing do
let(:worker) { described_class.new }
describe 'perform' do
it 'runs without error for missing record' do
expect { worker.perform(nil) }.to_not raise_error
describe '#perform' do
let(:media_attachment) { Fabricate(:media_attachment) }
it 'reprocesses and updates the media attachment' do
worker.perform(media_attachment.id)
expect(media_attachment.processing).to eq('complete')
end
it 'returns true for non-existent record' do
result = worker.perform(123_123_123)
expect(result).to be(true)
end
context 'when sidekiq retries are exhausted' do
it 'sets state to failed' do
described_class.within_sidekiq_retries_exhausted_block({ 'args' => [media_attachment.id] }) do
worker.perform(media_attachment.id)
end
expect(media_attachment.reload.processing).to eq('failed')
end
it 'returns true for non-existent record' do
described_class.within_sidekiq_retries_exhausted_block({ 'args' => [123_123_123] }) do
expect(worker.perform(123_123_123)).to be(true)
end
end
end
end
end

View file

@ -0,0 +1,38 @@
# frozen_string_literal: true
require 'rails_helper'
describe PublishAnnouncementReactionWorker do
let(:worker) { described_class.new }
describe '#perform' do
before { Fabricate(:account, user: Fabricate(:user, current_sign_in_at: 1.hour.ago)) }
let(:announcement) { Fabricate(:announcement) }
let(:name) { 'name value' }
it 'sends the announcement and name to the service when subscribed' do
allow(redis).to receive(:exists?).and_return(true)
allow(redis).to receive(:publish)
worker.perform(announcement.id, name)
expect(redis).to have_received(:publish)
end
it 'does not send the announcement and name to the service when not subscribed' do
allow(redis).to receive(:exists?).and_return(false)
allow(redis).to receive(:publish)
worker.perform(announcement.id, name)
expect(redis).to_not have_received(:publish)
end
it 'returns true for non-existent record' do
result = worker.perform(123_123_123, name)
expect(result).to be(true)
end
end
end

View file

@ -5,9 +5,48 @@ require 'rails_helper'
describe RedownloadAvatarWorker do
let(:worker) { described_class.new }
describe 'perform' do
it 'runs without error for missing record' do
expect { worker.perform(nil) }.to_not raise_error
describe '#perform' do
it 'returns nil for non-existent record' do
result = worker.perform(123_123_123)
expect(result).to be_nil
end
it 'returns nil for suspended account' do
account = Fabricate(:account, suspended_at: 10.days.ago)
expect(worker.perform(account.id)).to be_nil
end
it 'returns nil with a domain block' do
account = Fabricate(:account, domain: 'host.example')
Fabricate(:domain_block, domain: account.domain, reject_media: true)
expect(worker.perform(account.id)).to be_nil
end
it 'returns nil without an avatar remote url' do
account = Fabricate(:account, avatar_remote_url: '')
expect(worker.perform(account.id)).to be_nil
end
it 'returns nil when avatar file name is present' do
stub_request(:get, 'https://example.host/file').to_return request_fixture('avatar.txt')
account = Fabricate(:account, avatar_remote_url: 'https://example.host/file', avatar_file_name: 'test.jpg')
expect(worker.perform(account.id)).to be_nil
end
it 'reprocesses a remote avatar' do
stub_request(:get, 'https://example.host/file').to_return request_fixture('avatar.txt')
account = Fabricate(:account, avatar_remote_url: 'https://example.host/file')
account.update_column(:avatar_file_name, nil) # rubocop:disable Rails/SkipsModelValidations
result = worker.perform(account.id)
expect(result).to be(true)
expect(account.reload.avatar_file_name).to_not be_nil
end
end
end

View file

@ -5,9 +5,48 @@ require 'rails_helper'
describe RedownloadHeaderWorker do
let(:worker) { described_class.new }
describe 'perform' do
it 'runs without error for missing record' do
expect { worker.perform(nil) }.to_not raise_error
describe '#perform' do
it 'returns nil for non-existent record' do
result = worker.perform(123_123_123)
expect(result).to be_nil
end
it 'returns nil for suspended account' do
account = Fabricate(:account, suspended_at: 10.days.ago)
expect(worker.perform(account.id)).to be_nil
end
it 'returns nil with a domain block' do
account = Fabricate(:account, domain: 'host.example')
Fabricate(:domain_block, domain: account.domain, reject_media: true)
expect(worker.perform(account.id)).to be_nil
end
it 'returns nil without an header remote url' do
account = Fabricate(:account, header_remote_url: '')
expect(worker.perform(account.id)).to be_nil
end
it 'returns nil when header file name is present' do
stub_request(:get, 'https://example.host/file').to_return request_fixture('avatar.txt')
account = Fabricate(:account, header_remote_url: 'https://example.host/file', header_file_name: 'test.jpg')
expect(worker.perform(account.id)).to be_nil
end
it 'reprocesses a remote header' do
stub_request(:get, 'https://example.host/file').to_return request_fixture('avatar.txt')
account = Fabricate(:account, header_remote_url: 'https://example.host/file')
account.update_column(:header_file_name, nil) # rubocop:disable Rails/SkipsModelValidations
result = worker.perform(account.id)
expect(result).to be(true)
expect(account.reload.header_file_name).to_not be_nil
end
end
end

View file

@ -0,0 +1,37 @@
# frozen_string_literal: true
require 'rails_helper'
describe RedownloadMediaWorker do
let(:worker) { described_class.new }
describe '#perform' do
it 'returns nil for non-existent record' do
result = worker.perform(123_123_123)
expect(result).to be_nil
end
it 'returns nil without a remote_url' do
media_attachment = Fabricate(:media_attachment, remote_url: '')
result = worker.perform(media_attachment.id)
expect(result).to be_nil
end
context 'with a valid remote url' do
let(:url) { 'https://example.host/file.txt' }
before { stub_request(:get, url).to_return(status: 200) }
it 'processes downloads for valid record' do
media_attachment = Fabricate(:media_attachment, remote_url: url)
worker.perform(media_attachment.id)
expect(a_request(:get, url)).to have_been_made
end
end
end
end

View file

@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'rails_helper'
describe RemovalWorker do
let(:worker) { described_class.new }
let(:service) { instance_double(RemoveStatusService, call: true) }
describe '#perform' do
before do
allow(RemoveStatusService).to receive(:new).and_return(service)
end
let(:status) { Fabricate(:status) }
it 'sends the status to the service' do
worker.perform(status.id)
expect(service).to have_received(:call).with(status)
end
it 'returns true for non-existent record' do
result = worker.perform(123_123_123)
expect(result).to be(true)
end
end
end

View file

@ -0,0 +1,60 @@
# frozen_string_literal: true
require 'rails_helper'
describe Scheduler::SelfDestructScheduler do
let(:worker) { described_class.new }
describe '#perform' do
let!(:account) { Fabricate(:account, domain: nil, suspended_at: nil) }
context 'when not in self destruct mode' do
before do
allow(SelfDestructHelper).to receive(:self_destruct?).and_return(false)
end
it 'returns without processing' do
worker.perform
expect(account.reload.suspended_at).to be_nil
end
end
context 'when in self-destruct mode' do
before do
allow(SelfDestructHelper).to receive(:self_destruct?).and_return(true)
end
context 'when sidekiq is overwhelmed' do
before do
stats = instance_double(Sidekiq::Stats, enqueued: described_class::MAX_ENQUEUED**2)
allow(Sidekiq::Stats).to receive(:new).and_return(stats)
end
it 'returns without processing' do
worker.perform
expect(account.reload.suspended_at).to be_nil
end
end
context 'when sidekiq is operational' do
it 'suspends local non-suspended accounts' do
worker.perform
expect(account.reload.suspended_at).to_not be_nil
end
it 'suspends local suspended accounts marked for deletion' do
account.update(suspended_at: 10.days.ago)
deletion_request = Fabricate(:account_deletion_request, account: account)
worker.perform
expect(account.reload.suspended_at).to be > 1.day.ago
expect { deletion_request.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
end
end

View file

@ -5,9 +5,21 @@ require 'rails_helper'
describe Webhooks::DeliveryWorker do
let(:worker) { described_class.new }
describe 'perform' do
it 'runs without error' do
expect { worker.perform(nil, nil) }.to_not raise_error
describe '#perform' do
let(:webhook) { Fabricate(:webhook) }
it 'reprocesses and updates the webhook' do
stub_request(:post, webhook.url).to_return(status: 200, body: '')
worker.perform(webhook.id, 'body')
expect(a_request(:post, webhook.url)).to have_been_made.at_least_once
end
it 'returns true for non-existent record' do
result = worker.perform(123_123_123, '')
expect(result).to be(true)
end
end
end