1
0
Fork 0
forked from gitea/nas

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

This commit is contained in:
KMY 2024-01-18 09:17:39 +09:00
commit 2b51fabe9c
397 changed files with 2899 additions and 3252 deletions

View file

@ -137,12 +137,49 @@ RSpec.describe Auth::RegistrationsController do
context 'when user has an email address requiring approval' do
subject do
Setting.registrations_mode = 'open'
Fabricate(:email_domain_block, allow_with_approval: true, domain: 'example.com')
request.headers['Accept-Language'] = accept_language
post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
end
before do
Setting.registrations_mode = 'open'
Fabricate(:email_domain_block, allow_with_approval: true, domain: 'example.com')
end
it 'creates unapproved user and redirects to setup' do
subject
expect(response).to redirect_to auth_setup_path
user = User.find_by(email: 'test@example.com')
expect(user).to_not be_nil
expect(user.locale).to eq(accept_language)
expect(user.approved).to be(false)
end
end
context 'when user has an email address requiring approval through a MX record' do
subject do
request.headers['Accept-Language'] = accept_language
post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
end
before do
Setting.registrations_mode = 'open'
Fabricate(:email_domain_block, allow_with_approval: true, domain: 'mail.example.com')
allow(User).to receive(:skip_mx_check?).and_return(false)
resolver = instance_double(Resolv::DNS, :timeouts= => nil)
allow(resolver).to receive(:getresources)
.with('example.com', Resolv::DNS::Resource::IN::MX)
.and_return([instance_double(Resolv::DNS::Resource::MX, exchange: 'mail.example.com')])
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: '2.3.4.5')])
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([instance_double(Resolv::DNS::Resource::IN::AAAA, address: 'fd00::2')])
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
end
it 'creates unapproved user and redirects to setup' do
subject
expect(response).to redirect_to auth_setup_path

View file

@ -49,7 +49,7 @@ describe 'Using OAuth from an external app' do
let(:user) { Fabricate(:user, email: email, password: password) }
before do
user.confirm!
user.mark_email_as_confirmed!
user.approve!
end

View file

