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

This commit is contained in:
KMY 2024-08-17 09:38:31 +09:00
commit 82ffc95733
97 changed files with 1377 additions and 472 deletions

View file

@ -302,12 +302,10 @@ RSpec.describe MediaAttachment, :attachment_processing do
it 'queues CacheBusterWorker jobs' do
original_path = media.file.path(:original)
small_path = media.file.path(:small)
thumbnail_path = media.thumbnail.path(:original)
expect { media.destroy }
.to enqueue_sidekiq_job(CacheBusterWorker).with(original_path)
.and enqueue_sidekiq_job(CacheBusterWorker).with(small_path)
.and enqueue_sidekiq_job(CacheBusterWorker).with(thumbnail_path)
end
end

View file

@ -182,30 +182,30 @@ RSpec.describe User do
end
end
describe 'blacklist' do
describe 'email domains denylist integration' do
around do |example|
old_blacklist = Rails.configuration.x.email_blacklist
original = Rails.configuration.x.email_domains_denylist
Rails.configuration.x.email_domains_blacklist = 'mvrht.com'
Rails.configuration.x.email_domains_denylist = 'mvrht.com'
example.run
Rails.configuration.x.email_domains_blacklist = old_blacklist
Rails.configuration.x.email_domains_denylist = original
end
it 'allows a non-blacklisted user to be created' do
it 'allows a user with an email domain that is not on the denylist to be created' do
user = described_class.new(email: 'foo@example.com', account: account, password: password, agreement: true)
expect(user).to be_valid
end
it 'does not allow a blacklisted user to be created' do
it 'does not allow a user with an email domain on the deylist to be created' do
user = described_class.new(email: 'foo@mvrht.com', account: account, password: password, agreement: true)
expect(user).to_not be_valid
end
it 'does not allow a subdomain blacklisted user to be created' do
it 'does not allow a user with an email where the subdomain is on the denylist to be created' do
user = described_class.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password, agreement: true)
expect(user).to_not be_valid
@ -406,43 +406,43 @@ RSpec.describe User do
end
end
describe 'whitelist' do
describe 'allowlist integration' do
around do |example|
old_whitelist = Rails.configuration.x.email_domains_whitelist
original = Rails.configuration.x.email_domains_allowlist
Rails.configuration.x.email_domains_whitelist = 'mastodon.space'
Rails.configuration.x.email_domains_allowlist = 'mastodon.space'
example.run
Rails.configuration.x.email_domains_whitelist = old_whitelist
Rails.configuration.x.email_domains_allowlist = original
end
it 'does not allow a user to be created unless they are whitelisted' do
it 'does not allow a user to be created when their email is not on the allowlist' do
user = described_class.new(email: 'foo@example.com', account: account, password: password, agreement: true)
expect(user).to_not be_valid
end
it 'allows a user to be created if they are whitelisted' do
it 'allows a user to be created when their email is on the allowlist' do
user = described_class.new(email: 'foo@mastodon.space', account: account, password: password, agreement: true)
expect(user).to be_valid
end
it 'does not allow a user with a whitelisted top domain as subdomain in their email address to be created' do
it 'does not allow a user with an email subdomain included on the top level domain allowlist to be created' do
user = described_class.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password, agreement: true)
expect(user).to_not be_valid
end
context 'with a blacklisted subdomain' do
context 'with a subdomain on the denylist' do
around do |example|
old_blacklist = Rails.configuration.x.email_blacklist
original = Rails.configuration.x.email_domains_denylist
example.run
Rails.configuration.x.email_domains_blacklist = old_blacklist
Rails.configuration.x.email_domains_denylist = original
end
it 'does not allow a user to be created with a specific blacklisted subdomain even if the top domain is whitelisted' do
Rails.configuration.x.email_domains_blacklist = 'blacklisted.mastodon.space'
it 'does not allow a user to be created with an email subdomain on the denylist even if the top domain is on the allowlist' do
Rails.configuration.x.email_domains_denylist = 'denylisted.mastodon.space'
user = described_class.new(email: 'foo@blacklisted.mastodon.space', account: account, password: password)
user = described_class.new(email: 'foo@denylisted.mastodon.space', account: account, password: password)
expect(user).to_not be_valid
end
end

View file

@ -0,0 +1,30 @@
# frozen_string_literal: true
require 'rails_helper'
describe 'Log Out' do
include RoutingHelper
describe 'DELETE /auth/sign_out' do
let(:user) { Fabricate(:user) }
before do
sign_in user
end
it 'Logs out the user and redirect' do
delete '/auth/sign_out'
expect(response).to redirect_to('/auth/sign_in')
end
it 'Logs out the user and return a page to redirect to with a JSON request' do
delete '/auth/sign_out', headers: { 'HTTP_ACCEPT' => 'application/json' }
expect(response).to have_http_status(200)
expect(response.media_type).to eq 'application/json'
expect(body_as_json[:redirect_to]).to eq '/auth/sign_in'
end
end
end

View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe AcceptNotificationRequestService do
subject { described_class.new }
let(:notification_request) { Fabricate(:notification_request) }
describe '#call' do
it 'destroys the notification request, creates a permission, and queues a worker' do
expect { subject.call(notification_request) }
.to change { NotificationRequest.exists?(notification_request.id) }.to(false)
.and change { NotificationPermission.exists?(account_id: notification_request.account_id, from_account_id: notification_request.from_account_id) }.to(true)
expect(UnfilterNotificationsWorker).to have_enqueued_sidekiq_job(notification_request.account_id, notification_request.from_account_id)
end
end
end

