From 173953c23e8a988679e48e098e825af5be374bbe Mon Sep 17 00:00:00 2001 From: gunchleoc Date: Tue, 9 Jan 2024 11:56:13 +0100 Subject: [PATCH 01/23] Fix ISO code for Canadian French (#26015) Co-authored-by: Claire --- app/helpers/languages_helper.rb | 2 +- .../locales/{fr-QC.json => fr-CA.json} | 0 config/initializers/i18n.rb | 2 +- ...ecord.fr-QC.yml => activerecord.fr-CA.yml} | 2 +- .../{devise.fr-QC.yml => devise.fr-CA.yml} | 2 +- ...rkeeper.fr-QC.yml => doorkeeper.fr-CA.yml} | 2 +- config/locales/{fr-QC.yml => fr-CA.yml} | 2 +- ...e_form.fr-QC.yml => simple_form.fr-CA.yml} | 2 +- ...240109103012_fix_canadian_french_locale.rb | 21 +++++++++++++++++++ db/schema.rb | 2 +- lib/tasks/tests.rake | 13 +++++++++++- 11 files changed, 41 insertions(+), 9 deletions(-) rename app/javascript/mastodon/locales/{fr-QC.json => fr-CA.json} (100%) rename config/locales/{activerecord.fr-QC.yml => activerecord.fr-CA.yml} (99%) rename config/locales/{devise.fr-QC.yml => devise.fr-CA.yml} (99%) rename config/locales/{doorkeeper.fr-QC.yml => doorkeeper.fr-CA.yml} (99%) rename config/locales/{fr-QC.yml => fr-CA.yml} (99%) rename config/locales/{simple_form.fr-QC.yml => simple_form.fr-CA.yml} (99%) create mode 100644 db/migrate/20240109103012_fix_canadian_french_locale.rb diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb index 0d4edceb7b5..87f0f288d36 100644 --- a/app/helpers/languages_helper.rb +++ b/app/helpers/languages_helper.rb @@ -224,7 +224,7 @@ module LanguagesHelper 'en-GB': 'English (British)', 'es-AR': 'Español (Argentina)', 'es-MX': 'Español (México)', - 'fr-QC': 'Français (Canadien)', + 'fr-CA': 'Français (Canadien)', 'pt-BR': 'Português (Brasil)', 'pt-PT': 'Português (Portugal)', 'sr-Latn': 'Srpski (latinica)', diff --git a/app/javascript/mastodon/locales/fr-QC.json b/app/javascript/mastodon/locales/fr-CA.json similarity index 100% rename from app/javascript/mastodon/locales/fr-QC.json rename to app/javascript/mastodon/locales/fr-CA.json diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb index 39b7a3cc40f..1c1cea1b945 100644 --- a/config/initializers/i18n.rb +++ b/config/initializers/i18n.rb @@ -31,7 +31,7 @@ Rails.application.configure do :fi, :fo, :fr, - :'fr-QC', + :'fr-CA', :fy, :ga, :gd, diff --git a/config/locales/activerecord.fr-QC.yml b/config/locales/activerecord.fr-CA.yml similarity index 99% rename from config/locales/activerecord.fr-QC.yml rename to config/locales/activerecord.fr-CA.yml index 607758add64..1a83a0e9e26 100644 --- a/config/locales/activerecord.fr-QC.yml +++ b/config/locales/activerecord.fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: activerecord: attributes: poll: diff --git a/config/locales/devise.fr-QC.yml b/config/locales/devise.fr-CA.yml similarity index 99% rename from config/locales/devise.fr-QC.yml rename to config/locales/devise.fr-CA.yml index 8c1a94dab66..4c693600242 100644 --- a/config/locales/devise.fr-QC.yml +++ b/config/locales/devise.fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: devise: confirmations: confirmed: Votre adresse de courriel a été validée avec succès. diff --git a/config/locales/doorkeeper.fr-QC.yml b/config/locales/doorkeeper.fr-CA.yml similarity index 99% rename from config/locales/doorkeeper.fr-QC.yml rename to config/locales/doorkeeper.fr-CA.yml index 043b4a6cda9..9d671569f52 100644 --- a/config/locales/doorkeeper.fr-QC.yml +++ b/config/locales/doorkeeper.fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: activerecord: attributes: doorkeeper/application: diff --git a/config/locales/fr-QC.yml b/config/locales/fr-CA.yml similarity index 99% rename from config/locales/fr-QC.yml rename to config/locales/fr-CA.yml index 3d85ced1514..c43fa013c74 100644 --- a/config/locales/fr-QC.yml +++ b/config/locales/fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: about: about_mastodon_html: 'Le réseau social de l''avenir : pas de publicité, pas de surveillance institutionnelle, conception éthique et décentralisation ! Gardez le contrôle de vos données avec Mastodon !' contact_missing: Non défini diff --git a/config/locales/simple_form.fr-QC.yml b/config/locales/simple_form.fr-CA.yml similarity index 99% rename from config/locales/simple_form.fr-QC.yml rename to config/locales/simple_form.fr-CA.yml index 7a95a1c882a..f5a2a428e9c 100644 --- a/config/locales/simple_form.fr-QC.yml +++ b/config/locales/simple_form.fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: simple_form: hints: account: diff --git a/db/migrate/20240109103012_fix_canadian_french_locale.rb b/db/migrate/20240109103012_fix_canadian_french_locale.rb new file mode 100644 index 00000000000..1b8ef7a4afa --- /dev/null +++ b/db/migrate/20240109103012_fix_canadian_french_locale.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class FixCanadianFrenchLocale < ActiveRecord::Migration[7.0] + class User < ApplicationRecord + # Dummy class, to make migration possible across version changes + end + + disable_ddl_transaction! + + def up + User.where(locale: 'fr-QC').in_batches do |users| + users.update_all(locale: 'fr-CA') + end + end + + def down + User.where(locale: 'fr-CA').in_batches do |users| + users.update_all(locale: 'fr-QC') + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4ea9744f401..cbe54c1db79 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_12_22_100226) do +ActiveRecord::Schema[7.1].define(version: 2024_01_09_103012) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake index 209a73efa5e..c3a9dbfd738 100644 --- a/lib/tasks/tests.rake +++ b/lib/tasks/tests.rake @@ -83,6 +83,11 @@ namespace :tests do puts 'Default posting language not migrated as expected for kmr users' exit(1) end + + unless Account.find_local('qcuser').user.locale == 'fr-CA' + puts 'Locale for fr-QC users not updated to fr-CA as expected' + exit(1) + end end desc 'Populate the database with test data for 2.4.3' @@ -142,13 +147,19 @@ namespace :tests do INSERT INTO "accounts" (id, username, domain, private_key, public_key, created_at, updated_at) VALUES - (10, 'kmruser', NULL, #{user_private_key}, #{user_public_key}, now(), now()); + (10, 'kmruser', NULL, #{user_private_key}, #{user_public_key}, now(), now()), + (11, 'qcuser', NULL, #{user_private_key}, #{user_public_key}, now(), now()); INSERT INTO "users" (id, account_id, email, created_at, updated_at, admin, locale, chosen_languages) VALUES (4, 10, 'kmruser@localhost', now(), now(), false, 'ku', '{en,kmr,ku,ckb}'); + INSERT INTO "users" + (id, account_id, email, created_at, updated_at, locale) + VALUES + (5, 11, 'qcuser@localhost', now(), now(), 'fr-QC'); + INSERT INTO "settings" (id, thing_type, thing_id, var, value, created_at, updated_at) VALUES From 01ca84e5418183af477a1a8317f367f46113657e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 12:48:19 +0100 Subject: [PATCH 02/23] New Crowdin Translations (automated) (#28660) Co-authored-by: GitHub Actions --- config/locales/devise.fr-CA.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/devise.fr-CA.yml b/config/locales/devise.fr-CA.yml index 4c693600242..e9f09a69806 100644 --- a/config/locales/devise.fr-CA.yml +++ b/config/locales/devise.fr-CA.yml @@ -20,8 +20,8 @@ fr-CA: confirmation_instructions: action: Vérifier l’adresse courriel action_with_app: Confirmer et retourner à %{app} - explanation: Vous avez créé un compte sur %{host} avec cette adresse courriel. Vous êtes à un clic de l’activer. Si ce n'était pas vous, veuiller ignorer ce courriel. - explanation_when_pending: Vous avez demandé à vous inscrire à %{host} avec cette adresse courriel. Une fois que vous aurez confirmé cette adresse, nous étudierons votre demande. Vous pouvez vous connecter pour changer vos détails ou supprimer votre compte, mais vous ne pouvez pas accéder à la plupart des fonctionalités du compte avant que votre compte ne soit approuvé. Si votre demande est rejetée, vos données seront supprimées, donc aucune action supplémentaire ne sera requise de votre part. Si ce n'était pas vous, veuiller ignorer ce courriel. + explanation: Vous avez créé un compte sur %{host} avec cette adresse courriel. Vous êtes à un clic de l’activer. Si ce n'était pas vous, veuillez ignorer ce courriel. + explanation_when_pending: Vous avez demandé à vous inscrire à %{host} avec cette adresse courriel. Une fois que vous aurez confirmé cette adresse, nous étudierons votre demande. Vous pouvez vous connecter pour changer vos détails ou supprimer votre compte, mais vous ne pouvez pas accéder à la plupart des fonctionnalités du compte avant que votre compte ne soit approuvé. Si votre demande est rejetée, vos données seront supprimées, donc aucune action supplémentaire ne sera requise de votre part. Si ce n'était pas vous, veuillez ignorer ce courriel. extra_html: Veuillez également consulter les règles du serveur et nos conditions d’utilisation. subject: 'Mastodon: Instructions de confirmation pour %{instance}' title: Vérifier l’adresse courriel From 17818498847c934a9a29f664c1e8fd0472061b38 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 9 Jan 2024 12:50:21 +0100 Subject: [PATCH 03/23] Inline what remains of the rails-settings-cached gem (#28618) Co-authored-by: Claire --- Gemfile | 1 - Gemfile.lock | 9 -- app/models/setting.rb | 153 +++++++++++++++++++------- spec/models/setting_spec.rb | 208 ++++++++---------------------------- 4 files changed, 157 insertions(+), 214 deletions(-) diff --git a/Gemfile b/Gemfile index a56702fad2b..e0980c07204 100644 --- a/Gemfile +++ b/Gemfile @@ -75,7 +75,6 @@ gem 'premailer-rails' gem 'rack-attack', '~> 6.6' gem 'rack-cors', '~> 2.0', require: 'rack/cors' gem 'rails-i18n', '~> 7.0' -gem 'rails-settings-cached', '~> 0.6', git: 'https://github.com/mastodon/rails-settings-cached.git', branch: 'v0.6.6-aliases-true' gem 'redcarpet', '~> 3.6' gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis'] gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' diff --git a/Gemfile.lock b/Gemfile.lock index 442022e81a9..50a6412a1d7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,14 +18,6 @@ GIT sidekiq (>= 3.5) statsd-ruby (~> 1.4, >= 1.4.0) -GIT - remote: https://github.com/mastodon/rails-settings-cached.git - revision: 86328ef0bd04ce21cc0504ff5e334591e8c2ccab - branch: v0.6.6-aliases-true - specs: - rails-settings-cached (0.6.6) - rails (>= 4.2.0) - GIT remote: https://github.com/stanhu/omniauth-cas.git revision: 4211e6d05941b4a981f9a36b49ec166cecd0e271 @@ -922,7 +914,6 @@ DEPENDENCIES rails (~> 7.1.1) rails-controller-testing (~> 1.0) rails-i18n (~> 7.0) - rails-settings-cached (~> 0.6)! rdf-normalize (~> 0.5) redcarpet (~> 3.6) redis (~> 4.5) diff --git a/app/models/setting.rb b/app/models/setting.rb index 3bdc6ffb40c..ecd9d2d7371 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -13,49 +13,120 @@ # thing_id :bigint(8) # -class Setting < RailsSettings::Base - source Rails.root.join('config', 'settings.yml') +# This file is derived from a fork of the `rails-settings-cached` gem available at +# https://github.com/mastodon/rails-settings-cached/tree/v0.6.6-aliases-true, with +# the original available at: +# https://github.com/huacnlee/rails-settings-cached/tree/0.x + +# It is licensed as follows: + +# Copyright (c) 2006 Alex Wayne +# Some additional features added 2009 by Georg Ledermann + +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND +# NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +class Setting < ApplicationRecord + after_commit :rewrite_cache, on: %i(create update) + after_commit :expire_cache, on: %i(destroy) + + # Settings are server-wide settings only, but they were previously + # used for users too. This can be dropped later with a database + # migration dropping any scoped setting. + default_scope { where(thing_type: nil, thing_id: nil) } + + class << self + # get or set a variable with the variable as the called method + # rubocop:disable Style/MissingRespondToMissing + def method_missing(method, *args) + # set a value for a variable + if method.end_with?('=') + var_name = method.to_s.chomp('=') + value = args.first + self[var_name] = value + else + # retrieve a value + self[method.to_s] + end + end + # rubocop:enable Style/MissingRespondToMissing + + def object(var_name) + find_by(var: var_name.to_s) + end + + def cache_prefix_by_startup + @cache_prefix_by_startup ||= Digest::MD5.hexdigest(default_settings.to_s) + end + + def cache_key(var_name) + "rails_settings_cached/#{cache_prefix_by_startup}/#{var_name}" + end + + def [](key) + Rails.cache.fetch(cache_key(key)) do + db_val = object(key) + db_val ? db_val.value : default_settings[key] + end + end + + # set a setting value by [] notation + def []=(var_name, value) + var_name = var_name.to_s + + record = object(var_name) || new(var: var_name) + record.value = value + record.save! + end + + def default_settings + return @default_settings if defined?(@default_settings) + + content = Rails.root.join('config', 'settings.yml').read + hash = content.empty? ? {} : YAML.safe_load(ERB.new(content).result, aliases: true).to_hash + @default_settings = hash[Rails.env] || {} + end + end + + # get the value field, YAML decoded + def value + YAML.safe_load(self[:value], permitted_classes: [ActiveSupport::HashWithIndifferentAccess, Symbol]) if self[:value].present? + end + + # set the value field, YAML encoded + def value=(new_value) + self[:value] = new_value.to_yaml + end + + def rewrite_cache + Rails.cache.write(cache_key, value) + end + + def expire_cache + Rails.cache.delete(cache_key) + end + + def cache_key + self.class.cache_key(var) + end def to_param var end - - class << self - def [](key) - return super(key) unless rails_initialized? - - Rails.cache.fetch(cache_key(key, nil)) do - db_val = object(key) - - if db_val - default_value = default_settings[key] - - return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash) - - db_val.value - else - default_settings[key] - end - end - end - - def all_as_records - vars = thing_scoped - records = vars.index_by(&:var) - - default_settings.each do |key, default_value| - next if records.key?(key) || default_value.is_a?(Hash) - - records[key] = Setting.new(var: key, value: default_value) - end - - records - end - - def default_settings - return {} unless RailsSettings::Default.enabled? - - RailsSettings::Default.instance - end - end end diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index e98062810ef..ca9c65511df 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -13,189 +13,71 @@ RSpec.describe Setting do end describe '.[]' do + let(:key) { 'key' } + let(:cache_key) { 'cache-key' } + let(:cache_value) { 'cache-value' } + before do - allow(described_class).to receive(:rails_initialized?).and_return(rails_initialized) + allow(described_class).to receive(:cache_key).with(key).and_return(cache_key) end - let(:key) { 'key' } - - context 'when rails_initialized? is falsey' do - let(:rails_initialized) { false } - - it 'calls RailsSettings::Base#[]' do - allow(RailsSettings::Base).to receive(:[]).with(key) - - described_class[key] - - expect(RailsSettings::Base).to have_received(:[]).with(key) - end - end - - context 'when rails_initialized? is truthy' do + context 'when Rails.cache does not exists' do before do - allow(RailsSettings::Base).to receive(:cache_key).with(key, nil).and_return(cache_key) + allow(described_class).to receive(:object).with(key).and_return(object) + allow(described_class).to receive(:default_settings).and_return(default_settings) + + Fabricate(:setting, var: key, value: nil) + + Rails.cache.delete(cache_key) end - let(:rails_initialized) { true } - let(:cache_key) { 'cache-key' } - let(:cache_value) { 'cache-value' } + let(:object) { nil } + let(:default_value) { 'default_value' } + let(:default_settings) { { key => default_value } } - it 'calls not RailsSettings::Base#[]' do - allow(RailsSettings::Base).to receive(:[]).with(key) + it 'calls Setting.object' do + allow(described_class).to receive(:object).with(key) described_class[key] - expect(RailsSettings::Base).to_not have_received(:[]).with(key) + expect(described_class).to have_received(:object).with(key) end - context 'when Rails.cache does not exists' do - before do - allow(RailsSettings::Settings).to receive(:object).with(key).and_return(object) - allow(described_class).to receive(:default_settings).and_return(default_settings) - settings_double = instance_double(Settings::ScopedSettings, thing_scoped: records) - allow(Settings::ScopedSettings).to receive(:new).and_return(settings_double) - Rails.cache.delete(cache_key) + context 'when Setting.object returns truthy' do + let(:object) { db_val } + let(:db_val) { instance_double(described_class, value: 'db_val') } + let(:default_value) { 'default_value' } + + it 'returns db_val.value' do + expect(described_class[key]).to be db_val.value end + end - let(:object) { nil } - let(:default_value) { 'default_value' } - let(:default_settings) { { key => default_value } } - let(:records) { [Fabricate(:setting, var: key, value: nil)] } + context 'when Setting.object returns falsey' do + let(:object) { nil } - it 'calls RailsSettings::Settings.object' do - allow(RailsSettings::Settings).to receive(:object).with(key) + it 'returns default_settings[key]' do + expect(described_class[key]).to be default_settings[key] + end + end + end + context 'when Rails.cache exists' do + before do + Rails.cache.write(cache_key, cache_value) + end + + it 'does not query the database' do + callback = double + allow(callback).to receive(:call) + ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do described_class[key] - - expect(RailsSettings::Settings).to have_received(:object).with(key) - end - - context 'when RailsSettings::Settings.object returns truthy' do - let(:object) { db_val } - let(:db_val) { instance_double(described_class, value: 'db_val') } - - context 'when default_value is a Hash' do - let(:default_value) { { default_value: 'default_value' } } - - it 'calls default_value.with_indifferent_access.merge!' do - indifferent_hash = instance_double(Hash, merge!: nil) - allow(default_value).to receive(:with_indifferent_access).and_return(indifferent_hash) - - described_class[key] - - expect(default_value).to have_received(:with_indifferent_access) - expect(indifferent_hash).to have_received(:merge!).with(db_val.value) - end - end - - context 'when default_value is not a Hash' do - let(:default_value) { 'default_value' } - - it 'returns db_val.value' do - expect(described_class[key]).to be db_val.value - end - end - end - - context 'when RailsSettings::Settings.object returns falsey' do - let(:object) { nil } - - it 'returns default_settings[key]' do - expect(described_class[key]).to be default_settings[key] - end end + expect(callback).to_not have_received(:call) end - context 'when Rails.cache exists' do - before do - Rails.cache.write(cache_key, cache_value) - end - - it 'does not query the database' do - callback = double - allow(callback).to receive(:call) - ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do - described_class[key] - end - expect(callback).to_not have_received(:call) - end - - it 'returns the cached value' do - expect(described_class[key]).to eq cache_value - end - end - end - end - - describe '.all_as_records' do - before do - settings_double = instance_double(Settings::ScopedSettings, thing_scoped: records) - allow(Settings::ScopedSettings).to receive(:new).and_return(settings_double) - allow(described_class).to receive(:default_settings).and_return(default_settings) - end - - let(:key) { 'key' } - let(:default_value) { 'default_value' } - let(:default_settings) { { key => default_value } } - let(:original_setting) { Fabricate(:setting, var: key, value: nil) } - let(:records) { [original_setting] } - - it 'returns a Hash' do - expect(described_class.all_as_records).to be_a Hash - end - - context 'when records includes Setting with var as the key' do - let(:records) { [original_setting] } - - it 'includes the original Setting' do - setting = described_class.all_as_records[key] - expect(setting).to eq original_setting - end - end - - context 'when records includes nothing' do - let(:records) { [] } - - context 'when default_value is not a Hash' do - it 'includes Setting with value of default_value' do - setting = described_class.all_as_records[key] - - expect(setting).to be_a described_class - expect(setting).to have_attributes(var: key) - expect(setting).to have_attributes(value: 'default_value') - end - end - - context 'when default_value is a Hash' do - let(:default_value) { { 'foo' => 'fuga' } } - - it 'returns {}' do - expect(described_class.all_as_records).to eq({}) - end - end - end - end - - describe '.default_settings' do - subject { described_class.default_settings } - - before do - allow(RailsSettings::Default).to receive(:enabled?).and_return(enabled) - end - - context 'when RailsSettings::Default.enabled? is false' do - let(:enabled) { false } - - it 'returns {}' do - expect(subject).to eq({}) - end - end - - context 'when RailsSettings::Settings.enabled? is true' do - let(:enabled) { true } - - it 'returns instance of RailsSettings::Default' do - expect(subject).to be_a RailsSettings::Default + it 'returns the cached value' do + expect(described_class[key]).to eq cache_value end end end From 1ad908e0c08c236389967d86b4f238f428de9fef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:06:19 +0100 Subject: [PATCH 04/23] Update dependency fog-core to v2.4.0 (#28582) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 50a6412a1d7..2d54ac33ed5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -264,7 +264,7 @@ GEM erubi (1.12.0) et-orbi (1.2.7) tzinfo - excon (0.104.0) + excon (0.109.0) fabrication (2.31.0) faker (3.2.2) i18n (>= 1.8.11, < 2) @@ -299,7 +299,7 @@ GEM ffi-compiler (1.0.1) ffi (>= 1.0.0) rake - fog-core (2.3.0) + fog-core (2.4.0) builder excon (~> 0.71) formatador (>= 0.2, < 2.0) From 4e02838832a1b1dec9330c5c70b47529f1db256f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 9 Jan 2024 07:50:57 -0500 Subject: [PATCH 05/23] Enable "low risk" Rails 7.1 setting defaults (#28626) --- .../new_framework_defaults_7_1.rb | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/config/initializers/new_framework_defaults_7_1.rb b/config/initializers/new_framework_defaults_7_1.rb index 1475fe2fd9e..bcc300c89f6 100644 --- a/config/initializers/new_framework_defaults_7_1.rb +++ b/config/initializers/new_framework_defaults_7_1.rb @@ -29,7 +29,7 @@ Rails.application.config.add_autoload_paths_to_load_path = false # Do not treat an `ActionController::Parameters` instance # as equal to an equivalent `Hash` by default. -# Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false +Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false # Active Record Encryption now uses SHA-256 as its hash digest algorithm. Important: If you have # data encrypted with previous Rails versions, there are two scenarios to consider: @@ -50,7 +50,7 @@ Rails.application.config.add_autoload_paths_to_load_path = false # Instead, run these callbacks on the instance most likely to have internal # state which matches what was committed to the database, typically the last # instance to save. -# Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false +Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false # Configures SQLite with a strict strings mode, which disables double-quoted string literals. # @@ -59,10 +59,10 @@ Rails.application.config.add_autoload_paths_to_load_path = false # it then considers them as string literals. Because of this, typos can silently go unnoticed. # For example, it is possible to create an index for a non existing column. # See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details. -# Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true +Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true # Disable deprecated singular associations names -# Rails.application.config.active_record.allow_deprecated_singular_associations_name = false +Rails.application.config.active_record.allow_deprecated_singular_associations_name = false # Enable the Active Job `BigDecimal` argument serializer, which guarantees # roundtripping. Without this serializer, some queue adapters may serialize @@ -78,12 +78,12 @@ Rails.application.config.add_autoload_paths_to_load_path = false # `write` are given an invalid `expires_at` or `expires_in` time. # Options are `true`, and `false`. If `false`, the exception will be reported # as `handled` and logged instead. -# Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true +Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true # Specify whether Query Logs will format tags using the SQLCommenter format # (https://open-telemetry.github.io/opentelemetry-sqlcommenter/), or using the legacy format. # Options are `:legacy` and `:sqlcommenter`. -# Rails.application.config.active_record.query_log_tags_format = :sqlcommenter +Rails.application.config.active_record.query_log_tags_format = :sqlcommenter # Specify the default serializer used by `MessageEncryptor` and `MessageVerifier` # instances. @@ -129,39 +129,37 @@ Rails.application.config.add_autoload_paths_to_load_path = false # `config.load_defaults 7.1` does not set this value for environments other than # development and test. # -# if Rails.env.local? -# Rails.application.config.log_file_size = 100 * 1024 * 1024 -# end +Rails.application.config.log_file_size = 100 * 1024 * 1024 if Rails.env.local? # Enable raising on assignment to attr_readonly attributes. The previous # behavior would allow assignment but silently not persist changes to the # database. -# Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true +Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true # Enable validating only parent-related columns for presence when the parent is mandatory. # The previous behavior was to validate the presence of the parent record, which performed an extra query # to get the parent every time the child record was updated, even when parent has not changed. -# Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false +Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false # Enable precompilation of `config.filter_parameters`. Precompilation can # improve filtering performance, depending on the quantity and types of filters. -# Rails.application.config.precompile_filter_parameters = true +Rails.application.config.precompile_filter_parameters = true # Enable before_committed! callbacks on all enrolled records in a transaction. # The previous behavior was to only run the callbacks on the first copy of a record # if there were multiple copies of the same record enrolled in the transaction. -# Rails.application.config.active_record.before_committed_on_all_records = true +Rails.application.config.active_record.before_committed_on_all_records = true # Disable automatic column serialization into YAML. # To keep the historic behavior, you can set it to `YAML`, however it is # recommended to explicitly define the serialization method for each column # rather than to rely on a global default. -# Rails.application.config.active_record.default_column_serializer = nil +Rails.application.config.active_record.default_column_serializer = nil # Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model. # This matches the behaviour of all other callbacks. # In previous versions of Rails, they ran in the inverse order. -# Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true +Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true # Whether a `transaction` block is committed or rolled back when exited via `return`, `break` or `throw`. # @@ -169,7 +167,7 @@ Rails.application.config.add_autoload_paths_to_load_path = false # Controls when to generate a value for has_secure_token declarations. # -# Rails.application.config.active_record.generate_secure_token_on = :initialize +Rails.application.config.active_record.generate_secure_token_on = :initialize # ** Please read carefully, this must be configured in config/application.rb ** # Change the format of the cache entry. @@ -190,7 +188,7 @@ Rails.application.config.add_autoload_paths_to_load_path = false # # In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor. # -# Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor +Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor # Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your # platform. @@ -213,4 +211,4 @@ Rails.application.config.add_autoload_paths_to_load_path = false # # In previous versions of Rails, these test helpers always used an HTML4 parser. # -# Rails.application.config.dom_testing_default_html_version = :html5 +Rails.application.config.dom_testing_default_html_version = :html5 From 10203bd57a13b243b03491f107efbe9566e89ed6 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 9 Jan 2024 15:01:53 +0100 Subject: [PATCH 06/23] Clean up `Setting` model and remove dead code (#28661) --- app/lib/settings/scoped_settings.rb | 79 ----------------------------- app/models/setting.rb | 12 ++--- spec/models/setting_spec.rb | 30 +++++------ 3 files changed, 15 insertions(+), 106 deletions(-) delete mode 100644 app/lib/settings/scoped_settings.rb diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb deleted file mode 100644 index 3ad57cc1ea9..00000000000 --- a/app/lib/settings/scoped_settings.rb +++ /dev/null @@ -1,79 +0,0 @@ -# frozen_string_literal: true - -module Settings - class ScopedSettings - DEFAULTING_TO_UNSCOPED = %w( - theme - noindex - ).freeze - - def initialize(object) - @object = object - end - - def method_missing(method, *args) - method_name = method.to_s - # set a value for a variable - if method_name[-1] == '=' - var_name = method_name.sub('=', '') - value = args.first - self[var_name] = value - else - # retrieve a value - self[method_name] - end - end - - def respond_to_missing?(*) - true - end - - def all_as_records - vars = thing_scoped - records = vars.index_by(&:var) - - Setting.default_settings.each do |key, default_value| - next if records.key?(key) || default_value.is_a?(Hash) - - records[key] = Setting.new(var: key, value: default_value) - end - - records - end - - def []=(key, value) - key = key.to_s - record = thing_scoped.find_or_initialize_by(var: key) - record.update!(value: value) - - Rails.cache.write(Setting.cache_key(key, @object), value) - end - - def [](key) - Rails.cache.fetch(Setting.cache_key(key, @object)) do - db_val = thing_scoped.find_by(var: key.to_s) - if db_val - default_value = ScopedSettings.default_settings[key] - return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash) - - db_val.value - else - ScopedSettings.default_settings[key] - end - end - end - - class << self - def default_settings - defaulting = DEFAULTING_TO_UNSCOPED.index_with { |k| Setting[k] } - Setting.default_settings.merge!(defaulting) - end - end - - protected - - def thing_scoped - Setting.unscoped.where(thing_type: @object.class.base_class.to_s, thing_id: @object.id) - end - end -end diff --git a/app/models/setting.rb b/app/models/setting.rb index ecd9d2d7371..6af7a98c6df 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -67,10 +67,6 @@ class Setting < ApplicationRecord end # rubocop:enable Style/MissingRespondToMissing - def object(var_name) - find_by(var: var_name.to_s) - end - def cache_prefix_by_startup @cache_prefix_by_startup ||= Digest::MD5.hexdigest(default_settings.to_s) end @@ -81,16 +77,14 @@ class Setting < ApplicationRecord def [](key) Rails.cache.fetch(cache_key(key)) do - db_val = object(key) + db_val = find_by(var: key) db_val ? db_val.value : default_settings[key] end end # set a setting value by [] notation def []=(var_name, value) - var_name = var_name.to_s - - record = object(var_name) || new(var: var_name) + record = find_or_initialize_by(var: var_name.to_s) record.value = value record.save! end @@ -100,7 +94,7 @@ class Setting < ApplicationRecord content = Rails.root.join('config', 'settings.yml').read hash = content.empty? ? {} : YAML.safe_load(ERB.new(content).result, aliases: true).to_hash - @default_settings = hash[Rails.env] || {} + @default_settings = (hash[Rails.env] || {}).freeze end end diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index ca9c65511df..a1e24e83507 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -23,38 +23,32 @@ RSpec.describe Setting do context 'when Rails.cache does not exists' do before do - allow(described_class).to receive(:object).with(key).and_return(object) allow(described_class).to receive(:default_settings).and_return(default_settings) - Fabricate(:setting, var: key, value: nil) + Fabricate(:setting, var: key, value: 42) if save_setting Rails.cache.delete(cache_key) end - let(:object) { nil } let(:default_value) { 'default_value' } let(:default_settings) { { key => default_value } } + let(:save_setting) { true } - it 'calls Setting.object' do - allow(described_class).to receive(:object).with(key) + context 'when the setting has been saved to database' do + it 'returns the value from database' do + callback = double + allow(callback).to receive(:call) - described_class[key] + ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do + expect(described_class[key]).to eq 42 + end - expect(described_class).to have_received(:object).with(key) - end - - context 'when Setting.object returns truthy' do - let(:object) { db_val } - let(:db_val) { instance_double(described_class, value: 'db_val') } - let(:default_value) { 'default_value' } - - it 'returns db_val.value' do - expect(described_class[key]).to be db_val.value + expect(callback).to have_received(:call) end end - context 'when Setting.object returns falsey' do - let(:object) { nil } + context 'when the setting has not been saved to database' do + let(:save_setting) { false } it 'returns default_settings[key]' do expect(described_class[key]).to be default_settings[key] From 93938751eb34b194148236d3a3f907c3b71d0870 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:40:24 +0100 Subject: [PATCH 07/23] Update dependency ruby-prof to v1.7.0 (#28637) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2d54ac33ed5..7b9d3579e5a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -684,7 +684,7 @@ GEM rubocop (~> 1.40) rubocop-capybara (~> 2.17) rubocop-factory_bot (~> 2.22) - ruby-prof (1.6.3) + ruby-prof (1.7.0) ruby-progressbar (1.13.0) ruby-saml (1.15.0) nokogiri (>= 1.13.10) From 9a73a7dcaf2e383b2ec105d71bfcea2c48cbea10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:17:18 +0100 Subject: [PATCH 08/23] Update dependency irb to v1.11.1 (#28662) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7b9d3579e5a..549781aed46 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -370,9 +370,9 @@ GEM terminal-table (>= 1.5.1) idn-ruby (0.1.5) io-console (0.7.1) - irb (1.11.0) + irb (1.11.1) rdoc - reline (>= 0.3.8) + reline (>= 0.4.2) jmespath (1.6.2) json (2.7.1) json-canonicalization (1.0.0) @@ -616,7 +616,7 @@ GEM redlock (1.3.2) redis (>= 3.0.0, < 6.0) regexp_parser (2.8.3) - reline (0.4.1) + reline (0.4.2) io-console (~> 0.5) request_store (1.5.1) rack (>= 1.4) From 09ab073f0cc5a8963c6d34fb76d3af84e0c0f40e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 9 Jan 2024 10:28:56 -0500 Subject: [PATCH 09/23] Fix `LineLength` haml-lint in `app/views/settings` area (#28663) --- .haml-lint_todo.yml | 8 +--- .../settings/applications/_fields.html.haml | 25 ++++++++-- .../settings/featured_tags/index.html.haml | 4 +- app/views/settings/imports/index.html.haml | 22 +++++++-- .../migration/redirects/new.html.haml | 6 ++- .../preferences/appearance/show.html.haml | 46 ++++++++++++++++--- .../settings/preferences/other/show.html.haml | 39 ++++++++++++++-- app/views/settings/profiles/show.html.haml | 10 +++- .../confirmations/new.html.haml | 7 ++- 9 files changed, 137 insertions(+), 30 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 09764c2f30a..13ee2baaabe 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,20 +1,16 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2024-01-08 14:02:57 -0500 using Haml-Lint version 0.53.0. +# on 2024-01-09 10:00:31 -0500 using Haml-Lint version 0.53.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 10 + # Offense count: 5 LineLength: exclude: - 'app/views/admin/roles/_form.html.haml' - 'app/views/auth/registrations/edit.html.haml' - 'app/views/auth/registrations/new.html.haml' - 'app/views/media/player.html.haml' - - 'app/views/settings/applications/_fields.html.haml' - - 'app/views/settings/imports/index.html.haml' - - 'app/views/settings/preferences/appearance/show.html.haml' - - 'app/views/settings/preferences/other/show.html.haml' diff --git a/app/views/settings/applications/_fields.html.haml b/app/views/settings/applications/_fields.html.haml index 29e2bcb5a36..ed97e880fc8 100644 --- a/app/views/settings/applications/_fields.html.haml +++ b/app/views/settings/applications/_fields.html.haml @@ -1,11 +1,17 @@ .fields-group - = f.input :name, wrapper: :with_label, label: t('activerecord.attributes.doorkeeper/application.name') + = f.input :name, + label: t('activerecord.attributes.doorkeeper/application.name'), + wrapper: :with_label .fields-group - = f.input :website, wrapper: :with_label, label: t('activerecord.attributes.doorkeeper/application.website') + = f.input :website, + label: t('activerecord.attributes.doorkeeper/application.website'), + wrapper: :with_label .fields-group - = f.input :redirect_uri, wrapper: :with_block_label, label: t('activerecord.attributes.doorkeeper/application.redirect_uri'), hint: t('doorkeeper.applications.help.redirect_uri') + = f.input :redirect_uri, + label: t('activerecord.attributes.doorkeeper/application.redirect_uri'), hint: t('doorkeeper.applications.help.redirect_uri'), + wrapper: :with_block_label %p.hint= t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: content_tag(:code, Doorkeeper.configuration.native_redirect_uri)).html_safe @@ -15,4 +21,15 @@ %span.hint= t('simple_form.hints.defaults.scopes') - Doorkeeper.configuration.scopes.group_by { |s| s.split(':').first }.each_value do |value| - = f.input :scopes, label: false, hint: false, collection: value.sort, wrapper: :with_block_label, include_blank: false, label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, selected: f.object.scopes.all, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :scopes, + as: :check_boxes, + collection_wrapper_tag: 'ul', + collection: value.sort, + hint: false, + include_blank: false, + item_wrapper_tag: 'li', + label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, + label: false, + required: false, + selected: f.object.scopes.all, + wrapper: :with_block_label diff --git a/app/views/settings/featured_tags/index.html.haml b/app/views/settings/featured_tags/index.html.haml index 387eb290e32..22f91801291 100644 --- a/app/views/settings/featured_tags/index.html.haml +++ b/app/views/settings/featured_tags/index.html.haml @@ -11,7 +11,9 @@ %p.lead= t('featured_tags.hint_html') .fields-group - = f.input :name, wrapper: :with_block_label, hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@recently_used_tags.map { |tag| link_to("##{tag.display_name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' ') + = f.input :name, + hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@recently_used_tags.map { |tag| link_to("##{tag.display_name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' '), + wrapper: :with_block_label .actions = f.button :button, t('featured_tags.add_new'), type: :submit diff --git a/app/views/settings/imports/index.html.haml b/app/views/settings/imports/index.html.haml index 5f7950b5982..d5ca252dc15 100644 --- a/app/views/settings/imports/index.html.haml +++ b/app/views/settings/imports/index.html.haml @@ -3,13 +3,29 @@ = simple_form_for @import, url: settings_imports_path do |f| .field-group - = f.input :type, as: :grouped_select, collection: { constructive: %i(following bookmarks lists), destructive: %i(muting blocking domain_blocking) }, wrapper: :with_block_label, include_blank: false, label_method: ->(type) { I18n.t("imports.types.#{type}") }, group_label_method: ->(group) { I18n.t("imports.type_groups.#{group.first}") }, group_method: :last, hint: t('imports.preface') + = f.input :type, + as: :grouped_select, + collection: { constructive: %i(following bookmarks lists), destructive: %i(muting blocking domain_blocking) }, + group_label_method: ->(group) { I18n.t("imports.type_groups.#{group.first}") }, + group_method: :last, + hint: t('imports.preface'), + include_blank: false, + label_method: ->(type) { I18n.t("imports.types.#{type}") }, + wrapper: :with_block_label .fields-row .fields-group.fields-row__column.fields-row__column-6 - = f.input :data, as: :file, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data') + = f.input :data, + as: :file, + hint: t('simple_form.hints.imports.data'), + wrapper: :with_block_label .fields-group.fields-row__column.fields-row__column-6 - = f.input :mode, as: :radio_buttons, collection: Import::MODES, label_method: ->(mode) { safe_join([I18n.t("imports.modes.#{mode}"), content_tag(:span, I18n.t("imports.modes.#{mode}_long"), class: 'hint')]) }, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :mode, + as: :radio_buttons, + collection_wrapper_tag: 'ul', + collection: Import::MODES, + item_wrapper_tag: 'li', + label_method: ->(mode) { safe_join([I18n.t("imports.modes.#{mode}"), content_tag(:span, I18n.t("imports.modes.#{mode}_long"), class: 'hint')]) } .actions = f.button :button, t('imports.upload'), type: :submit diff --git a/app/views/settings/migration/redirects/new.html.haml b/app/views/settings/migration/redirects/new.html.haml index 37008787997..731acb9dbce 100644 --- a/app/views/settings/migration/redirects/new.html.haml +++ b/app/views/settings/migration/redirects/new.html.haml @@ -15,7 +15,11 @@ .fields-row .fields-row__column.fields-group.fields-row__column-6 - = f.input :acct, wrapper: :with_block_label, input_html: { autocapitalize: 'none', autocorrect: 'off' }, label: t('simple_form.labels.account_migration.acct'), hint: t('simple_form.hints.account_migration.acct') + = f.input :acct, + hint: t('simple_form.hints.account_migration.acct'), + input_html: { autocapitalize: 'none', autocorrect: 'off' }, + label: t('simple_form.labels.account_migration.acct'), + wrapper: :with_block_label .fields-row__column.fields-group.fields-row__column-6 - if current_user.encrypted_password.present? diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index 11fa2bfc435..76cd4381d8b 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -7,13 +7,28 @@ = simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put, id: 'edit_user' } do |f| .fields-row .fields-group.fields-row__column.fields-row__column-6 - = f.input :locale, collection: ui_languages, wrapper: :with_label, include_blank: false, label_method: ->(locale) { native_locale_name(locale) }, selected: I18n.locale, hint: false + = f.input :locale, + collection: ui_languages, + hint: false, + include_blank: false, + label_method: ->(locale) { native_locale_name(locale) }, + selected: I18n.locale, + wrapper: :with_label .fields-group.fields-row__column.fields-row__column-6 - = f.input :time_zone, wrapper: :with_label, collection: ActiveSupport::TimeZone.all.map { |tz| ["(GMT#{tz.formatted_offset}) #{tz.name}", tz.tzinfo.name] }, hint: false + = f.input :time_zone, + collection: ActiveSupport::TimeZone.all.map { |tz| ["(GMT#{tz.formatted_offset}) #{tz.name}", tz.tzinfo.name] }, + hint: false, + wrapper: :with_label .fields-group = f.simple_fields_for :settings, current_user.settings do |ff| - = ff.input :theme, collection: Themes.instance.names, label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_theme'), include_blank: false, hint: false + = ff.input :theme, + collection: Themes.instance.names, + hint: false, + include_blank: false, + label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) }, + label: I18n.t('simple_form.labels.defaults.setting_theme'), + wrapper: :with_label - unless I18n.locale == :en .flash-message.translation-prompt @@ -25,11 +40,17 @@ %p.hint= t 'appearance.advanced_web_interface_hint' .fields-group - = ff.input :'web.advanced_layout', wrapper: :with_label, hint: false, label: I18n.t('simple_form.labels.defaults.setting_advanced_layout') + = ff.input :'web.advanced_layout', + hint: false, + label: I18n.t('simple_form.labels.defaults.setting_advanced_layout'), + wrapper: :with_label %h4= t 'appearance.animations_and_accessibility' .fields-group - = ff.input :'web.use_pending_items', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_use_pending_items'), hint: I18n.t('simple_form.hints.defaults.setting_use_pending_items') + = ff.input :'web.use_pending_items', + hint: I18n.t('simple_form.hints.defaults.setting_use_pending_items'), + label: I18n.t('simple_form.labels.defaults.setting_use_pending_items'), + wrapper: :with_label .fields-group = ff.input :'web.auto_play', wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_auto_play_gif') @@ -52,10 +73,21 @@ %h4= t 'appearance.sensitive_content' .fields-group - = ff.input :'web.display_media', collection: %w(default show_all hide_all), label_method: ->(item) { t("simple_form.hints.defaults.setting_display_media_#{item}") }, hint: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label, label: I18n.t('simple_form.labels.defaults.setting_display_media') + = ff.input :'web.display_media', + as: :radio_buttons, + collection_wrapper_tag: 'ul', + collection: %w(default show_all hide_all), + hint: false, + item_wrapper_tag: 'li', + label_method: ->(item) { t("simple_form.hints.defaults.setting_display_media_#{item}") }, + label: I18n.t('simple_form.labels.defaults.setting_display_media'), + wrapper: :with_floating_label .fields-group - = ff.input :'web.use_blurhash', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_use_blurhash'), hint: I18n.t('simple_form.hints.defaults.setting_use_blurhash') + = ff.input :'web.use_blurhash', + hint: I18n.t('simple_form.hints.defaults.setting_use_blurhash'), + label: I18n.t('simple_form.labels.defaults.setting_use_blurhash'), + wrapper: :with_label .fields-group = ff.input :'web.expand_content_warnings', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_expand_spoilers') diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 5228ce11905..e2888f72129 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -9,24 +9,53 @@ = f.simple_fields_for :settings, current_user.settings do |ff| .fields-group - = ff.input :aggregate_reblogs, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_aggregate_reblogs'), hint: I18n.t('simple_form.hints.defaults.setting_aggregate_reblogs') + = ff.input :aggregate_reblogs, + hint: I18n.t('simple_form.hints.defaults.setting_aggregate_reblogs'), + label: I18n.t('simple_form.labels.defaults.setting_aggregate_reblogs'), + recommended: true, + wrapper: :with_label %h4= t 'preferences.posting_defaults' .fields-row .fields-group.fields-row__column.fields-row__column-6 - = ff.input :default_privacy, collection: Status.selectable_visibilities, wrapper: :with_label, include_blank: false, label_method: ->(visibility) { safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_privacy') + = ff.input :default_privacy, + collection: Status.selectable_visibilities, + hint: false, + include_blank: false, + label_method: ->(visibility) { safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, + label: I18n.t('simple_form.labels.defaults.setting_default_privacy'), + required: false, + wrapper: :with_label .fields-group.fields-row__column.fields-row__column-6 - = ff.input :default_language, collection: [nil] + filterable_languages, wrapper: :with_label, label_method: ->(locale) { locale.nil? ? I18n.t('statuses.default_language') : native_locale_name(locale) }, required: false, include_blank: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_language') + = ff.input :default_language, + collection: [nil] + filterable_languages, + hint: false, + include_blank: false, + label_method: ->(locale) { locale.nil? ? I18n.t('statuses.default_language') : native_locale_name(locale) }, + label: I18n.t('simple_form.labels.defaults.setting_default_language'), + required: false, + wrapper: :with_label .fields-group - = ff.input :default_sensitive, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_default_sensitive'), hint: I18n.t('simple_form.hints.defaults.setting_default_sensitive') + = ff.input :default_sensitive, + hint: I18n.t('simple_form.hints.defaults.setting_default_sensitive'), + label: I18n.t('simple_form.labels.defaults.setting_default_sensitive'), + wrapper: :with_label %h4= t 'preferences.public_timelines' .fields-group - = f.input :chosen_languages, collection: filterable_languages, wrapper: :with_block_label, include_blank: false, label_method: ->(locale) { native_locale_name(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :chosen_languages, + as: :check_boxes, + collection_wrapper_tag: 'ul', + collection: filterable_languages, + include_blank: false, + item_wrapper_tag: 'li', + label_method: ->(locale) { native_locale_name(locale) }, + required: false, + wrapper: :with_block_label .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index 5f9613c9391..b7b0a0da92e 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -33,7 +33,10 @@ .fields-row .fields-row__column.fields-row__column-6 .fields-group - = f.input :avatar, wrapper: :with_block_label, input_html: { accept: Account::Avatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(Account::Avatar::LIMIT)) + = f.input :avatar, + hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(Account::Avatar::LIMIT)), + input_html: { accept: Account::Avatar::IMAGE_MIME_TYPES.join(',') }, + wrapper: :with_block_label .fields-row__column.fields-row__column-6 .fields-group @@ -46,7 +49,10 @@ .fields-row .fields-row__column.fields-row__column-6 .fields-group - = f.input :header, wrapper: :with_block_label, input_html: { accept: Account::Header::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(Account::Header::LIMIT)) + = f.input :header, + hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(Account::Header::LIMIT)), + input_html: { accept: Account::Header::IMAGE_MIME_TYPES.join(',') }, + wrapper: :with_block_label .fields-row__column.fields-row__column-6 .fields-group diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml index 43830ac27fb..0b8278a104e 100644 --- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml +++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml @@ -12,7 +12,12 @@ %samp.qr-alternative__code= @new_otp_secret.scan(/.{4}/).join(' ') .fields-group - = f.input :otp_attempt, wrapper: :with_label, hint: t('otp_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { autocomplete: 'off' }, required: true + = f.input :otp_attempt, + hint: t('otp_authentication.code_hint'), + input_html: { autocomplete: 'off' }, + label: t('simple_form.labels.defaults.otp_attempt'), + required: true, + wrapper: :with_label .actions = f.button :button, t('otp_authentication.enable'), type: :submit From eed4eef39a92464459496a476e5e3cccfbe084ab Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 9 Jan 2024 11:03:16 -0500 Subject: [PATCH 10/23] Fix `LineLength` haml-lint in `app/views/auth` area (#28664) --- .haml-lint_todo.yml | 6 +-- app/views/auth/challenges/new.html.haml | 6 ++- app/views/auth/confirmations/new.html.haml | 8 ++- app/views/auth/passwords/edit.html.haml | 13 ++++- app/views/auth/passwords/new.html.haml | 7 ++- .../registrations/_account_warning.html.haml | 4 +- .../auth/registrations/_session.html.haml | 4 +- app/views/auth/registrations/edit.html.haml | 26 ++++++++-- app/views/auth/registrations/new.html.haml | 52 ++++++++++++++++--- app/views/auth/sessions/new.html.haml | 20 +++++-- .../_otp_authentication_form.html.haml | 7 ++- app/views/auth/setup/show.html.haml | 5 +- 12 files changed, 130 insertions(+), 28 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 13ee2baaabe..ac9f7637588 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,16 +1,14 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2024-01-09 10:00:31 -0500 using Haml-Lint version 0.53.0. +# on 2024-01-09 10:48:44 -0500 using Haml-Lint version 0.53.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 5 + # Offense count: 3 LineLength: exclude: - 'app/views/admin/roles/_form.html.haml' - - 'app/views/auth/registrations/edit.html.haml' - - 'app/views/auth/registrations/new.html.haml' - 'app/views/media/player.html.haml' diff --git a/app/views/auth/challenges/new.html.haml b/app/views/auth/challenges/new.html.haml index 4f21e4af6e7..50dcebb00cf 100644 --- a/app/views/auth/challenges/new.html.haml +++ b/app/views/auth/challenges/new.html.haml @@ -5,7 +5,11 @@ = f.input :return_to, as: :hidden .field-group - = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password', autofocus: true }, label: t('challenge.prompt'), required: true + = f.input :current_password, + input_html: { autocomplete: 'current-password', autofocus: true }, + label: t('challenge.prompt'), + required: true, + wrapper: :with_block_label .actions = f.button :button, t('challenge.confirm'), type: :submit diff --git a/app/views/auth/confirmations/new.html.haml b/app/views/auth/confirmations/new.html.haml index 0cb82a1f86a..eaa9d9add09 100644 --- a/app/views/auth/confirmations/new.html.haml +++ b/app/views/auth/confirmations/new.html.haml @@ -21,7 +21,13 @@ = render 'shared/error_messages', object: resource .fields-group - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, readonly: current_user.present?, hint: current_user.present? && t('auth.confirmations.wrong_email_hint') + = f.input :email, + autofocus: true, + hint: current_user.present? && t('auth.confirmations.wrong_email_hint'), + input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, + label: t('simple_form.labels.defaults.email'), + readonly: current_user.present?, + wrapper: :with_label .actions = f.button :button, t('auth.resend_confirmation'), type: :submit diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml index b95a9b676bf..a75dc2d9fb3 100644 --- a/app/views/auth/passwords/edit.html.haml +++ b/app/views/auth/passwords/edit.html.haml @@ -8,9 +8,18 @@ = f.input :reset_password_token, as: :hidden .fields-group - = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, required: true + = f.input :password, + autofocus: true, + input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, + label: t('simple_form.labels.defaults.new_password'), + required: true, + wrapper: :with_label .fields-group - = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, required: true + = f.input :password_confirmation, + input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, + label: t('simple_form.labels.defaults.confirm_new_password'), + required: true, + wrapper: :with_label .actions = f.button :button, t('auth.set_new_password'), type: :submit diff --git a/app/views/auth/passwords/new.html.haml b/app/views/auth/passwords/new.html.haml index 10ad108eafa..8d5adaf3b98 100644 --- a/app/views/auth/passwords/new.html.haml +++ b/app/views/auth/passwords/new.html.haml @@ -5,7 +5,12 @@ = render 'shared/error_messages', object: resource .fields-group - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false + = f.input :email, + autofocus: true, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, + label: t('simple_form.labels.defaults.email'), + wrapper: :with_label .actions = f.button :button, t('auth.reset_password'), type: :submit diff --git a/app/views/auth/registrations/_account_warning.html.haml b/app/views/auth/registrations/_account_warning.html.haml index 40e7e12968b..19e5746ff63 100644 --- a/app/views/auth/registrations/_account_warning.html.haml +++ b/app/views/auth/registrations/_account_warning.html.haml @@ -5,7 +5,9 @@ = fa_icon 'warning' .log-entry__content .log-entry__title - = t('disputes.strikes.title', action: t(account_warning.action, scope: 'disputes.strikes.title_actions'), date: l(account_warning.created_at.to_date)) + = t 'disputes.strikes.title', + action: t(account_warning.action, scope: 'disputes.strikes.title_actions'), + date: l(account_warning.created_at.to_date) .log-entry__timestamp %time.formatted{ datetime: account_warning.created_at.iso8601 }= l(account_warning.created_at) diff --git a/app/views/auth/registrations/_session.html.haml b/app/views/auth/registrations/_session.html.haml index 28499a7c91c..2fa7db70c7b 100644 --- a/app/views/auth/registrations/_session.html.haml +++ b/app/views/auth/registrations/_session.html.haml @@ -3,7 +3,9 @@ %span{ title: session.user_agent }< = fa_icon "#{session_device_icon(session)} fw", 'aria-label': session_device_icon(session)   - = t 'sessions.description', browser: t("sessions.browsers.#{session.browser}", default: session.browser.to_s), platform: t("sessions.platforms.#{session.platform}", default: session.platform.to_s) + = t 'sessions.description', + browser: t("sessions.browsers.#{session.browser}", default: session.browser.to_s), + platform: t("sessions.platforms.#{session.platform}", default: session.platform.to_s) %td %samp= session.ip %td diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml index f5ef4e97e40..48350f478e8 100644 --- a/app/views/auth/registrations/edit.html.haml +++ b/app/views/auth/registrations/edit.html.haml @@ -15,15 +15,33 @@ - if (!use_seamless_external_login? || resource.encrypted_password.present?) && !omniauth_only? .fields-row .fields-row__column.fields-group.fields-row__column-6 - = f.input :email, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, required: true, disabled: current_account.suspended? + = f.input :email, + disabled: current_account.suspended?, + input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, + required: true, + wrapper: :with_label .fields-row__column.fields-group.fields-row__column-6 - = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.current_password'), autocomplete: 'current-password' }, required: true, disabled: current_account.suspended?, hint: false + = f.input :current_password, + disabled: current_account.suspended?, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.current_password'), autocomplete: 'current-password' }, + required: true, + wrapper: :with_label .fields-row .fields-row__column.fields-group.fields-row__column-6 - = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: t('simple_form.hints.defaults.password'), disabled: current_account.suspended? + = f.input :password, + disabled: current_account.suspended?, + hint: t('simple_form.hints.defaults.password'), + input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, + label: t('simple_form.labels.defaults.new_password'), + wrapper: :with_label .fields-row__column.fields-group.fields-row__column-6 - = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, disabled: current_account.suspended? + = f.input :password_confirmation, + disabled: current_account.suspended?, + input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, + label: t('simple_form.labels.defaults.confirm_new_password'), + wrapper: :with_label .actions = f.button :button, t('generic.save_changes'), type: :submit, class: 'button', disabled: current_account.suspended? diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index 4cac7b51bd0..1e5aac2976a 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -19,25 +19,61 @@ .fields-group = f.simple_fields_for :account do |ff| - = ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}" - = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' }, hint: false - = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: false - = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' }, hint: false - = f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), autocomplete: 'off' }, hint: false - = f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' } + = ff.input :username, + append: "@#{site_hostname}", + input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, + label: false, + required: true, + wrapper: :with_label + = f.input :email, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' }, + placeholder: t('simple_form.labels.defaults.email'), + required: true + = f.input :password, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, + placeholder: t('simple_form.labels.defaults.password'), + required: true + = f.input :password_confirmation, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' }, + placeholder: t('simple_form.labels.defaults.confirm_password'), + required: true + = f.input :confirm_password, + as: :string, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), autocomplete: 'off' }, + placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), + required: false + = f.input :website, + as: :url, + input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' }, + label: t('simple_form.labels.defaults.honeypot', label: 'Website'), + required: false, + wrapper: :with_label - if approved_registrations? && @invite.blank? %p.lead= t('auth.sign_up.manual_review', domain: site_hostname) .fields-group = f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields| - = invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: Setting.require_invite_text, label: false, hint: false + = invite_request_fields.input :text, + as: :text, + hint: false, + label: false, + required: Setting.require_invite_text, + wrapper: :with_block_label = hidden_field_tag :accept, params[:accept] = f.input :invite_code, as: :hidden .fields-group - = f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.privacy_policy_agreement_html', rules_path: about_more_path, privacy_policy_path: privacy_policy_path), required: true + = f.input :agreement, + as: :boolean, + label: t('auth.privacy_policy_agreement_html', rules_path: about_more_path, privacy_policy_path: privacy_policy_path), + required: true, + wrapper: :with_label .actions = f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit diff --git a/app/views/auth/sessions/new.html.haml b/app/views/auth/sessions/new.html.haml index 7914e0157fa..89903581a2b 100644 --- a/app/views/auth/sessions/new.html.haml +++ b/app/views/auth/sessions/new.html.haml @@ -10,11 +10,25 @@ %p.lead= t('auth.sign_in.preamble_html', domain: site_hostname) .fields-group - if use_seamless_external_login? - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label': t('simple_form.labels.defaults.username_or_email') }, hint: false + = f.input :email, + autofocus: true, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.username_or_email') }, + label: t('simple_form.labels.defaults.username_or_email'), + wrapper: :with_label - else - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false + = f.input :email, + autofocus: true, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, + label: t('simple_form.labels.defaults.email'), + wrapper: :with_label .fields-group - = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'current-password' }, hint: false + = f.input :password, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'current-password' }, + label: t('simple_form.labels.defaults.password'), + wrapper: :with_label .actions = f.button :button, t('auth.login'), type: :submit diff --git a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml index 8cc2c856103..30e97a68c11 100644 --- a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml +++ b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml @@ -5,7 +5,12 @@ %p.hint.authentication-hint= t('simple_form.hints.sessions.otp') .fields-group - = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label': t('simple_form.labels.defaults.otp_attempt'), autocomplete: 'one-time-code' }, autofocus: true + = f.input :otp_attempt, + autofocus: true, + input_html: { 'aria-label': t('simple_form.labels.defaults.otp_attempt'), autocomplete: 'one-time-code' }, + label: t('simple_form.labels.defaults.otp_attempt'), + type: :number, + wrapper: :with_label .actions = f.button :button, t('auth.login'), type: :submit diff --git a/app/views/auth/setup/show.html.haml b/app/views/auth/setup/show.html.haml index 97c826d704e..713f77470d3 100644 --- a/app/views/auth/setup/show.html.haml +++ b/app/views/auth/setup/show.html.haml @@ -16,7 +16,10 @@ %p.lead= t('auth.setup.email_below_hint_html') .fields-group - = f.input :email, required: true, hint: false, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' } + = f.input :email, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' }, + required: true .actions = f.button :button, t('auth.resend_confirmation'), type: :submit, class: 'button timer-button', disabled: true From 1f44903991168858d7cc00b3e3255617cd31154c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 22:08:02 +0100 Subject: [PATCH 11/23] Update dependency sidekiq-unique-jobs to v7.1.31 (#27818) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 549781aed46..91b3bf701fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -716,7 +716,7 @@ GEM rufus-scheduler (~> 3.2) sidekiq (>= 6, < 8) tilt (>= 1.4.0) - sidekiq-unique-jobs (7.1.30) + sidekiq-unique-jobs (7.1.31) brpoplpush-redis_script (> 0.1.1, <= 2.0.0) concurrent-ruby (~> 1.0, >= 1.0.5) redis (< 5.0) From 63d0b52cf3641a819853197bf837937b9f67ef8e Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Tue, 9 Jan 2024 22:58:19 +0100 Subject: [PATCH 12/23] Add a system spec for the `/share` endpoint (#28672) --- spec/system/share_entrypoint_spec.rb | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 spec/system/share_entrypoint_spec.rb diff --git a/spec/system/share_entrypoint_spec.rb b/spec/system/share_entrypoint_spec.rb new file mode 100644 index 00000000000..fd02d1120c0 --- /dev/null +++ b/spec/system/share_entrypoint_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'ShareEntrypoint' do + include ProfileStories + + subject { page } + + let(:email) { 'test@example.com' } + let(:password) { 'password' } + let(:confirmed_at) { Time.zone.now } + let(:finished_onboarding) { true } + + before do + as_a_logged_in_user + visit share_path + end + + it 'can be used to post a new status' do + expect(subject).to have_css('div#mastodon-compose') + expect(subject).to have_css('.compose-form__publish-button-wrapper > button') + + status_text = 'This is a new status!' + + within('.compose-form') do + fill_in "What's on your mind?", with: status_text + click_on 'Publish!' + end + + expect(subject).to have_css('.notification-bar-message', text: 'Post published.') + end +end From a71e918e958de85e8295212d1a48925e93fae4e0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 04:35:01 -0500 Subject: [PATCH 13/23] Fix `LineLength` haml-lint in `media/player` view (#28667) --- .haml-lint_todo.yml | 5 ++--- app/views/media/player.html.haml | 31 ++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index ac9f7637588..af2d2e8f4eb 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,14 +1,13 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2024-01-09 10:48:44 -0500 using Haml-Lint version 0.53.0. +# on 2024-01-09 11:30:07 -0500 using Haml-Lint version 0.53.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 3 + # Offense count: 1 LineLength: exclude: - 'app/views/admin/roles/_form.html.haml' - - 'app/views/media/player.html.haml' diff --git a/app/views/media/player.html.haml b/app/views/media/player.html.haml index f00c8f040b0..df02cc4110c 100644 --- a/app/views/media/player.html.haml +++ b/app/views/media/player.html.haml @@ -6,14 +6,39 @@ meta = @media_attachment.file.meta || {} - if @media_attachment.video? - = react_component :video, src: @media_attachment.file.url(:original), preview: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.file.url(:small), frameRate: meta.dig('original', 'frame_rate'), blurhash: @media_attachment.blurhash, width: 670, height: 380, editable: true, detailed: true, inline: true, alt: @media_attachment.description, media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer)].as_json do + = react_component :video, + alt: @media_attachment.description, + blurhash: @media_attachment.blurhash, + detailed: true, + editable: true, + frameRate: meta.dig('original', 'frame_rate'), + height: 380, + inline: true, + media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer)].as_json, + preview: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.file.url(:small), + src: @media_attachment.file.url(:original), + width: 670 do %video{ controls: 'controls' } %source{ src: @media_attachment.file.url(:original) } - elsif @media_attachment.gifv? - = react_component :media_gallery, height: 380, standalone: true, autoplay: true, media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer).as_json] do + = react_component :media_gallery, + autoplay: true, + height: 380, + media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer).as_json], + standalone: true do %video{ autoplay: 'autoplay', muted: 'muted', loop: 'loop' } %source{ src: @media_attachment.file.url(:original) } - elsif @media_attachment.audio? - = react_component :audio, src: @media_attachment.file.url(:original), poster: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.account.avatar_static_url, backgroundColor: meta.dig('colors', 'background'), foregroundColor: meta.dig('colors', 'foreground'), accentColor: meta.dig('colors', 'accent'), width: 670, height: 380, fullscreen: true, alt: @media_attachment.description, duration: meta.dig(:original, :duration) do + = react_component :audio, + accentColor: meta.dig('colors', 'accent'), + alt: @media_attachment.description, + backgroundColor: meta.dig('colors', 'background'), + duration: meta.dig(:original, :duration), + foregroundColor: meta.dig('colors', 'foreground'), + fullscreen: true, + height: 380, + poster: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.account.avatar_static_url, + src: @media_attachment.file.url(:original), + width: 670 do %audio{ controls: 'controls' } %source{ src: @media_attachment.file.url(:original) } From 742d8d30e2bdbd2bb42676fc8ab7ebf0ecf21966 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 04:36:12 -0500 Subject: [PATCH 14/23] Add coverage for `--days` option to CLI `media refresh` command (#28669) --- spec/lib/mastodon/cli/media_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/lib/mastodon/cli/media_spec.rb b/spec/lib/mastodon/cli/media_spec.rb index 071bcd9e34a..10005107aa5 100644 --- a/spec/lib/mastodon/cli/media_spec.rb +++ b/spec/lib/mastodon/cli/media_spec.rb @@ -183,6 +183,21 @@ describe Mastodon::CLI::Media do .to output_results('Downloaded 1 media') end end + + context 'with --days option' do + before do + Fabricate(:media_attachment, remote_url: 'https://example.com/image.jpg', id: Mastodon::Snowflake.id_at(50.days.ago)) + Fabricate(:media_attachment, remote_url: 'https://example.com/image.jpg', id: Mastodon::Snowflake.id_at(5.days.ago)) + Fabricate(:media_attachment, remote_url: '', id: Mastodon::Snowflake.id_at(5.days.ago)) + end + + let(:options) { { days: 10 } } + + it 'redownloads the attachment file for the remote records more recent than the option' do + expect { subject } + .to output_results('Downloaded 1 media') + end + end end describe '#remove_orphans' do From 36b46ea3b5b4a4fb51cf1cd103b5a3c1103c300e Mon Sep 17 00:00:00 2001 From: zunda Date: Wed, 10 Jan 2024 09:37:31 +0000 Subject: [PATCH 15/23] bundle add csv (#28671) --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index e0980c07204..e096a5d6857 100644 --- a/Gemfile +++ b/Gemfile @@ -48,6 +48,7 @@ gem 'omniauth', '~> 2.0' gem 'omniauth-rails_csrf_protection', '~> 1.0' gem 'color_diff', '~> 0.1' +gem 'csv', '~> 3.2' gem 'discard', '~> 1.2' gem 'doorkeeper', '~> 5.6' gem 'ed25519', '~> 1.3' diff --git a/Gemfile.lock b/Gemfile.lock index 91b3bf701fd..595c9fd2795 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -208,6 +208,7 @@ GEM crass (1.0.6) css_parser (1.14.0) addressable + csv (3.2.8) database_cleaner-active_record (2.1.0) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) @@ -845,6 +846,7 @@ DEPENDENCIES color_diff (~> 0.1) concurrent-ruby connection_pool + csv (~> 3.2) database_cleaner-active_record debug (~> 1.8) devise (~> 4.9) From ea1c0feb86e3b1213b0808cef43446b5146d50da Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 05:35:06 -0500 Subject: [PATCH 16/23] Remove `add_column_with_default` migration helper (#28654) --- ...16191202_add_hide_notifications_to_mute.rb | 6 +-- ...005171936_add_disabled_to_custom_emojis.rb | 6 +-- .../20171028221157_add_reblogs_to_follows.rb | 8 +--- ...20171107143332_add_memorial_to_accounts.rb | 6 +-- .../20171107143624_add_disabled_to_users.rb | 6 +-- ...0171109012327_add_moderator_to_accounts.rb | 6 +-- ...30000000_add_embed_url_to_preview_cards.rb | 6 +-- ...0180615122121_add_autofollow_to_invites.rb | 6 +-- ...7154237_add_whole_word_to_custom_filter.rb | 6 +-- ..._confidential_to_doorkeeper_application.rb | 8 +--- .../20181010141500_add_silent_to_mentions.rb | 8 +--- ...937_add_reject_reports_to_domain_blocks.rb | 6 +-- ...649_add_unread_to_account_conversations.rb | 8 +--- ...0181127165847_add_show_replies_to_lists.rb | 8 +--- ...20190201012802_add_overwrite_to_imports.rb | 6 +-- ...0190306145741_add_lock_version_to_polls.rb | 8 +--- .../20190307234537_add_approved_to_users.rb | 8 +--- ...13028_add_lock_version_to_account_stats.rb | 6 +-- ...58_add_title_to_account_warning_presets.rb | 6 +-- .../20200917192924_add_notify_to_follows.rb | 8 +--- ...18054746_add_obfuscate_to_domain_blocks.rb | 6 +-- .../20211231080958_add_category_to_reports.rb | 6 +-- ...0613110834_add_action_to_custom_filters.rb | 6 +-- .../20230605085710_add_exclusive_to_lists.rb | 6 +-- ..._add_image_description_to_preview_cards.rb | 6 +-- ...0230814223300_add_indexable_to_accounts.rb | 6 +-- ...2_remove_whole_word_from_custom_filters.rb | 6 +-- ...remove_irreversible_from_custom_filters.rb | 6 +-- lib/mastodon/migration_helpers.rb | 41 +------------------ 29 files changed, 37 insertions(+), 188 deletions(-) diff --git a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb index b817d512de4..2ef5d257917 100644 --- a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb +++ b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddHideNotificationsToMute < ActiveRecord::Migration[5.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - add_column_with_default :mutes, :hide_notifications, :boolean, default: true, allow_null: false + add_column :mutes, :hide_notifications, :boolean, default: true, null: false end def down diff --git a/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb b/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb index d6fd228f955..eaf5f4ef2d0 100644 --- a/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb +++ b/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddDisabledToCustomEmojis < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :custom_emojis, :disabled, :bool, default: false } + safety_assured { add_column :custom_emojis, :disabled, :bool, default: false, null: false } end def down diff --git a/db/migrate/20171028221157_add_reblogs_to_follows.rb b/db/migrate/20171028221157_add_reblogs_to_follows.rb index 0dab84c7999..068d66d1da3 100644 --- a/db/migrate/20171028221157_add_reblogs_to_follows.rb +++ b/db/migrate/20171028221157_add_reblogs_to_follows.rb @@ -1,16 +1,12 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddReblogsToFollows < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :follows, :show_reblogs, :boolean, default: true, allow_null: false - add_column_with_default :follow_requests, :show_reblogs, :boolean, default: true, allow_null: false + add_column :follows, :show_reblogs, :boolean, default: true, null: false + add_column :follow_requests, :show_reblogs, :boolean, default: true, null: false end end diff --git a/db/migrate/20171107143332_add_memorial_to_accounts.rb b/db/migrate/20171107143332_add_memorial_to_accounts.rb index 3cf782b81fe..35a98f45e85 100644 --- a/db/migrate/20171107143332_add_memorial_to_accounts.rb +++ b/db/migrate/20171107143332_add_memorial_to_accounts.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddMemorialToAccounts < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :accounts, :memorial, :bool, default: false } + safety_assured { add_column :accounts, :memorial, :bool, default: false, null: false } end def down diff --git a/db/migrate/20171107143624_add_disabled_to_users.rb b/db/migrate/20171107143624_add_disabled_to_users.rb index 4ab4df73728..055d05b1095 100644 --- a/db/migrate/20171107143624_add_disabled_to_users.rb +++ b/db/migrate/20171107143624_add_disabled_to_users.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddDisabledToUsers < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :users, :disabled, :bool, default: false } + safety_assured { add_column :users, :disabled, :bool, default: false, null: false } end def down diff --git a/db/migrate/20171109012327_add_moderator_to_accounts.rb b/db/migrate/20171109012327_add_moderator_to_accounts.rb index e8fc313c8c6..6a29e5aafea 100644 --- a/db/migrate/20171109012327_add_moderator_to_accounts.rb +++ b/db/migrate/20171109012327_add_moderator_to_accounts.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddModeratorToAccounts < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :users, :moderator, :bool, default: false } + safety_assured { add_column :users, :moderator, :bool, default: false, null: false } end def down diff --git a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb index e78373b24cd..f2336e8e25d 100644 --- a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb +++ b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddEmbedURLToPreviewCards < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :preview_cards, :embed_url, :string, default: '', allow_null: false + add_column :preview_cards, :embed_url, :string, default: '', null: false end end diff --git a/db/migrate/20180615122121_add_autofollow_to_invites.rb b/db/migrate/20180615122121_add_autofollow_to_invites.rb index ef129003a15..19a5f0d1715 100644 --- a/db/migrate/20180615122121_add_autofollow_to_invites.rb +++ b/db/migrate/20180615122121_add_autofollow_to_invites.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddAutofollowToInvites < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :invites, :autofollow, :bool, default: false, allow_null: false + add_column :invites, :autofollow, :bool, default: false, null: false end end diff --git a/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb b/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb index 793c3e6cfb4..519dfdfae1d 100644 --- a/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb +++ b/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddWholeWordToCustomFilter < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def change safety_assured do - add_column_with_default :custom_filters, :whole_word, :boolean, default: true, allow_null: false + add_column :custom_filters, :whole_word, :boolean, default: true, null: false end end diff --git a/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb b/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb index 7360c71ac91..6544b81c8e5 100644 --- a/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb +++ b/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddConfidentialToDoorkeeperApplication < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :oauth_applications, :confidential, :boolean, - allow_null: false, + null: false, default: true # maintaining backwards compatibility: require secrets ) end diff --git a/db/migrate/20181010141500_add_silent_to_mentions.rb b/db/migrate/20181010141500_add_silent_to_mentions.rb index f9bfc516948..029119e79bb 100644 --- a/db/migrate/20181010141500_add_silent_to_mentions.rb +++ b/db/migrate/20181010141500_add_silent_to_mentions.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddSilentToMentions < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :mentions, :silent, :boolean, - allow_null: false, + null: false, default: false ) end diff --git a/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb b/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb index b6cfd31d25a..49bd2b02f72 100644 --- a/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb +++ b/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddRejectReportsToDomainBlocks < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :domain_blocks, :reject_reports, :boolean, default: false, allow_null: false + add_column :domain_blocks, :reject_reports, :boolean, default: false, null: false end end diff --git a/db/migrate/20181018205649_add_unread_to_account_conversations.rb b/db/migrate/20181018205649_add_unread_to_account_conversations.rb index fec9476398a..ae4576255d2 100644 --- a/db/migrate/20181018205649_add_unread_to_account_conversations.rb +++ b/db/migrate/20181018205649_add_unread_to_account_conversations.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddUnreadToAccountConversations < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :account_conversations, :unread, :boolean, - allow_null: false, + null: false, default: false ) end diff --git a/db/migrate/20181127165847_add_show_replies_to_lists.rb b/db/migrate/20181127165847_add_show_replies_to_lists.rb index 45d457b748e..a391d9f6f09 100644 --- a/db/migrate/20181127165847_add_show_replies_to_lists.rb +++ b/db/migrate/20181127165847_add_show_replies_to_lists.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddShowRepliesToLists < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :lists, :replies_policy, :integer, - allow_null: false, + null: false, default: 0 ) end diff --git a/db/migrate/20190201012802_add_overwrite_to_imports.rb b/db/migrate/20190201012802_add_overwrite_to_imports.rb index fe9423ed04c..b497950eef2 100644 --- a/db/migrate/20190201012802_add_overwrite_to_imports.rb +++ b/db/migrate/20190201012802_add_overwrite_to_imports.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddOverwriteToImports < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :imports, :overwrite, :boolean, default: false, allow_null: false + add_column :imports, :overwrite, :boolean, default: false, null: false end end diff --git a/db/migrate/20190306145741_add_lock_version_to_polls.rb b/db/migrate/20190306145741_add_lock_version_to_polls.rb index 760818d97bf..ec4430ea945 100644 --- a/db/migrate/20190306145741_add_lock_version_to_polls.rb +++ b/db/migrate/20190306145741_add_lock_version_to_polls.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddLockVersionToPolls < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :polls, :lock_version, :integer, - allow_null: false, + null: false, default: 0 ) end diff --git a/db/migrate/20190307234537_add_approved_to_users.rb b/db/migrate/20190307234537_add_approved_to_users.rb index 9abab29c932..ffdc24716ea 100644 --- a/db/migrate/20190307234537_add_approved_to_users.rb +++ b/db/migrate/20190307234537_add_approved_to_users.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddApprovedToUsers < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :users, :approved, :bool, - allow_null: false, + null: false, default: true ) end diff --git a/db/migrate/20191001213028_add_lock_version_to_account_stats.rb b/db/migrate/20191001213028_add_lock_version_to_account_stats.rb index 0dc1655596f..3ffbacf25f6 100644 --- a/db/migrate/20191001213028_add_lock_version_to_account_stats.rb +++ b/db/migrate/20191001213028_add_lock_version_to_account_stats.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddLockVersionToAccountStats < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :account_stats, :lock_version, :integer, allow_null: false, default: 0 } + safety_assured { add_column :account_stats, :lock_version, :integer, null: false, default: 0 } end def down diff --git a/db/migrate/20200312144258_add_title_to_account_warning_presets.rb b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb index 78b854f82c6..63d339c49c7 100644 --- a/db/migrate/20200312144258_add_title_to_account_warning_presets.rb +++ b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddTitleToAccountWarningPresets < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :account_warning_presets, :title, :string, default: '', allow_null: false } + safety_assured { add_column :account_warning_presets, :title, :string, default: '', null: false } end def down diff --git a/db/migrate/20200917192924_add_notify_to_follows.rb b/db/migrate/20200917192924_add_notify_to_follows.rb index a57bb36dc24..1dc831dc47e 100644 --- a/db/migrate/20200917192924_add_notify_to_follows.rb +++ b/db/migrate/20200917192924_add_notify_to_follows.rb @@ -1,16 +1,12 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddNotifyToFollows < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :follows, :notify, :boolean, default: false, allow_null: false - add_column_with_default :follow_requests, :notify, :boolean, default: false, allow_null: false + add_column :follows, :notify, :boolean, default: false, null: false + add_column :follow_requests, :notify, :boolean, default: false, null: false end end diff --git a/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb b/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb index 91bba38c586..d7038c83dcf 100644 --- a/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb +++ b/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddObfuscateToDomainBlocks < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :domain_blocks, :obfuscate, :boolean, default: false, allow_null: false } + safety_assured { add_column :domain_blocks, :obfuscate, :boolean, default: false, null: false } end def down diff --git a/db/migrate/20211231080958_add_category_to_reports.rb b/db/migrate/20211231080958_add_category_to_reports.rb index f114cda615e..a20a3155d64 100644 --- a/db/migrate/20211231080958_add_category_to_reports.rb +++ b/db/migrate/20211231080958_add_category_to_reports.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddCategoryToReports < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :reports, :category, :int, default: 0, allow_null: false + add_column :reports, :category, :int, default: 0, null: false change_table(:reports, bulk: true) do |t| t.column :action_taken_at, :datetime t.column :rule_ids, :bigint, array: true diff --git a/db/migrate/20220613110834_add_action_to_custom_filters.rb b/db/migrate/20220613110834_add_action_to_custom_filters.rb index c1daf3c9485..ab2f7c65e7f 100644 --- a/db/migrate/20220613110834_add_action_to_custom_filters.rb +++ b/db/migrate/20220613110834_add_action_to_custom_filters.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddActionToCustomFilters < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :custom_filters, :action, :integer, allow_null: false, default: 0 + add_column :custom_filters, :action, :integer, null: false, default: 0 execute 'UPDATE custom_filters SET action = 1 WHERE irreversible IS TRUE' end end diff --git a/db/migrate/20230605085710_add_exclusive_to_lists.rb b/db/migrate/20230605085710_add_exclusive_to_lists.rb index 315c9d48723..abcb8fae1e0 100644 --- a/db/migrate/20230605085710_add_exclusive_to_lists.rb +++ b/db/migrate/20230605085710_add_exclusive_to_lists.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddExclusiveToLists < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :lists, :exclusive, :boolean, default: false, allow_null: false } + safety_assured { add_column :lists, :exclusive, :boolean, default: false, null: false } end def down diff --git a/db/migrate/20230725213448_add_image_description_to_preview_cards.rb b/db/migrate/20230725213448_add_image_description_to_preview_cards.rb index 03020db655a..7445a0e7fc8 100644 --- a/db/migrate/20230725213448_add_image_description_to_preview_cards.rb +++ b/db/migrate/20230725213448_add_image_description_to_preview_cards.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddImageDescriptionToPreviewCards < ActiveRecord::Migration[7.0] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :preview_cards, :image_description, :string, default: '', allow_null: false } + safety_assured { add_column :preview_cards, :image_description, :string, default: '', null: false } end def down diff --git a/db/migrate/20230814223300_add_indexable_to_accounts.rb b/db/migrate/20230814223300_add_indexable_to_accounts.rb index 6729c05ef29..0544eb92fe4 100644 --- a/db/migrate/20230814223300_add_indexable_to_accounts.rb +++ b/db/migrate/20230814223300_add_indexable_to_accounts.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddIndexableToAccounts < ActiveRecord::Migration[7.0] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :accounts, :indexable, :boolean, default: false, allow_null: false } + safety_assured { add_column :accounts, :indexable, :boolean, default: false, null: false } end def down diff --git a/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb b/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb index 99c3366a209..5e477d9b11c 100644 --- a/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb +++ b/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class RemoveWholeWordFromCustomFilters < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up @@ -15,7 +11,7 @@ class RemoveWholeWordFromCustomFilters < ActiveRecord::Migration[6.1] def down safety_assured do - add_column_with_default :custom_filters, :whole_word, :boolean, default: true, allow_null: false + add_column :custom_filters, :whole_word, :boolean, default: true, null: false end end end diff --git a/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb b/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb index 1c366ee53cd..1ed009fe99c 100644 --- a/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb +++ b/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class RemoveIrreversibleFromCustomFilters < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up @@ -15,7 +11,7 @@ class RemoveIrreversibleFromCustomFilters < ActiveRecord::Migration[6.1] def down safety_assured do - add_column_with_default :custom_filters, :irreversible, :boolean, allow_null: false, default: false + add_column :custom_filters, :irreversible, :boolean, null: false, default: false end end end diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb index 7bc12988384..1a2ce6420fc 100644 --- a/lib/mastodon/migration_helpers.rb +++ b/lib/mastodon/migration_helpers.rb @@ -104,18 +104,7 @@ module Mastodon 'in the body of your migration class' end - # If default value is presented, use `add_column_with_default` method instead. - if options[:default] - add_column_with_default( - table_name, - column_name, - :datetime_with_timezone, - default: options[:default], - allow_null: options[:null] - ) - else - add_column(table_name, column_name, :datetime_with_timezone, **options) - end + add_column(table_name, column_name, :datetime_with_timezone, **options) end end @@ -377,34 +366,6 @@ module Mastodon end end - # Adds a column with a default value without locking an entire table. - # - # This method runs the following steps: - # - # 1. Add the column with a default value of NULL. - # 2. Change the default value of the column to the specified value. - # 3. Update all existing rows in batches. - # 4. Set a `NOT NULL` constraint on the column if desired (the default). - # - # These steps ensure a column can be added to a large and commonly used - # table without locking the entire table for the duration of the table - # modification. - # - # table - The name of the table to update. - # column - The name of the column to add. - # type - The column type (e.g. `:integer`). - # default - The default value for the column. - # limit - Sets a column limit. For example, for :integer, the default is - # 4-bytes. Set `limit: 8` to allow 8-byte integers. - # allow_null - When set to `true` the column will allow NULL values, the - # default is to not allow NULL values. - # - # This method can also take a block which is passed directly to the - # `update_column_in_batches` method. - def add_column_with_default(table, column, type, default:, limit: nil, allow_null: false, &block) - add_column(table, column, type, default: default, limit: limit, null: allow_null) - end - # Renames a column without requiring downtime. # # Concurrent renames work by using database triggers to ensure both the From 00341c70ffea2cdef9d6e73f6897ffbab04401f0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 06:06:58 -0500 Subject: [PATCH 17/23] Use Sidekiq `fake!` instead of `inline!` in specs (#25369) --- .../admin/disputes/appeals_controller_spec.rb | 4 ++-- .../admin/domain_blocks_controller_spec.rb | 2 +- spec/controllers/admin/resets_controller_spec.rb | 2 +- .../api/v1/conversations_controller_spec.rb | 2 +- .../api/v1/statuses/reblogs_controller_spec.rb | 4 ++-- spec/controllers/auth/sessions_controller_spec.rb | 2 +- .../concerns/user_tracking_concern_spec.rb | 2 +- spec/controllers/disputes/appeals_controller_spec.rb | 2 +- spec/controllers/settings/deletes_controller_spec.rb | 2 +- spec/controllers/settings/exports_controller_spec.rb | 2 +- spec/features/admin/accounts_spec.rb | 2 +- spec/lib/activitypub/activity/create_spec.rb | 2 +- spec/lib/activitypub/activity/delete_spec.rb | 2 +- spec/lib/activitypub/activity/move_spec.rb | 2 +- spec/models/admin/account_action_spec.rb | 2 +- spec/models/user_spec.rb | 4 ++-- spec/rails_helper.rb | 8 ++------ spec/requests/api/v1/featured_tags_spec.rb | 2 +- spec/requests/api/v1/notifications_spec.rb | 2 +- spec/requests/api/v1/statuses/favourites_spec.rb | 8 ++------ spec/requests/api/v1/timelines/home_spec.rb | 2 +- .../models/concerns/account/statuses_search_spec.rb | 2 +- .../activitypub/fetch_remote_status_service_spec.rb | 2 +- .../activitypub/process_account_service_spec.rb | 2 +- spec/services/authorize_follow_service_spec.rb | 2 +- spec/services/batched_remove_status_service_spec.rb | 2 +- spec/services/block_domain_service_spec.rb | 2 +- spec/services/block_service_spec.rb | 2 +- spec/services/bulk_import_service_spec.rb | 2 +- spec/services/delete_account_service_spec.rb | 4 ++-- spec/services/fan_out_on_write_service_spec.rb | 12 +++++------- spec/services/favourite_service_spec.rb | 2 +- spec/services/follow_service_spec.rb | 2 +- spec/services/import_service_spec.rb | 2 +- spec/services/mute_service_spec.rb | 2 +- spec/services/notify_service_spec.rb | 2 +- spec/services/reblog_service_spec.rb | 2 +- spec/services/reject_follow_service_spec.rb | 2 +- spec/services/remove_from_followers_service_spec.rb | 2 +- spec/services/remove_status_service_spec.rb | 2 +- spec/services/report_service_spec.rb | 2 +- spec/services/resolve_account_service_spec.rb | 2 +- spec/services/suspend_account_service_spec.rb | 2 +- spec/services/unallow_domain_service_spec.rb | 2 +- spec/services/unblock_service_spec.rb | 2 +- spec/services/unfollow_service_spec.rb | 4 ++-- spec/services/unsuspend_account_service_spec.rb | 2 +- spec/services/update_account_service_spec.rb | 2 +- spec/services/update_status_service_spec.rb | 2 +- spec/system/new_statuses_spec.rb | 2 +- spec/workers/backup_worker_spec.rb | 2 +- spec/workers/move_worker_spec.rb | 6 +++--- spec/workers/poll_expiration_notify_worker_spec.rb | 2 +- 53 files changed, 66 insertions(+), 76 deletions(-) diff --git a/spec/controllers/admin/disputes/appeals_controller_spec.rb b/spec/controllers/admin/disputes/appeals_controller_spec.rb index 4581d00d6f7..f830c3b95c9 100644 --- a/spec/controllers/admin/disputes/appeals_controller_spec.rb +++ b/spec/controllers/admin/disputes/appeals_controller_spec.rb @@ -44,7 +44,7 @@ RSpec.describe Admin::Disputes::AppealsController do expect(response).to redirect_to(disputes_strike_path(appeal.strike)) end - it 'notifies target account about approved appeal' do + it 'notifies target account about approved appeal', :sidekiq_inline do expect(UserMailer.deliveries.size).to eq(1) expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email) expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at))) @@ -62,7 +62,7 @@ RSpec.describe Admin::Disputes::AppealsController do expect(response).to redirect_to(disputes_strike_path(appeal.strike)) end - it 'notifies target account about rejected appeal' do + it 'notifies target account about rejected appeal', :sidekiq_inline do expect(UserMailer.deliveries.size).to eq(1) expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email) expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at))) diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb index 22960f53126..87b08323da9 100644 --- a/spec/controllers/admin/domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/domain_blocks_controller_spec.rb @@ -176,7 +176,7 @@ RSpec.describe Admin::DomainBlocksController do end end - describe 'PUT #update' do + describe 'PUT #update', :sidekiq_inline do subject do post :update, params: { :id => domain_block.id, :domain_block => { domain: 'example.com', severity: new_severity }, 'confirm' => '' } end diff --git a/spec/controllers/admin/resets_controller_spec.rb b/spec/controllers/admin/resets_controller_spec.rb index 14826973c12..e82a3a6afa7 100644 --- a/spec/controllers/admin/resets_controller_spec.rb +++ b/spec/controllers/admin/resets_controller_spec.rb @@ -11,7 +11,7 @@ describe Admin::ResetsController do sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end - describe 'POST #create' do + describe 'POST #create', :sidekiq_inline do it 'redirects to admin accounts page' do expect do post :create, params: { account_id: account.id } diff --git a/spec/controllers/api/v1/conversations_controller_spec.rb b/spec/controllers/api/v1/conversations_controller_spec.rb index 50e2a62efd8..2734e4a07b4 100644 --- a/spec/controllers/api/v1/conversations_controller_spec.rb +++ b/spec/controllers/api/v1/conversations_controller_spec.rb @@ -13,7 +13,7 @@ RSpec.describe Api::V1::ConversationsController do allow(controller).to receive(:doorkeeper_token) { token } end - describe 'GET #index' do + describe 'GET #index', :sidekiq_inline do let(:scopes) { 'read:statuses' } before do diff --git a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb index e3a9bdb5029..014a03c1a20 100644 --- a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb @@ -9,7 +9,7 @@ describe Api::V1::Statuses::ReblogsController do let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:statuses', application: app) } - context 'with an oauth token', :sidekiq_fake do + context 'with an oauth token' do before do allow(controller).to receive(:doorkeeper_token) { token } end @@ -46,7 +46,7 @@ describe Api::V1::Statuses::ReblogsController do end end - describe 'POST #destroy' do + describe 'POST #destroy', :sidekiq_inline do context 'with public status' do let(:status) { Fabricate(:status, account: user.account) } diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index 212cc4d5e5a..e3f2b278bda 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -138,7 +138,7 @@ RSpec.describe Auth::SessionsController do expect(controller.current_user).to eq user end - it 'sends a suspicious sign-in mail' do + it 'sends a suspicious sign-in mail', :sidekiq_inline do expect(UserMailer.deliveries.size).to eq(1) expect(UserMailer.deliveries.first.to.first).to eq(user.email) expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.suspicious_sign_in.subject')) diff --git a/spec/controllers/concerns/user_tracking_concern_spec.rb b/spec/controllers/concerns/user_tracking_concern_spec.rb index dd0b3c042a5..b1de3cf4e2e 100644 --- a/spec/controllers/concerns/user_tracking_concern_spec.rb +++ b/spec/controllers/concerns/user_tracking_concern_spec.rb @@ -75,7 +75,7 @@ describe UserTrackingConcern do expect(redis.ttl("account:#{user.account_id}:regeneration")).to be >= 0 end - it 'regenerates feed when sign in is older than two weeks' do + it 'regenerates feed when sign in is older than two weeks', :sidekiq_inline do get :show expect_updated_sign_in_at(user) diff --git a/spec/controllers/disputes/appeals_controller_spec.rb b/spec/controllers/disputes/appeals_controller_spec.rb index c8444a2a964..452bd60dc59 100644 --- a/spec/controllers/disputes/appeals_controller_spec.rb +++ b/spec/controllers/disputes/appeals_controller_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Disputes::AppealsController do post :create, params: { strike_id: strike.id, appeal: { text: 'Foo' } } end - it 'notifies staff about new appeal' do + it 'notifies staff about new appeal', :sidekiq_inline do expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email]) end diff --git a/spec/controllers/settings/deletes_controller_spec.rb b/spec/controllers/settings/deletes_controller_spec.rb index 2c1532ecd87..ccca4564e73 100644 --- a/spec/controllers/settings/deletes_controller_spec.rb +++ b/spec/controllers/settings/deletes_controller_spec.rb @@ -50,7 +50,7 @@ describe Settings::DeletesController do delete :destroy, params: { form_delete_confirmation: { password: 'petsmoldoggos' } } end - it 'removes user record and redirects', :aggregate_failures do + it 'removes user record and redirects', :aggregate_failures, :sidekiq_inline do expect(response).to redirect_to '/auth/sign_in' expect(User.find_by(id: user.id)).to be_nil expect(user.account.reload).to be_suspended diff --git a/spec/controllers/settings/exports_controller_spec.rb b/spec/controllers/settings/exports_controller_spec.rb index 0bd1e80c3cc..3399f78ac58 100644 --- a/spec/controllers/settings/exports_controller_spec.rb +++ b/spec/controllers/settings/exports_controller_spec.rb @@ -38,7 +38,7 @@ describe Settings::ExportsController do expect(response).to redirect_to(settings_export_path) end - it 'queues BackupWorker job by 1', :sidekiq_fake do + it 'queues BackupWorker job by 1' do expect do post :create end.to change(BackupWorker.jobs, :size).by(1) diff --git a/spec/features/admin/accounts_spec.rb b/spec/features/admin/accounts_spec.rb index 6d7bab1844c..54d755b914d 100644 --- a/spec/features/admin/accounts_spec.rb +++ b/spec/features/admin/accounts_spec.rb @@ -48,7 +48,7 @@ describe 'Admin::Accounts' do end end - context 'with action of `reject`' do + context 'with action of `reject`', :sidekiq_inline do it 'rejects and removes the account' do batch_checkbox_for(unapproved_user_account).check diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 8084427d067..3e3a4978c89 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -23,7 +23,7 @@ RSpec.describe ActivityPub::Activity::Create do stub_request(:get, 'http://example.com/emojib.png').to_return(body: attachment_fixture('emojo.png'), headers: { 'Content-Type' => 'application/octet-stream' }) end - describe 'processing posts received out of order', :sidekiq_fake do + describe 'processing posts received out of order' do let(:follower) { Fabricate(:account, username: 'bob') } let(:object_json) do diff --git a/spec/lib/activitypub/activity/delete_spec.rb b/spec/lib/activitypub/activity/delete_spec.rb index aec2c71e58a..48421a11629 100644 --- a/spec/lib/activitypub/activity/delete_spec.rb +++ b/spec/lib/activitypub/activity/delete_spec.rb @@ -47,7 +47,7 @@ RSpec.describe ActivityPub::Activity::Delete do expect(Status.find_by(id: status.id)).to be_nil end - it 'sends delete activity to followers of rebloggers' do + it 'sends delete activity to followers of rebloggers', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end diff --git a/spec/lib/activitypub/activity/move_spec.rb b/spec/lib/activitypub/activity/move_spec.rb index f3973c70cea..4dda014a068 100644 --- a/spec/lib/activitypub/activity/move_spec.rb +++ b/spec/lib/activitypub/activity/move_spec.rb @@ -38,7 +38,7 @@ RSpec.describe ActivityPub::Activity::Move do subject.perform end - context 'when all conditions are met' do + context 'when all conditions are met', :sidekiq_inline do it 'sets moved account on old account' do expect(old_account.reload.moved_to_account_id).to eq new_account.id end diff --git a/spec/models/admin/account_action_spec.rb b/spec/models/admin/account_action_spec.rb index 5d64d565fc5..9bc9f8061d7 100644 --- a/spec/models/admin/account_action_spec.rb +++ b/spec/models/admin/account_action_spec.rb @@ -46,7 +46,7 @@ RSpec.describe Admin::AccountAction do expect(target_account).to be_suspended end - it 'queues Admin::SuspensionWorker by 1', :sidekiq_fake do + it 'queues Admin::SuspensionWorker by 1' do expect do subject end.to change { Admin::SuspensionWorker.jobs.size }.by 1 diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ab5bd39b7b4..c8415df92a0 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -58,7 +58,7 @@ RSpec.describe User do end end - describe 'scopes' do + describe 'scopes', :sidekiq_inline do describe 'recent' do it 'returns an array of recent users ordered by id' do first_user = Fabricate(:user) @@ -452,7 +452,7 @@ RSpec.describe User do expect(user.confirmed_at).to be_present end - it 'delivers mails' do + it 'delivers mails', :sidekiq_inline do expect(ActionMailer::Base.deliveries.count).to eq 2 end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index e5d432b45f9..783258b3af0 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -26,7 +26,6 @@ Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } ActiveRecord::Migration.maintain_test_schema! WebMock.disable_net_connect!(allow: Chewy.settings[:host], allow_localhost: RUN_SYSTEM_SPECS) -Sidekiq::Testing.inline! Sidekiq.logger = nil # System tests config @@ -96,11 +95,8 @@ RSpec.configure do |config| self.use_transactional_tests = true end - config.around(:each, :sidekiq_fake) do |example| - Sidekiq::Testing.fake! do - example.run - Sidekiq::Worker.clear_all - end + config.around(:each, :sidekiq_inline) do |example| + Sidekiq::Testing.inline!(&example) end config.before :each, type: :cli do diff --git a/spec/requests/api/v1/featured_tags_spec.rb b/spec/requests/api/v1/featured_tags_spec.rb index c4aa2c0a2db..f499dd1d09a 100644 --- a/spec/requests/api/v1/featured_tags_spec.rb +++ b/spec/requests/api/v1/featured_tags_spec.rb @@ -147,7 +147,7 @@ RSpec.describe 'FeaturedTags' do expect(body).to be_empty end - it 'deletes the featured tag' do + it 'deletes the featured tag', :sidekiq_inline do delete "/api/v1/featured_tags/#{id}", headers: headers featured_tag = FeaturedTag.find_by(id: id) diff --git a/spec/requests/api/v1/notifications_spec.rb b/spec/requests/api/v1/notifications_spec.rb index 7a904816e05..222ff67fc87 100644 --- a/spec/requests/api/v1/notifications_spec.rb +++ b/spec/requests/api/v1/notifications_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Notifications' do let(:scopes) { 'read:notifications write:notifications' } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } - describe 'GET /api/v1/notifications' do + describe 'GET /api/v1/notifications', :sidekiq_inline do subject do get '/api/v1/notifications', headers: headers, params: params end diff --git a/spec/requests/api/v1/statuses/favourites_spec.rb b/spec/requests/api/v1/statuses/favourites_spec.rb index 8f3e6e5c421..033aed7e285 100644 --- a/spec/requests/api/v1/statuses/favourites_spec.rb +++ b/spec/requests/api/v1/statuses/favourites_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe 'Favourites' do +RSpec.describe 'Favourites', :sidekiq_inline do let(:user) { Fabricate(:user) } let(:scopes) { 'write:favourites' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } @@ -70,7 +70,7 @@ RSpec.describe 'Favourites' do end end - describe 'POST /api/v1/statuses/:status_id/unfavourite', :sidekiq_fake do + describe 'POST /api/v1/statuses/:status_id/unfavourite' do subject do post "/api/v1/statuses/#{status.id}/unfavourite", headers: headers end @@ -88,9 +88,7 @@ RSpec.describe 'Favourites' do subject expect(response).to have_http_status(200) - expect(user.account.favourited?(status)).to be true - UnfavouriteWorker.drain expect(user.account.favourited?(status)).to be false end @@ -113,9 +111,7 @@ RSpec.describe 'Favourites' do subject expect(response).to have_http_status(200) - expect(user.account.favourited?(status)).to be true - UnfavouriteWorker.drain expect(user.account.favourited?(status)).to be false end diff --git a/spec/requests/api/v1/timelines/home_spec.rb b/spec/requests/api/v1/timelines/home_spec.rb index 5834b909557..e57e9643bf6 100644 --- a/spec/requests/api/v1/timelines/home_spec.rb +++ b/spec/requests/api/v1/timelines/home_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe 'Home' do +describe 'Home', :sidekiq_inline do let(:user) { Fabricate(:user) } let(:scopes) { 'read:statuses' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } diff --git a/spec/search/models/concerns/account/statuses_search_spec.rb b/spec/search/models/concerns/account/statuses_search_spec.rb index bf2606eecea..915bc094cb5 100644 --- a/spec/search/models/concerns/account/statuses_search_spec.rb +++ b/spec/search/models/concerns/account/statuses_search_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe Account::StatusesSearch do +describe Account::StatusesSearch, :sidekiq_inline do describe 'a non-indexable account becoming indexable' do let(:account) { Account.find_by(username: 'search_test_account_1') } diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb index 3c64feaeec8..0fb32d20b19 100644 --- a/spec/services/activitypub/fetch_remote_status_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb @@ -225,7 +225,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do end end - context 'with statuses referencing other statuses' do + context 'with statuses referencing other statuses', :sidekiq_inline do before do stub_const 'ActivityPub::FetchRemoteStatusService::DISCOVERIES_PER_REQUEST', 5 end diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb index 58dd2badbb3..9abe03181e7 100644 --- a/spec/services/activitypub/process_account_service_spec.rb +++ b/spec/services/activitypub/process_account_service_spec.rb @@ -193,7 +193,7 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end end - it 'creates accounts without exceeding rate limit' do + it 'creates accounts without exceeding rate limit', :sidekiq_inline do expect { subject.call('user1', 'foo.test', payload) } .to create_some_remote_accounts .and create_fewer_than_rate_limit_accounts diff --git a/spec/services/authorize_follow_service_spec.rb b/spec/services/authorize_follow_service_spec.rb index d07645ab6b1..602250ee96f 100644 --- a/spec/services/authorize_follow_service_spec.rb +++ b/spec/services/authorize_follow_service_spec.rb @@ -41,7 +41,7 @@ RSpec.describe AuthorizeFollowService, type: :service do expect(bob.following?(sender)).to be true end - it 'sends an accept activity' do + it 'sends an accept activity', :sidekiq_inline do expect(a_request(:post, bob.inbox_url)).to have_been_made.once end end diff --git a/spec/services/batched_remove_status_service_spec.rb b/spec/services/batched_remove_status_service_spec.rb index 991a852f0e2..1c59d5ed06f 100644 --- a/spec/services/batched_remove_status_service_spec.rb +++ b/spec/services/batched_remove_status_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe BatchedRemoveStatusService, type: :service do +RSpec.describe BatchedRemoveStatusService, :sidekiq_inline, type: :service do subject { described_class.new } let!(:alice) { Fabricate(:account) } diff --git a/spec/services/block_domain_service_spec.rb b/spec/services/block_domain_service_spec.rb index fc3a1397d96..7ad00fff68a 100644 --- a/spec/services/block_domain_service_spec.rb +++ b/spec/services/block_domain_service_spec.rb @@ -68,7 +68,7 @@ RSpec.describe BlockDomainService, type: :service do expect(already_banned_account.reload.silenced_at).to_not eq DomainBlock.find_by(domain: 'evil.org').created_at end - it 'leaves the domains status and attachments, but clears media' do + it 'leaves the domains status and attachments, but clears media', :sidekiq_inline do expect { bad_status_plain.reload }.to_not raise_error expect { bad_status_with_attachment.reload }.to_not raise_error expect { bad_attachment.reload }.to_not raise_error diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb index 5f7c2e8da08..9e4ff8e598a 100644 --- a/spec/services/block_service_spec.rb +++ b/spec/services/block_service_spec.rb @@ -31,7 +31,7 @@ RSpec.describe BlockService, type: :service do expect(sender.blocking?(bob)).to be true end - it 'sends a block activity' do + it 'sends a block activity', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/bulk_import_service_spec.rb b/spec/services/bulk_import_service_spec.rb index f703650c378..c3a71605804 100644 --- a/spec/services/bulk_import_service_spec.rb +++ b/spec/services/bulk_import_service_spec.rb @@ -12,7 +12,7 @@ RSpec.describe BulkImportService do import.update(total_items: import.rows.count) end - describe '#call', :sidekiq_fake do + describe '#call' do context 'when importing follows' do let(:import_type) { 'following' } let(:overwrite) { false } diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb index f04ba9cf140..1965b7daabe 100644 --- a/spec/services/delete_account_service_spec.rb +++ b/spec/services/delete_account_service_spec.rb @@ -62,7 +62,7 @@ RSpec.describe DeleteAccountService, type: :service do end end - describe '#call on local account' do + describe '#call on local account', :sidekiq_inline do before do stub_request(:post, remote_alice.inbox_url).to_return(status: 201) stub_request(:post, remote_bob.inbox_url).to_return(status: 201) @@ -83,7 +83,7 @@ RSpec.describe DeleteAccountService, type: :service do end end - describe '#call on remote account' do + describe '#call on remote account', :sidekiq_inline do before do stub_request(:post, account.inbox_url).to_return(status: 201) end diff --git a/spec/services/fan_out_on_write_service_spec.rb b/spec/services/fan_out_on_write_service_spec.rb index 6ad041193bc..77237dffbdd 100644 --- a/spec/services/fan_out_on_write_service_spec.rb +++ b/spec/services/fan_out_on_write_service_spec.rb @@ -38,7 +38,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of a follower' do + it 'is added to the home feed of a follower', :sidekiq_inline do expect(home_feed_of(bob)).to include status.id expect(home_feed_of(tom)).to include status.id end @@ -62,7 +62,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of the mentioned follower' do + it 'is added to the home feed of the mentioned follower', :sidekiq_inline do expect(home_feed_of(bob)).to include status.id end @@ -83,7 +83,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of a follower' do + it 'is added to the home feed of a follower', :sidekiq_inline do expect(home_feed_of(bob)).to include status.id expect(home_feed_of(tom)).to include status.id end @@ -101,7 +101,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of the mentioned follower' do + it 'is added to the home feed of the mentioned follower', :sidekiq_inline do expect(home_feed_of(bob)).to include status.id end @@ -114,7 +114,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(redis).to_not have_received(:publish).with('timeline:public', anything) end - context 'when handling status updates', :sidekiq_fake do + context 'when handling status updates' do before do subject.call(status) @@ -123,8 +123,6 @@ RSpec.describe FanOutOnWriteService, type: :service do status.snapshot!(account_id: status.account_id) redis.set("subscribed:timeline:#{eve.id}:notifications", '1') - - Sidekiq::Worker.clear_all end it 'pushes the update to mentioned users through the notifications streaming channel' do diff --git a/spec/services/favourite_service_spec.rb b/spec/services/favourite_service_spec.rb index 782c235c418..3143e7b669a 100644 --- a/spec/services/favourite_service_spec.rb +++ b/spec/services/favourite_service_spec.rb @@ -33,7 +33,7 @@ RSpec.describe FavouriteService, type: :service do expect(status.favourites.first).to_not be_nil end - it 'sends a like activity' do + it 'sends a like activity', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb index c2ad0d71739..cf4de34c89d 100644 --- a/spec/services/follow_service_spec.rb +++ b/spec/services/follow_service_spec.rb @@ -150,7 +150,7 @@ RSpec.describe FollowService, type: :service do expect(FollowRequest.find_by(account: sender, target_account: bob)).to_not be_nil end - it 'sends a follow activity to the inbox' do + it 'sends a follow activity to the inbox', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb index d67da66caf4..7d005c8a111 100644 --- a/spec/services/import_service_spec.rb +++ b/spec/services/import_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe ImportService, type: :service do +RSpec.describe ImportService, :sidekiq_inline, type: :service do include RoutingHelper let!(:account) { Fabricate(:account, locked: false) } diff --git a/spec/services/mute_service_spec.rb b/spec/services/mute_service_spec.rb index 50f74ff277f..a2ca2ffe135 100644 --- a/spec/services/mute_service_spec.rb +++ b/spec/services/mute_service_spec.rb @@ -17,7 +17,7 @@ RSpec.describe MuteService, type: :service do redis.del(home_timeline_key) end - it "clears account's statuses" do + it "clears account's statuses", :sidekiq_inline do FeedManager.instance.push_to_home(account, status) FeedManager.instance.push_to_home(account, other_account_status) diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb index 50055dafc76..38a33c522d0 100644 --- a/spec/services/notify_service_spec.rb +++ b/spec/services/notify_service_spec.rb @@ -166,7 +166,7 @@ RSpec.describe NotifyService, type: :service do context 'when email notification is enabled' do let(:enabled) { true } - it 'sends email' do + it 'sends email', :sidekiq_inline do expect { subject }.to change(ActionMailer::Base.deliveries, :count).by(1) end end diff --git a/spec/services/reblog_service_spec.rb b/spec/services/reblog_service_spec.rb index 7b85e37ed8c..c6d13e5a12c 100644 --- a/spec/services/reblog_service_spec.rb +++ b/spec/services/reblog_service_spec.rb @@ -87,7 +87,7 @@ RSpec.describe ReblogService, type: :service do expect(ActivityPub::DistributionWorker).to have_received(:perform_async) end - it 'sends an announce activity to the author' do + it 'sends an announce activity to the author', :sidekiq_inline do expect(a_request(:post, bob.inbox_url)).to have_been_made.once end end diff --git a/spec/services/reject_follow_service_spec.rb b/spec/services/reject_follow_service_spec.rb index d28104b2c78..48316a6c4d9 100644 --- a/spec/services/reject_follow_service_spec.rb +++ b/spec/services/reject_follow_service_spec.rb @@ -41,7 +41,7 @@ RSpec.describe RejectFollowService, type: :service do expect(bob.following?(sender)).to be false end - it 'sends a reject activity' do + it 'sends a reject activity', :sidekiq_inline do expect(a_request(:post, bob.inbox_url)).to have_been_made.once end end diff --git a/spec/services/remove_from_followers_service_spec.rb b/spec/services/remove_from_followers_service_spec.rb index 1b29cdcbea3..21da38a97bd 100644 --- a/spec/services/remove_from_followers_service_spec.rb +++ b/spec/services/remove_from_followers_service_spec.rb @@ -33,7 +33,7 @@ RSpec.describe RemoveFromFollowersService, type: :service do expect(bob.followed_by?(sender)).to be false end - it 'sends a reject activity' do + it 'sends a reject activity', :sidekiq_inline do expect(a_request(:post, sender.inbox_url)).to have_been_made.once end end diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb index cd3224e0285..63a9df548f8 100644 --- a/spec/services/remove_status_service_spec.rb +++ b/spec/services/remove_status_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe RemoveStatusService, type: :service do +RSpec.describe RemoveStatusService, :sidekiq_inline, type: :service do subject { described_class.new } let!(:alice) { Fabricate(:account) } diff --git a/spec/services/report_service_spec.rb b/spec/services/report_service_spec.rb index 2a919f6405e..39e14a6a1c7 100644 --- a/spec/services/report_service_spec.rb +++ b/spec/services/report_service_spec.rb @@ -23,7 +23,7 @@ RSpec.describe ReportService, type: :service do stub_request(:post, 'http://example.com/inbox').to_return(status: 200) end - context 'when forward is true' do + context 'when forward is true', :sidekiq_inline do let(:forward) { true } it 'sends ActivityPub payload when forward is true' do diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index 3c4b182e298..1c4c3b40160 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -195,7 +195,7 @@ RSpec.describe ResolveAccountService, type: :service do expect(account.uri).to eq 'https://ap.example.com/users/foo' end - it 'merges accounts' do + it 'merges accounts', :sidekiq_inline do account = subject.call('foo@ap.example.com') expect(status.reload.account_id).to eq account.id diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb index dcc8dbfd37d..4a5f8a0b6b3 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe SuspendAccountService, type: :service do +RSpec.describe SuspendAccountService, :sidekiq_inline, type: :service do shared_examples 'common behavior' do subject { described_class.new.call(account) } diff --git a/spec/services/unallow_domain_service_spec.rb b/spec/services/unallow_domain_service_spec.rb index d96e3541875..6ac6bc40162 100644 --- a/spec/services/unallow_domain_service_spec.rb +++ b/spec/services/unallow_domain_service_spec.rb @@ -12,7 +12,7 @@ RSpec.describe UnallowDomainService, type: :service do let!(:already_banned_account) { Fabricate(:account, username: 'badguy', domain: 'evil.org', suspended: true, silenced: true) } let!(:domain_allow) { Fabricate(:domain_allow, domain: 'evil.org') } - context 'with limited federation mode' do + context 'with limited federation mode', :sidekiq_inline do before do allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(true) end diff --git a/spec/services/unblock_service_spec.rb b/spec/services/unblock_service_spec.rb index 86632c39388..9813c5e7fae 100644 --- a/spec/services/unblock_service_spec.rb +++ b/spec/services/unblock_service_spec.rb @@ -33,7 +33,7 @@ RSpec.describe UnblockService, type: :service do expect(sender.blocking?(bob)).to be false end - it 'sends an unblock activity' do + it 'sends an unblock activity', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/unfollow_service_spec.rb b/spec/services/unfollow_service_spec.rb index 3e65e610ba5..18a25a676dd 100644 --- a/spec/services/unfollow_service_spec.rb +++ b/spec/services/unfollow_service_spec.rb @@ -20,7 +20,7 @@ RSpec.describe UnfollowService, type: :service do end end - describe 'remote ActivityPub' do + describe 'remote ActivityPub', :sidekiq_inline do let(:bob) { Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } before do @@ -38,7 +38,7 @@ RSpec.describe UnfollowService, type: :service do end end - describe 'remote ActivityPub (reverse)' do + describe 'remote ActivityPub (reverse)', :sidekiq_inline do let(:bob) { Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } before do diff --git a/spec/services/unsuspend_account_service_spec.rb b/spec/services/unsuspend_account_service_spec.rb index 211c39e6c72..c848767cd10 100644 --- a/spec/services/unsuspend_account_service_spec.rb +++ b/spec/services/unsuspend_account_service_spec.rb @@ -45,7 +45,7 @@ RSpec.describe UnsuspendAccountService, type: :service do remote_follower.follow!(account) end - it 'merges back into feeds of local followers and sends update' do + it 'merges back into feeds of local followers and sends update', :sidekiq_inline do subject expect_feeds_merged diff --git a/spec/services/update_account_service_spec.rb b/spec/services/update_account_service_spec.rb index 6318cc95fbb..9f4e36862d3 100644 --- a/spec/services/update_account_service_spec.rb +++ b/spec/services/update_account_service_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' RSpec.describe UpdateAccountService, type: :service do subject { described_class.new } - describe 'switching form locked to unlocked accounts' do + describe 'switching form locked to unlocked accounts', :sidekiq_inline do let(:account) { Fabricate(:account, locked: true) } let(:alice) { Fabricate(:account) } let(:bob) { Fabricate(:account) } diff --git a/spec/services/update_status_service_spec.rb b/spec/services/update_status_service_spec.rb index 7f9f746c2a7..55651c305d7 100644 --- a/spec/services/update_status_service_spec.rb +++ b/spec/services/update_status_service_spec.rb @@ -111,7 +111,7 @@ RSpec.describe UpdateStatusService, type: :service do end end - context 'when poll changes', :sidekiq_fake do + context 'when poll changes' do let(:account) { Fabricate(:account) } let!(:status) { Fabricate(:status, text: 'Foo', account: account, poll_attributes: { options: %w(Foo Bar), account: account, multiple: false, hide_totals: false, expires_at: 7.days.from_now }) } let!(:poll) { status.poll } diff --git a/spec/system/new_statuses_spec.rb b/spec/system/new_statuses_spec.rb index 02f2e283931..a3b816b4d59 100644 --- a/spec/system/new_statuses_spec.rb +++ b/spec/system/new_statuses_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe 'NewStatuses' do +describe 'NewStatuses', :sidekiq_inline do include ProfileStories subject { page } diff --git a/spec/workers/backup_worker_spec.rb b/spec/workers/backup_worker_spec.rb index 1a169513e96..987cbc7d609 100644 --- a/spec/workers/backup_worker_spec.rb +++ b/spec/workers/backup_worker_spec.rb @@ -14,7 +14,7 @@ describe BackupWorker do let(:backup) { Fabricate(:backup) } let!(:other_backup) { Fabricate(:backup, user: backup.user) } - it 'sends the backup to the service and removes other backups' do + it 'sends the backup to the service and removes other backups', :sidekiq_inline do expect do worker.perform(backup.id) end.to change(UserMailer.deliveries, :size).by(1) diff --git a/spec/workers/move_worker_spec.rb b/spec/workers/move_worker_spec.rb index 34b342710b2..0513dc42e52 100644 --- a/spec/workers/move_worker_spec.rb +++ b/spec/workers/move_worker_spec.rb @@ -104,7 +104,7 @@ describe MoveWorker do end shared_examples 'lists handling' do - it 'puts the new account on the list and makes valid lists', sidekiq: :inline do + it 'puts the new account on the list and makes valid lists', :sidekiq_inline do subject.perform(source_account.id, target_account.id) expect(list.accounts.include?(target_account)).to be true @@ -159,7 +159,7 @@ describe MoveWorker do describe '#perform' do context 'when both accounts are distant' do - it 'calls UnfollowFollowWorker', :sidekiq_fake do + it 'calls UnfollowFollowWorker' do subject.perform(source_account.id, target_account.id) expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, false) end @@ -170,7 +170,7 @@ describe MoveWorker do context 'when target account is local' do let(:target_account) { Fabricate(:account) } - it 'calls UnfollowFollowWorker', :sidekiq_fake do + it 'calls UnfollowFollowWorker' do subject.perform(source_account.id, target_account.id) expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, true) end diff --git a/spec/workers/poll_expiration_notify_worker_spec.rb b/spec/workers/poll_expiration_notify_worker_spec.rb index ca36a375902..4bd90270d89 100644 --- a/spec/workers/poll_expiration_notify_worker_spec.rb +++ b/spec/workers/poll_expiration_notify_worker_spec.rb @@ -10,7 +10,7 @@ describe PollExpirationNotifyWorker do let(:remote?) { false } let(:poll_vote) { Fabricate(:poll_vote, poll: poll) } - describe '#perform', :sidekiq_fake do + describe '#perform' do it 'runs without error for missing record' do expect { worker.perform(nil) }.to_not raise_error end From 543d7890fd818ed8871b0f8e6adbf19b605edf70 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 08:36:06 -0500 Subject: [PATCH 18/23] Use normalizes to prepare `User` values (#28650) Co-authored-by: Claire --- app/models/user.rb | 22 ++++-------------- spec/models/user_spec.rb | 50 ++++++++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 55f654137a1..0c589f8068a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -118,14 +118,15 @@ class User < ApplicationRecord scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) } scope :matches_ip, ->(value) { left_joins(:ips).where('user_ips.ip <<= ?', value).group('users.id') } - before_validation :sanitize_languages before_validation :sanitize_role - before_validation :sanitize_time_zone - before_validation :sanitize_locale before_create :set_approved after_commit :send_pending_devise_notifications after_create_commit :trigger_webhooks + normalizes :locale, with: ->(locale) { I18n.available_locales.exclude?(locale.to_sym) ? nil : locale } + normalizes :time_zone, with: ->(time_zone) { ActiveSupport::TimeZone[time_zone].nil? ? nil : time_zone } + normalizes :chosen_languages, with: ->(chosen_languages) { chosen_languages.compact_blank.presence } + # This avoids a deprecation warning from Rails 5.1 # It seems possible that a future release of devise-two-factor will # handle this itself, and this can be removed from our User class. @@ -447,25 +448,10 @@ class User < ApplicationRecord @bypass_invite_request_check end - def sanitize_languages - return if chosen_languages.nil? - - chosen_languages.compact_blank! - self.chosen_languages = nil if chosen_languages.empty? - end - def sanitize_role self.role = nil if role.present? && role.everyone? end - def sanitize_time_zone - self.time_zone = nil if time_zone.present? && ActiveSupport::TimeZone[time_zone].nil? - end - - def sanitize_locale - self.locale = nil if locale.present? && I18n.available_locales.exclude?(locale.to_sym) - end - def prepare_new_user! BootstrapTimelineWorker.perform_async(account_id) ActivityTracker.increment('activity:accounts:local') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index c8415df92a0..7f68671df45 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -38,23 +38,49 @@ RSpec.describe User do user.save(validate: false) expect(user.valid?).to be true end + end - it 'cleans out invalid locale' do - user = Fabricate.build(:user, locale: 'toto') - expect(user.valid?).to be true - expect(user.locale).to be_nil + describe 'Normalizations' do + describe 'locale' do + it 'preserves valid locale' do + user = Fabricate.build(:user, locale: 'en') + + expect(user.locale).to eq('en') + end + + it 'cleans out invalid locale' do + user = Fabricate.build(:user, locale: 'toto') + + expect(user.locale).to be_nil + end end - it 'cleans out invalid timezone' do - user = Fabricate.build(:user, time_zone: 'toto') - expect(user.valid?).to be true - expect(user.time_zone).to be_nil + describe 'time_zone' do + it 'preserves valid timezone' do + user = Fabricate.build(:user, time_zone: 'UTC') + + expect(user.time_zone).to eq('UTC') + end + + it 'cleans out invalid timezone' do + user = Fabricate.build(:user, time_zone: 'toto') + + expect(user.time_zone).to be_nil + end end - it 'cleans out empty string from languages' do - user = Fabricate.build(:user, chosen_languages: ['']) - user.valid? - expect(user.chosen_languages).to be_nil + describe 'languages' do + it 'preserves valid options for languages' do + user = Fabricate.build(:user, chosen_languages: ['en', 'fr', '']) + + expect(user.chosen_languages).to eq(['en', 'fr']) + end + + it 'cleans out empty string from languages' do + user = Fabricate.build(:user, chosen_languages: ['']) + + expect(user.chosen_languages).to be_nil + end end end From 8422b8ded0fa0ac1fdb70e6fb494ef5453b845d9 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 09:54:11 -0500 Subject: [PATCH 19/23] Extract capybara config and improve headless_chrome driver config (#28681) --- spec/rails_helper.rb | 2 -- spec/support/capybara.rb | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 spec/support/capybara.rb diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 783258b3af0..aabb121fc3d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -108,8 +108,6 @@ RSpec.configure do |config| end config.around :each, type: :system do |example| - driven_by :selenium, using: :headless_chrome, screen_size: [1600, 1200] - # The streaming server needs access to the database # but with use_transactional_tests every transaction # is rolled-back, so the streaming server never sees the data diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb new file mode 100644 index 00000000000..d4f27e209e1 --- /dev/null +++ b/spec/support/capybara.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +Capybara.server_host = 'localhost' +Capybara.server_port = 3000 +Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}" + +require 'selenium/webdriver' + +Capybara.register_driver :chrome do |app| + Capybara::Selenium::Driver.new(app, browser: :chrome) +end + +Capybara.register_driver :headless_chrome do |app| + options = Selenium::WebDriver::Chrome::Options.new + options.add_argument '--headless=new' + options.add_argument '--window-size=1680,1050' + + Capybara::Selenium::Driver.new( + app, + browser: :chrome, + options: options + ) +end + +Capybara.javascript_driver = :headless_chrome + +RSpec.configure do |config| + config.before(:each, type: :system) do + driven_by Capybara.javascript_driver + end +end From d7e13e248380704895674949bf870ac5e8d8387b Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 10 Jan 2024 16:05:46 +0100 Subject: [PATCH 20/23] Fix potential redirection loop of streaming endpoint (#28665) --- app/controllers/api/v1/streaming_controller.rb | 7 ++++++- spec/controllers/api/v1/streaming_controller_spec.rb | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/streaming_controller.rb b/app/controllers/api/v1/streaming_controller.rb index 0cb6e856f2b..adb14676e12 100644 --- a/app/controllers/api/v1/streaming_controller.rb +++ b/app/controllers/api/v1/streaming_controller.rb @@ -2,7 +2,7 @@ class Api::V1::StreamingController < Api::BaseController def index - if Rails.configuration.x.streaming_api_base_url == request.host + if same_host? not_found else redirect_to streaming_api_url, status: 301, allow_other_host: true @@ -11,6 +11,11 @@ class Api::V1::StreamingController < Api::BaseController private + def same_host? + base_url = Addressable::URI.parse(Rails.configuration.x.streaming_api_base_url) + request.host == base_url.host && request.port == (base_url.port || 80) + end + def streaming_api_url Addressable::URI.parse(request.url).tap do |uri| base_url = Addressable::URI.parse(Rails.configuration.x.streaming_api_base_url) diff --git a/spec/controllers/api/v1/streaming_controller_spec.rb b/spec/controllers/api/v1/streaming_controller_spec.rb index c3e7153ce86..099f68a74eb 100644 --- a/spec/controllers/api/v1/streaming_controller_spec.rb +++ b/spec/controllers/api/v1/streaming_controller_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' describe Api::V1::StreamingController do around do |example| before = Rails.configuration.x.streaming_api_base_url - Rails.configuration.x.streaming_api_base_url = Rails.configuration.x.web_domain + Rails.configuration.x.streaming_api_base_url = "wss://#{Rails.configuration.x.web_domain}" example.run Rails.configuration.x.streaming_api_base_url = before end From 0a7cff53c2577b3e79599e069eeb344f2613ad8d Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 04:30:29 -0500 Subject: [PATCH 21/23] Add coverage for `Account.followable_by` scope (#28689) --- spec/models/account_spec.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 87aa8bc7543..b4fcb805a6a 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -1009,4 +1009,27 @@ RSpec.describe Account do expect(subject.reload.followers_count).to eq 15 end end + + describe '.followable_by' do + context 'with follows and follow requests' do + let!(:account) { Fabricate(:account) } + let!(:eligible_account) { Fabricate(:account) } + let!(:following_account) { Fabricate(:account) } + let!(:follow_requested_account) { Fabricate(:account) } + + before do + Fabricate :follow, account: account, target_account: following_account + Fabricate :follow_request, account: account, target_account: follow_requested_account + end + + it 'returns accounts not already following or requested to follow' do + results = described_class.followable_by(account) + + expect(results) + .to include(eligible_account) + .and not_include(following_account) + .and not_include(follow_requested_account) + end + end + end end From 5dcb8d92c367b5b52a10d2294b03a194ec24475f Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 11 Jan 2024 13:22:39 +0100 Subject: [PATCH 22/23] Fix lint issue in glitch-soc-only setting form --- app/views/settings/preferences/other/show.html.haml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 17a3afc2545..49d03ca00a6 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -45,7 +45,17 @@ wrapper: :with_label .fields-group - = ff.input :default_content_type, collection: ['text/plain', 'text/markdown', 'text/html'], wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_default_content_type'), include_blank: false, label_method: ->(item) { safe_join([t("simple_form.labels.defaults.setting_default_content_type_#{item.split('/')[1]}"), content_tag(:span, t("simple_form.hints.defaults.setting_default_content_type_#{item.split('/')[1]}"), class: 'hint')]) }, required: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', glitch_only: true + = ff.input :default_content_type, + collection: %w(text/plain text/markdown text/html), + wrapper: :with_label, + label: I18n.t('simple_form.labels.defaults.setting_default_content_type'), + include_blank: false, + label_method: ->(item) { safe_join([t("simple_form.labels.defaults.setting_default_content_type_#{item.split('/')[1]}"), content_tag(:span, t("simple_form.hints.defaults.setting_default_content_type_#{item.split('/')[1]}"), class: 'hint')]) }, + required: false, + as: :radio_buttons, + collection_wrapper_tag: 'ul', + item_wrapper_tag: 'li', + glitch_only: true %h4= t 'preferences.public_timelines' From 08304075bed202ce8794fb24bf28121a10363418 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 11 Jan 2024 13:26:17 +0100 Subject: [PATCH 23/23] Fix old glitch-soc migration using removed `add_column_with_default` helper --- ...0180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb b/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb index 8078a07bfcc..563251b215e 100644 --- a/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb +++ b/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb @@ -9,7 +9,7 @@ class AddApplyToMentionsFlagToKeywordMutes < ActiveRecord::Migration[5.2] def up safety_assured do - add_column_with_default :glitch_keyword_mutes, :apply_to_mentions, :boolean, allow_null: false, default: true + add_column :glitch_keyword_mutes, :apply_to_mentions, :boolean, null: false, default: true end end