@ -660,106 +660,69 @@ describe Mastodon::CLI::Accounts do
end
describe '#refresh' do
let(:action) { :refresh }
context 'with --all option' do
let!(:local_account) { Fabricate(:account, domain: nil) }
let!(:remote_account_example_com) { Fabricate(:account, domain: 'example.com') }
let!(:account_example_net) { Fabricate(:account, domain: 'example.net') }
let(:scope) { Account.remote }
let(:options) { { all: true } }
let!(:local_account) { Fabricate(:account, domain: nil) }
let(:remote_com_avatar_url) { 'https://example.host/avatar/com' }
let(:remote_com_header_url) { 'https://example.host/header/com' }
let(:remote_account_example_com) { Fabricate(:account, domain: 'example.com', avatar_remote_url: remote_com_avatar_url, header_remote_url: remote_com_header_url) }
let(:remote_net_avatar_url) { 'https://example.host/avatar/net' }
let(:remote_net_header_url) { 'https://example.host/header/net' }
let(:account_example_net) { Fabricate(:account, domain: 'example.net', avatar_remote_url: remote_net_avatar_url, header_remote_url: remote_net_header_url) }
let(:scope) { Account.remote }
before do
# TODO: we should be using `stub_parallelize_with_progress!` but
# this makes the assertions harder to write
allow(cli).to receive(:parallelize_with_progress).and_yield(remote_account_example_com)
.and_yield(account_example_net)
.and_return([2, nil])
cli.options = { all: true }
stub_parallelize_with_progress!
stub_request(:get, remote_com_avatar_url)
.to_return request_fixture('avatar.txt')
stub_request(:get, remote_com_header_url)
.to_return request_fixture('avatar.txt')
stub_request(:get, remote_net_avatar_url)
.to_return request_fixture('avatar.txt')
stub_request(:get, remote_net_header_url)
.to_return request_fixture('avatar.txt')
remote_account_example_com
.update_column(:avatar_file_name, nil)
account_example_net
.update_column(:avatar_file_name, nil)
end
it 'refreshes the avatar for all remote accounts' do
allow(remote_account_example_com).to receive(:reset_avatar!)
allow(account_example_net).to receive(:reset_avatar!)
expect { cli.refresh }
it 'refreshes the avatar and header for all remote accounts' do
expect { subject }
.to output_results('Refreshed 2 accounts')
.and not_change(local_account, :updated_at)
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(remote_account_example_com).to have_received(:reset_avatar!).once
expect(account_example_net).to have_received(:reset_avatar!).once
end
it 'does not refresh avatar for local accounts' do
allow(local_account).to receive(:reset_avatar!)
expect { cli.refresh }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(local_account).to_not have_received(:reset_avatar!)
end
it 'refreshes the header for all remote accounts' do
allow(remote_account_example_com).to receive(:reset_header!)
allow(account_example_net).to receive(:reset_header!)
expect { cli.refresh }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(remote_account_example_com).to have_received(:reset_header!).once
expect(account_example_net).to have_received(:reset_header!).once
end
it 'does not refresh the header for local accounts' do
allow(local_account).to receive(:reset_header!)
expect { cli.refresh }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(local_account).to_not have_received(:reset_header!)
end
it 'displays a successful message' do
expect { cli.refresh }
.to output_results('Refreshed 2 accounts')
# One request from factory creation, one more from task
expect(a_request(:get, remote_com_avatar_url))
.to have_been_made.at_least_times(2)
expect(a_request(:get, remote_com_header_url))
.to have_been_made.at_least_times(2)
expect(a_request(:get, remote_net_avatar_url))
.to have_been_made.at_least_times(2)
expect(a_request(:get, remote_net_header_url))
.to have_been_made.at_least_times(2)
end
context 'with --dry-run option' do
before do
cli.options = { all: true, dry_run: true }
end
let(:options) { { all: true, dry_run: true } }
it 'does not refresh the avatar for any account' do
allow(local_account).to receive(:reset_avatar!)
allow(remote_account_example_com).to receive(:reset_avatar!)
allow(account_example_net).to receive(:reset_avatar!)
expect { cli.refresh }
it 'does not refresh the avatar or header for any account' do
expect { subject }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(local_account).to_not have_received(:reset_avatar!)
expect(remote_account_example_com).to_not have_received(:reset_avatar!)
expect(account_example_net).to_not have_received(:reset_avatar!)
end
it 'does not refresh the header for any account' do
allow(local_account).to receive(:reset_header!)
allow(remote_account_example_com).to receive(:reset_header!)
allow(account_example_net).to receive(:reset_header!)
expect { cli.refresh }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(local_account).to_not have_received(:reset_header!)
expect(remote_account_example_com).to_not have_received(:reset_header!)
expect(account_example_net).to_not have_received(:reset_header!)
end
it 'displays a successful message with (DRY RUN)' do
expect { cli.refresh }
.to output_results('Refreshed 2 accounts (DRY RUN)')
# One request from factory creation, none from task due to dry run
expect(a_request(:get, remote_com_avatar_url))
.to have_been_made.once
expect(a_request(:get, remote_com_header_url))
.to have_been_made.once
expect(a_request(:get, remote_net_avatar_url))
.to have_been_made.once
expect(a_request(:get, remote_net_header_url))
.to have_been_made.once
end
end
end
@ -782,7 +745,7 @@ describe Mastodon::CLI::Accounts do
allow(account_example_com_a).to receive(:reset_avatar!)
allow(account_example_com_b).to receive(:reset_avatar!)
expect { cli.refresh(*arguments) }
expect { subject }
.to output_results('OK')
expect(account_example_com_a).to have_received(:reset_avatar!).once
@ -792,7 +755,7 @@ describe Mastodon::CLI::Accounts do
it 'does not reset the avatar for unspecified accounts' do
allow(account_example_net).to receive(:reset_avatar!)
expect { cli.refresh(*arguments) }
expect { subject }
.to output_results('OK')
expect(account_example_net).to_not have_received(:reset_avatar!)
@ -802,7 +765,7 @@ describe Mastodon::CLI::Accounts do
allow(account_example_com_a).to receive(:reset_header!)
allow(account_example_com_b).to receive(:reset_header!)
expect { cli.refresh(*arguments) }
expect { subject }
.to output_results('OK')
expect(account_example_com_a).to have_received(:reset_header!).once
@ -812,7 +775,7 @@ describe Mastodon::CLI::Accounts do
it 'does not reset the header for unspecified accounts' do
allow(account_example_net).to receive(:reset_header!)
expect { cli.refresh(*arguments) }
expect { subject }
.to output_results('OK')
expect(account_example_net).to_not have_received(:reset_header!)
@ -822,7 +785,7 @@ describe Mastodon::CLI::Accounts do
it 'displays a failure message' do
allow(account_example_com_a).to receive(:reset_avatar!).and_raise(Mastodon::UnexpectedResponseError)
expect { cli.refresh(*arguments) }
expect { subject }
.to output_results("Account failed: #{account_example_com_a.username}@#{account_example_com_a.domain}")
end
end
@ -831,22 +794,20 @@ describe Mastodon::CLI::Accounts do
it 'exits with an error message' do
allow(Account).to receive(:find_remote).with(account_example_com_b.username, account_example_com_b.domain).and_return(nil)
expect { cli.refresh(*arguments) }
expect { subject }
.to output_results('No such account')
.and raise_error(SystemExit)
end
end
context 'with --dry-run option' do
before do
cli.options = { dry_run: true }
end
let(:options) { { dry_run: true } }
it 'does not refresh the avatar for any account' do
allow(account_example_com_a).to receive(:reset_avatar!)
allow(account_example_com_b).to receive(:reset_avatar!)
expect { cli.refresh(*arguments) }
expect { subject }
.to output_results('OK (DRY RUN)')
expect(account_example_com_a).to_not have_received(:reset_avatar!)
@ -857,7 +818,7 @@ describe Mastodon::CLI::Accounts do
allow(account_example_com_a).to receive(:reset_header!)
allow(account_example_com_b).to receive(:reset_header!)
expect { cli.refresh(*arguments) }
expect { subject }
.to output_results('OK (DRY RUN)')
expect(account_example_com_a).to_not have_received(:reset_header!)
@ -867,67 +828,70 @@ describe Mastodon::CLI::Accounts do
end
context 'with --domain option' do
let!(:account_example_com_a) { Fabricate(:account, domain: 'example.com') }
let!(:account_example_com_b) { Fabricate(:account, domain: 'example.com') }
let!(:account_example_net) { Fabricate(:account, domain: 'example.net') }
let(:domain) { 'example.com' }
let(:scope) { Account.remote.where(domain: domain) }
let(:domain) { 'example.com' }
let(:options) { { domain: domain } }
let(:com_a_avatar_url) { 'https://example.host/avatar/a' }
let(:com_a_header_url) { 'https://example.host/header/a' }
let(:account_example_com_a) { Fabricate(:account, domain: domain, avatar_remote_url: com_a_avatar_url, header_remote_url: com_a_header_url) }
let(:com_b_avatar_url) { 'https://example.host/avatar/b' }
let(:com_b_header_url) { 'https://example.host/header/b' }
let(:account_example_com_b) { Fabricate(:account, domain: domain, avatar_remote_url: com_b_avatar_url, header_remote_url: com_b_header_url) }
let(:net_avatar_url) { 'https://example.host/avatar/net' }
let(:net_header_url) { 'https://example.host/header/net' }
let(:account_example_net) { Fabricate(:account, domain: 'example.net', avatar_remote_url: net_avatar_url, header_remote_url: net_header_url) }
before do
allow(cli).to receive(:parallelize_with_progress).and_yield(account_example_com_a)
.and_yield(account_example_com_b)
.and_return([2, nil])
cli.options = { domain: domain }
stub_parallelize_with_progress!
stub_request(:get, com_a_avatar_url)
.to_return request_fixture('avatar.txt')
stub_request(:get, com_a_header_url)
.to_return request_fixture('avatar.txt')
stub_request(:get, com_b_avatar_url)
.to_return request_fixture('avatar.txt')
stub_request(:get, com_b_header_url)
.to_return request_fixture('avatar.txt')
stub_request(:get, net_avatar_url)
.to_return request_fixture('avatar.txt')
stub_request(:get, net_header_url)
.to_return request_fixture('avatar.txt')
account_example_com_a
.update_column(:avatar_file_name, nil)
account_example_com_b
.update_column(:avatar_file_name, nil)
account_example_net
.update_column(:avatar_file_name, nil)
end
it 'refreshes the avatar for all accounts on specified domain' do
allow(account_example_com_a).to receive(:reset_avatar!)
allow(account_example_com_b).to receive(:reset_avatar!)
expect { cli.refresh }
it 'refreshes the avatar and header for all accounts on specified domain' do
expect { subject }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(account_example_com_a).to have_received(:reset_avatar!).once
expect(account_example_com_b).to have_received(:reset_avatar!).once
end
# One request from factory creation, one more from task
expect(a_request(:get, com_a_avatar_url))
.to have_been_made.at_least_times(2)
expect(a_request(:get, com_a_header_url))
.to have_been_made.at_least_times(2)
expect(a_request(:get, com_b_avatar_url))
.to have_been_made.at_least_times(2)
expect(a_request(:get, com_b_header_url))
.to have_been_made.at_least_times(2)
it 'does not refresh the avatar for accounts outside specified domain' do
allow(account_example_net).to receive(:reset_avatar!)
expect { cli.refresh }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(account_example_net).to_not have_received(:reset_avatar!)
end
it 'refreshes the header for all accounts on specified domain' do
allow(account_example_com_a).to receive(:reset_header!)
allow(account_example_com_b).to receive(:reset_header!)
expect { cli.refresh }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope)
expect(account_example_com_a).to have_received(:reset_header!).once
expect(account_example_com_b).to have_received(:reset_header!).once
end
it 'does not refresh the header for accounts outside specified domain' do
allow(account_example_net).to receive(:reset_header!)
expect { cli.refresh }
.to output_results('Refreshed 2 accounts')
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
expect(account_example_net).to_not have_received(:reset_header!)
# One request from factory creation, none from task
expect(a_request(:get, net_avatar_url))
.to have_been_made.once
expect(a_request(:get, net_header_url))
.to have_been_made.once
end
end
context 'when neither a list of accts nor options are provided' do
it 'exits with an error message' do
expect { cli.refresh }
expect { subject }
.to output_results('No account(s) given')
.and raise_error(SystemExit)
end