View file

@ -1,23 +1,36 @@
# frozen_string_literal: true
module BrowserErrorsHelpers
def ignore_js_error(error)
@ignored_js_errors_for_spec << error
end
end
RSpec.configure do |config|
config.include BrowserErrorsHelpers, :js, type: :system
config.before(:each, :js, type: :system) do
@ignored_js_errors_for_spec = []
end
config.after(:each, :js, type: :system) do
# Classes of intermittent ignorable errors
ignored_errors = [
/Error while trying to use the following icon from the Manifest/, # https://github.com/mastodon/mastodon/pull/30793
/Manifest: Line: 1, column: 1, Syntax error/, # Similar parsing/interruption issue as above
]
].concat(@ignored_js_errors_for_spec)
errors = page.driver.browser.logs.get(:browser).reject do |error|
ignored_errors.any? { |pattern| pattern.match(error.message) }
end
if errors.present?
aggregate_failures 'javascript errrors' do
aggregate_failures 'browser errrors' do
errors.each do |error|
expect(error.level).to_not eq('SEVERE'), error.message
next unless error.level == 'WARNING'
warn 'WARN: javascript warning'
warn 'WARN: browser warning'
warn error.message
end
end

View file

@ -6,14 +6,20 @@ Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
require 'selenium/webdriver'
def common_chrome_options
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument '--window-size=1680,1050'
options.add_argument '--disable-search-engine-choice-screen'
options
end
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
Capybara::Selenium::Driver.new(app, browser: :chrome, options: common_chrome_options)
end
Capybara.register_driver :headless_chrome do |app|
options = Selenium::WebDriver::Chrome::Options.new
options = common_chrome_options
options.add_argument '--headless=new'
options.add_argument '--window-size=1680,1050'
Capybara::Selenium::Driver.new(
app,

View file

@ -0,0 +1,46 @@
# frozen_string_literal: true
require 'rails_helper'
describe 'Log out' do
include ProfileStories
before do
as_a_logged_in_user
end
describe 'Logging out from the preferences' do
it 'logs the user out' do
visit settings_path
within '.sidebar' do
click_on 'Logout'
end
expect(page).to have_title(I18n.t('auth.login'))
expect(page).to have_current_path('/auth/sign_in')
end
end
describe 'Logging out from the JS app', :js, :streaming do
it 'logs the user out' do
# The frontend tries to load announcements after a short delay, but the session might be expired by then, and the browser will output an error.
ignore_js_error(/Failed to load resource: the server responded with a status of 422/)
visit root_path
within '.navigation-bar' do
click_on 'Menu'
end
within '.dropdown-menu' do
click_on 'Logout'
end
click_on 'Log out'
expect(page).to have_title(I18n.t('auth.login'))
expect(page).to have_current_path('/auth/sign_in')
end
end
end

View file

@ -9,10 +9,10 @@ describe EmailMxValidator do
context 'with an e-mail domain that is explicitly allowed' do
around do |block|
tmp = Rails.configuration.x.email_domains_whitelist
Rails.configuration.x.email_domains_whitelist = 'example.com'
tmp = Rails.configuration.x.email_domains_allowlist
Rails.configuration.x.email_domains_allowlist = 'example.com'
block.call
Rails.configuration.x.email_domains_whitelist = tmp
Rails.configuration.x.email_domains_allowlist = tmp
end
it 'does not add errors if there are no DNS records' do
@ -69,7 +69,7 @@ describe EmailMxValidator do
expect(user.errors).to have_received(:add)
end
it 'adds an error if the MX record is blacklisted' do
it 'adds an error if the MX record has an email domain block' do
EmailDomainBlock.create!(domain: 'mail.example.com')
configure_resolver(

View file

@ -2,7 +2,7 @@
require 'rails_helper'
RSpec.describe BlacklistedEmailValidator do
RSpec.describe UserEmailValidator do
describe '#validate' do
subject { described_class.new.validate(user) }

View file

@ -0,0 +1,46 @@
# frozen_string_literal: true
require 'rails_helper'
describe UnfilterNotificationsWorker do
let(:recipient) { Fabricate(:account) }
let(:sender) { Fabricate(:account) }
before do
# Populate multiple kinds of filtered notifications
private_message = Fabricate(:status, account: sender, visibility: :direct)
mention = Fabricate(:mention, account: recipient, status: private_message)
Fabricate(:notification, filtered: true, from_account: sender, account: recipient, type: :mention, activity: mention)
follow_request = sender.request_follow!(recipient)
Fabricate(:notification, filtered: true, from_account: sender, account: recipient, type: :follow_request, activity: follow_request)
end
shared_examples 'shared behavior' do
it 'unfilters notifications and adds private messages to conversations' do
expect { subject }
.to change { recipient.notifications.where(from_account_id: sender.id).pluck(:filtered) }.from([true, true]).to([false, false])
.and change { recipient.conversations.exists?(last_status_id: sender.statuses.first.id) }.to(true)
end
end
describe '#perform' do
context 'with single argument (prerelease behavior)' do
subject { described_class.new.perform(notification_request.id) }
let(:notification_request) { Fabricate(:notification_request, from_account: sender, account: recipient) }
it_behaves_like 'shared behavior'
it 'destroys the notification request' do
expect { subject }
.to change { NotificationRequest.exists?(notification_request.id) }.to(false)
end
end
context 'with two arguments' do
subject { described_class.new.perform(recipient.id, sender.id) }
it_behaves_like 'shared behavior'
end
end
end