View file

@ -115,26 +115,35 @@ describe Announcement do
describe '#reactions' do
context 'with announcement_reactions present' do
let(:account_reaction_emoji) { Fabricate :custom_emoji }
let(:other_reaction_emoji) { Fabricate :custom_emoji }
let!(:account) { Fabricate(:account) }
let!(:announcement) { Fabricate(:announcement) }
let!(:announcement_reaction) { Fabricate(:announcement_reaction, announcement: announcement, created_at: 10.days.ago) }
let!(:announcement_reaction_account) { Fabricate(:announcement_reaction, announcement: announcement, created_at: 5.days.ago, account: account) }
before do
Fabricate(:announcement_reaction)
Fabricate(:announcement_reaction, announcement: announcement, created_at: 10.days.ago, name: other_reaction_emoji.shortcode)
Fabricate(:announcement_reaction, announcement: announcement, created_at: 5.days.ago, account: account, name: account_reaction_emoji.shortcode)
Fabricate(:announcement_reaction) # For some other announcement
end
it 'returns the announcement reactions for the announcement' do
results = announcement.reactions
expect(results.first.name).to eq(announcement_reaction.name)
expect(results.last.name).to eq(announcement_reaction_account.name)
expect(results).to have_attributes(
size: eq(2),
first: have_attributes(name: other_reaction_emoji.shortcode, me: false),
last: have_attributes(name: account_reaction_emoji.shortcode, me: false)
)
end
it 'returns the announcement reactions for the announcement limited to account' do
it 'returns the announcement reactions for the announcement with `me` set correctly' do
results = announcement.reactions(account)
expect(results.first.name).to eq(announcement_reaction.name)
expect(results).to have_attributes(
size: eq(2),
first: have_attributes(name: other_reaction_emoji.shortcode, me: false),
last: have_attributes(name: account_reaction_emoji.shortcode, me: true)
)
end
end
end

View file

@ -461,12 +461,12 @@ RSpec.describe User do
end
end
describe '#confirm!' do
describe '#mark_email_as_confirmed!' do
subject(:user) { Fabricate(:user, confirmed_at: confirmed_at) }
before do
ActionMailer::Base.deliveries.clear
user.confirm!
user.mark_email_as_confirmed!
end
after { ActionMailer::Base.deliveries.clear }

View file

@ -64,7 +64,7 @@ RSpec.describe UserPolicy do
context 'when record.confirmed?' do
it 'denies' do
john.user.confirm!
john.user.mark_email_as_confirmed!
expect(subject).to_not permit(admin, john.user)
end
end

View file

@ -48,6 +48,39 @@ RSpec.describe AppSignUpService, type: :service do
end
end
context 'when the email address requires approval through MX records' do
before do
Setting.registrations_mode = 'open'
Fabricate(:email_domain_block, allow_with_approval: true, domain: 'smtp.email.com')
allow(User).to receive(:skip_mx_check?).and_return(false)
resolver = instance_double(Resolv::DNS, :timeouts= => nil)
allow(resolver).to receive(:getresources)
.with('email.com', Resolv::DNS::Resource::IN::MX)
.and_return([instance_double(Resolv::DNS::Resource::MX, exchange: 'smtp.email.com')])
allow(resolver).to receive(:getresources).with('email.com', Resolv::DNS::Resource::IN::A).and_return([])
allow(resolver).to receive(:getresources).with('email.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
allow(resolver).to receive(:getresources).with('smtp.email.com', Resolv::DNS::Resource::IN::A).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: '2.3.4.5')])
allow(resolver).to receive(:getresources).with('smtp.email.com', Resolv::DNS::Resource::IN::AAAA).and_return([instance_double(Resolv::DNS::Resource::IN::AAAA, address: 'fd00::2')])
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
end
it 'creates an unapproved user', :aggregate_failures do
access_token = subject.call(app, remote_ip, params)
expect(access_token).to_not be_nil
expect(access_token.scopes.to_s).to eq 'read write'
user = User.find_by(id: access_token.resource_owner_id)
expect(user).to_not be_nil
expect(user.confirmed?).to be false
expect(user.approved?).to be false
expect(user.account).to_not be_nil
expect(user.invite_request).to be_nil
end
end
context 'when registrations are closed' do
before do
Setting.registrations_mode = 'none'

View file

@ -46,7 +46,7 @@ RSpec.describe ReblogService, type: :service do
Status
.where(id: reblog_of_id)
.where(text: 'discard-status-text')
.update_all(deleted_at: Time.now.utc) # rubocop:disable Rails/SkipsModelValidations
.update_all(deleted_at: Time.now.utc)
end
end
end

View file

@ -9,8 +9,8 @@ RSpec.configure do |config|
expect(error.level).to_not eq('SEVERE'), error.message
next unless error.level == 'WARNING'
$stderr.warn 'WARN: javascript warning'
$stderr.warn error.message
warn 'WARN: javascript warning'
warn error.message
end
end
end

View file

@ -41,7 +41,7 @@ describe RedownloadAvatarWorker do
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
account.update_column(:avatar_file_name, nil)
result = worker.perform(account.id)

View file

@ -41,7 +41,7 @@ describe RedownloadHeaderWorker do
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
account.update_column(:header_file_name, nil)
result = worker.perform(account.id)