about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_todo.yml2
-rw-r--r--app/controllers/api/v1/timelines/public_controller.rb2
-rw-r--r--app/controllers/auth/confirmations_controller.rb13
-rw-r--r--app/controllers/settings/flavours_controller.rb4
-rw-r--r--app/helpers/accounts_helper.rb2
-rw-r--r--app/lib/advanced_text_formatter.rb1
-rw-r--r--app/lib/feed_manager.rb2
-rw-r--r--app/lib/themes.rb45
-rw-r--r--app/models/direct_feed.rb9
-rw-r--r--app/models/status.rb19
-rw-r--r--app/models/user.rb1
-rw-r--r--app/serializers/activitypub/note_serializer.rb1
-rw-r--r--app/serializers/rest/account_serializer.rb2
-rw-r--r--app/serializers/rest/mute_serializer.rb4
-rw-r--r--app/serializers/rest/status_serializer.rb4
-rw-r--r--app/services/backup_service.rb2
-rw-r--r--app/services/fan_out_on_write_service.rb2
-rw-r--r--app/services/post_status_service.rb25
-rw-r--r--app/validators/status_pin_validator.rb2
-rw-r--r--config/initializers/0_duplicate_migrations.rb24
-rw-r--r--config/initializers/simple_form.rb1
-rw-r--r--db/migrate/20171009222537_create_keyword_mutes.rb2
-rw-r--r--db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb2
-rw-r--r--db/migrate/20171210213213_add_local_only_flag_to_statuses.rb2
-rw-r--r--db/migrate/20180410220657_create_bookmarks.rb2
-rw-r--r--db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb2
-rw-r--r--db/migrate/20180707193142_migrate_filters.rb12
-rw-r--r--db/migrate/20190512200918_add_content_type_to_statuses.rb2
-rw-r--r--db/migrate/20220209175231_add_content_type_to_status_edits.rb2
-rw-r--r--db/post_migrate/20180813160548_post_migrate_filters.rb6
-rw-r--r--lib/sanitize_ext/sanitize_config.rb8
-rw-r--r--lib/tasks/assets.rake12
-rw-r--r--lib/tasks/glitchsoc.rake8
-rw-r--r--spec/controllers/api/v1/accounts/credentials_controller_spec.rb4
-rw-r--r--spec/controllers/api/v1/timelines/direct_controller_spec.rb2
-rw-r--r--spec/controllers/application_controller_spec.rb4
-rw-r--r--spec/controllers/settings/flavours_controller_spec.rb3
-rw-r--r--spec/lib/advanced_text_formatter_spec.rb82
-rw-r--r--spec/models/concerns/account_interactions_spec.rb39
-rw-r--r--spec/models/public_feed_spec.rb12
-rw-r--r--spec/models/status_spec.rb42
-rw-r--r--spec/models/tag_feed_spec.rb2
-rw-r--r--spec/policies/status_policy_spec.rb4
-rw-r--r--spec/services/notify_service_spec.rb2
-rw-r--r--spec/validators/status_length_validator_spec.rb2
45 files changed, 210 insertions, 215 deletions
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 2e4801a55..dc7e21dc5 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -473,6 +473,7 @@ RSpec/ContextWording:
     - 'spec/lib/activitypub/activity/create_spec.rb'
     - 'spec/lib/activitypub/activity/follow_spec.rb'
     - 'spec/lib/activitypub/activity/reject_spec.rb'
+    - 'spec/lib/advanced_text_formatter_spec.rb'
     - 'spec/lib/emoji_formatter_spec.rb'
     - 'spec/lib/entity_cache_spec.rb'
     - 'spec/lib/feed_manager_spec.rb'
@@ -1321,6 +1322,7 @@ Rails/FilePath:
     - 'app/models/setting.rb'
     - 'app/validators/reaction_validator.rb'
     - 'config/environments/test.rb'
+    - 'config/initializers/locale.rb'
     - 'db/migrate/20170716191202_add_hide_notifications_to_mute.rb'
     - 'db/migrate/20171005171936_add_disabled_to_custom_emojis.rb'
     - 'db/migrate/20171028221157_add_reblogs_to_follows.rb'
diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb
index 493fe4776..4675af921 100644
--- a/app/controllers/api/v1/timelines/public_controller.rb
+++ b/app/controllers/api/v1/timelines/public_controller.rb
@@ -40,7 +40,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
       only_media: truthy_param?(:only_media),
       allow_local_only: truthy_param?(:allow_local_only),
       with_replies: Setting.show_replies_in_public_timelines,
-      with_reblogs: Setting.show_reblogs_in_public_timelines,
+      with_reblogs: Setting.show_reblogs_in_public_timelines
     )
   end
 
diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb
index 0817a905c..620fb621d 100644
--- a/app/controllers/auth/confirmations_controller.rb
+++ b/app/controllers/auth/confirmations_controller.rb
@@ -15,12 +15,6 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
 
   skip_before_action :require_functional!
 
-  def new
-    super
-
-    resource.email = current_user.unconfirmed_email || current_user.email if user_signed_in?
-  end
-
   def show
     old_session_values = session.to_hash
     reset_session
@@ -29,6 +23,12 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
     super
   end
 
+  def new
+    super
+
+    resource.email = current_user.unconfirmed_email || current_user.email if user_signed_in?
+  end
+
   def confirm_captcha
     check_captcha! do |message|
       flash.now[:alert] = message
@@ -51,6 +51,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
     # step.
     confirmation_token = params[:confirmation_token]
     return if confirmation_token.nil?
+
     @confirmation_user = User.find_first_by_auth_conditions(confirmation_token: confirmation_token)
   end
 
diff --git a/app/controllers/settings/flavours_controller.rb b/app/controllers/settings/flavours_controller.rb
index c1172598b..b179b9429 100644
--- a/app/controllers/settings/flavours_controller.rb
+++ b/app/controllers/settings/flavours_controller.rb
@@ -12,9 +12,7 @@ class Settings::FlavoursController < Settings::BaseController
   end
 
   def show
-    unless Themes.instance.flavours.include?(params[:flavour]) || (params[:flavour] == current_flavour)
-      redirect_to action: 'show', flavour: current_flavour
-    end
+    redirect_to action: 'show', flavour: current_flavour unless Themes.instance.flavours.include?(params[:flavour]) || (params[:flavour] == current_flavour)
 
     @listing = Themes.instance.flavours
     @selected = params[:flavour]
diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb
index 91c3a116b..b8277ee17 100644
--- a/app/helpers/accounts_helper.rb
+++ b/app/helpers/accounts_helper.rb
@@ -28,7 +28,7 @@ module AccountsHelper
   end
 
   def hide_followers_count?(account)
-    Setting.hide_followers_count || account.user&.settings['hide_followers_count']
+    Setting.hide_followers_count || account.user&.settings&.[]('hide_followers_count')
   end
 
   def account_description(account)
diff --git a/app/lib/advanced_text_formatter.rb b/app/lib/advanced_text_formatter.rb
index 21e81d4d1..cdf1e2d9c 100644
--- a/app/lib/advanced_text_formatter.rb
+++ b/app/lib/advanced_text_formatter.rb
@@ -15,6 +15,7 @@ class AdvancedTextFormatter < TextFormatter
 
     def autolink(link, link_type)
       return link if link_type == :email
+
       @format_link.call(link)
     end
   end
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 4ce888fc9..15ff6d15f 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -306,6 +306,7 @@ class FeedManager
 
       statuses.each do |status|
         next if filter_from_direct?(status, account)
+
         added += 1 if add_to_feed(:direct, account.id, status)
       end
 
@@ -459,6 +460,7 @@ class FeedManager
   # @return [Boolean]
   def filter_from_direct?(status, receiver_id)
     return false if receiver_id == status.account_id
+
     filter_from_mentions?(status, receiver_id)
   end
 
diff --git a/app/lib/themes.rb b/app/lib/themes.rb
index 81e016d4a..45ba47780 100644
--- a/app/lib/themes.rb
+++ b/app/lib/themes.rb
@@ -7,24 +7,23 @@ class Themes
   include Singleton
 
   def initialize
-
     core = YAML.load_file(Rails.root.join('app', 'javascript', 'core', 'theme.yml'))
-    core['pack'] = Hash.new unless core['pack']
+    core['pack'] = {} unless core['pack']
 
-    result = Hash.new
-    Dir.glob(Rails.root.join('app', 'javascript', 'flavours', '*', 'theme.yml')) do |path|
-      data = YAML.load_file(path)
+    result = {}
+    Rails.root.glob('app/javascript/flavours/*/theme.yml') do |pathname|
+      data = YAML.load_file(pathname)
       next unless data['pack']
 
-      dir = File.dirname(path)
-      name = File.basename(dir)
+      dir = pathname.dirname
+      name = dir.basename.to_s
       locales = []
       screenshots = []
 
       if data['locales']
         Dir.glob(File.join(dir, data['locales'], '*.{js,json}')) do |locale|
-          localeName = File.basename(locale, File.extname(locale))
-          locales.push(localeName) unless localeName.match(/defaultMessages|whitelist|index/)
+          locale_name = File.basename(locale, File.extname(locale))
+          locales.push(locale_name) unless /defaultMessages|whitelist|index/.match?(locale_name)
         end
       end
 
@@ -43,34 +42,30 @@ class Themes
       result[name] = data
     end
 
-    Dir.glob(Rails.root.join('app', 'javascript', 'skins', '*', '*')) do |path|
-      ext = File.extname(path)
-      skin = File.basename(path)
-      name = File.basename(File.dirname(path))
+    Rails.root.glob('app/javascript/skins/*/*') do |pathname|
+      ext = pathname.extname.to_s
+      skin = pathname.basename.to_s
+      name = pathname.dirname.basename.to_s
       next unless result[name]
 
-      if File.directory?(path)
+      if pathname.directory?
         pack = []
-        Dir.glob(File.join(path, '*.{css,scss}')) do |sheet|
-          pack.push(File.basename(sheet, File.extname(sheet)))
+        pathname.glob('*.{css,scss}') do |sheet|
+          pack.push(sheet.basename(sheet.extname).to_s)
         end
-      elsif ext.match(/^\.s?css$/i)
-        skin = File.basename(path, ext)
+      elsif /^\.s?css$/i.match?(ext)
+        skin = pathname.basename(ext).to_s
         pack = ['common']
       end
 
-      if skin != 'default'
-        result[name]['skin'][skin] = pack
-      end
+      result[name]['skin'][skin] = pack if skin != 'default'
     end
 
     @core = core
     @conf = result
   end
 
-  def core
-    @core
-  end
+  attr_reader :core
 
   def flavour(name)
     @conf[name]
@@ -86,7 +81,7 @@ class Themes
 
   def flavours_and_skins
     flavours.map do |flavour|
-      [flavour, skins_for(flavour).map{ |skin| [flavour, skin] }]
+      [flavour, skins_for(flavour).map { |skin| [flavour, skin] }]
     end
   end
 end
diff --git a/app/models/direct_feed.rb b/app/models/direct_feed.rb
index 1f2448070..689a735b3 100644
--- a/app/models/direct_feed.rb
+++ b/app/models/direct_feed.rb
@@ -4,9 +4,8 @@ class DirectFeed < Feed
   include Redisable
 
   def initialize(account)
-    @type    = :direct
-    @id      = account.id
     @account = account
+    super(:direct, account.id)
   end
 
   def get(limit, max_id = nil, since_id = nil, min_id = nil)
@@ -19,10 +18,12 @@ class DirectFeed < Feed
 
   private
 
-  def from_database(limit, max_id, since_id, min_id)
+  # TODO: _min_id is not actually handled by `as_direct_timeline`
+  def from_database(limit, max_id, since_id, _min_id)
     loop do
-      statuses = Status.as_direct_timeline(@account, limit, max_id, since_id, min_id)
+      statuses = Status.as_direct_timeline(@account, limit, max_id, since_id)
       return statuses if statuses.empty?
+
       max_id = statuses.last.id
       statuses = statuses.reject { |status| FeedManager.instance.filter?(:direct, status, @account) }
       return statuses unless statuses.empty?
diff --git a/app/models/status.rb b/app/models/status.rb
index e01ddb5c5..8a58e5d68 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -338,7 +338,7 @@ class Status < ApplicationRecord
       visibilities.keys - %w(direct limited)
     end
 
-    def as_direct_timeline(account, limit = 20, max_id = nil, since_id = nil, cache_ids = false)
+    def as_direct_timeline(account, limit = 20, max_id = nil, since_id = nil)
       # direct timeline is mix of direct message from_me and to_me.
       # 2 queries are executed with pagination.
       # constant expression using arel_table is required for partial index
@@ -369,14 +369,9 @@ class Status < ApplicationRecord
         query_to_me = query_to_me.where('mentions.status_id > ?', since_id)
       end
 
-      if cache_ids
-        # returns array of cache_ids object that have id and updated_at
-        (query_from_me.cache_ids.to_a + query_to_me.cache_ids.to_a).uniq(&:id).sort_by(&:id).reverse.take(limit)
-      else
-        # returns ActiveRecord.Relation
-        items = (query_from_me.select(:id).to_a + query_to_me.select(:id).to_a).uniq(&:id).sort_by(&:id).reverse.take(limit)
-        Status.where(id: items.map(&:id))
-      end
+      # returns ActiveRecord.Relation
+      items = (query_from_me.select(:id).to_a + query_to_me.select(:id).to_a).uniq(&:id).sort_by(&:id).reverse.take(limit)
+      Status.where(id: items.map(&:id))
     end
 
     def favourites_map(status_ids, account_id)
@@ -553,9 +548,9 @@ class Status < ApplicationRecord
   end
 
   def set_locality
-    if account.domain.nil? && !attribute_changed?(:local_only)
-      self.local_only = marked_local_only?
-    end
+    return unless account.domain.nil? && !attribute_changed?(:local_only)
+
+    self.local_only = marked_local_only?
   end
 
   def set_conversation
diff --git a/app/models/user.rb b/app/models/user.rb
index 3471bb2c1..daf8768e8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -244,7 +244,6 @@ class User < ApplicationRecord
   end
 
   def functional?
-
     functional_or_moved?
   end
 
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index ca067ed9b..52ffaf717 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -32,6 +32,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
 
   def id
     raise Mastodon::NotPermittedError, 'Local-only statuses should not be serialized' if object.local_only? && !instance_options[:allow_local_only]
+
     ActivityPub::TagManager.instance.uri_for(object)
   end
 
diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb
index e6c8fe4b2..d4e7ac974 100644
--- a/app/serializers/rest/account_serializer.rb
+++ b/app/serializers/rest/account_serializer.rb
@@ -91,7 +91,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
   end
 
   def followers_count
-    (Setting.hide_followers_count || object.user&.setting_hide_followers_count) ? -1 : object.followers_count
+    Setting.hide_followers_count || object.user&.setting_hide_followers_count ? -1 : object.followers_count
   end
 
   def display_name
diff --git a/app/serializers/rest/mute_serializer.rb b/app/serializers/rest/mute_serializer.rb
index 043a2f059..c9b55ff16 100644
--- a/app/serializers/rest/mute_serializer.rb
+++ b/app/serializers/rest/mute_serializer.rb
@@ -2,7 +2,7 @@
 
 class REST::MuteSerializer < ActiveModel::Serializer
   include RoutingHelper
-  
+
   attributes :id, :account, :target_account, :created_at, :hide_notifications
 
   def account
@@ -12,4 +12,4 @@ class REST::MuteSerializer < ActiveModel::Serializer
   def target_account
     REST::AccountSerializer.new(object.target_account)
   end
-end
\ No newline at end of file
+end
diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb
index 659c45b83..eb5f3c3ea 100644
--- a/app/serializers/rest/status_serializer.rb
+++ b/app/serializers/rest/status_serializer.rb
@@ -13,7 +13,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
   attribute :muted, if: :current_user?
   attribute :bookmarked, if: :current_user?
   attribute :pinned, if: :pinnable?
-  attribute :local_only if :local?
+  attribute :local_only, if: :local?
   has_many :filtered, serializer: REST::FilterResultSerializer, if: :current_user?
 
   attribute :content, unless: :source_requested?
@@ -32,6 +32,8 @@ class REST::StatusSerializer < ActiveModel::Serializer
   has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
   has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
 
+  delegate :local?, to: :object
+
   def id
     object.id.to_s
   end
diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb
index a9d740211..c5e7a8e58 100644
--- a/app/services/backup_service.rb
+++ b/app/services/backup_service.rb
@@ -154,7 +154,7 @@ class BackupService < BaseService
       object,
       serializer: serializer,
       adapter: ActivityPub::Adapter,
-      allow_local_only: true,
+      allow_local_only: true
     ).as_json
   end
 
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index 8e74e152e..3b14a6748 100644
--- a/app/services/fan_out_on_write_service.rb
+++ b/app/services/fan_out_on_write_service.rb
@@ -116,7 +116,7 @@ class FanOutOnWriteService < BaseService
   end
 
   def deliver_to_direct_timelines!
-    FeedInsertWorker.push_bulk(@status.mentions.includes(:account).map(&:account).select { |mentioned_account| mentioned_account.local? }) do |account|
+    FeedInsertWorker.push_bulk(@status.mentions.includes(:account).map(&:account).select(&:local?)) do |account|
       [@status.id, account.id, 'direct', { 'update' => update? }]
     end
   end
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index bca3b3ff7..74ec47a33 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -61,17 +61,22 @@ class PostStatusService < BaseService
 
   private
 
-  def preprocess_attributes!
-    if @text.blank? && @options[:spoiler_text].present?
-     @text = '.'
-     if @media&.find(&:video?) || @media&.find(&:gifv?)
-       @text = '📹'
-     elsif @media&.find(&:audio?)
-       @text = '🎵'
-     elsif @media&.find(&:image?)
-       @text = '🖼'
-     end
+  def fill_blank_text!
+    return unless @text.blank? && @options[:spoiler_text].present?
+
+    if @media&.any?(&:video?) || @media&.any?(&:gifv?)
+      @text = '📹'
+    elsif @media&.any?(&:audio?)
+      @text = '🎵'
+    elsif @media&.any?(&:image?)
+      @text = '🖼'
+    else
+      @text = '.'
     end
+  end
+
+  def preprocess_attributes!
+    fill_blank_text!
     @sensitive    = (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?
     @visibility   = @options[:visibility] || @account.user&.setting_default_privacy
     @visibility   = :unlisted if @visibility&.to_sym == :public && @account.silenced?
diff --git a/app/validators/status_pin_validator.rb b/app/validators/status_pin_validator.rb
index 9466a81fe..4af7bd295 100644
--- a/app/validators/status_pin_validator.rb
+++ b/app/validators/status_pin_validator.rb
@@ -7,6 +7,6 @@ class StatusPinValidator < ActiveModel::Validator
     pin.errors.add(:base, I18n.t('statuses.pin_errors.reblog')) if pin.status.reblog?
     pin.errors.add(:base, I18n.t('statuses.pin_errors.ownership')) if pin.account_id != pin.status.account_id
     pin.errors.add(:base, I18n.t('statuses.pin_errors.direct')) if pin.status.direct_visibility?
-    pin.errors.add(:base, I18n.t('statuses.pin_errors.limit')) if pin.account.status_pins.count >= MAX_PINNED  && pin.account.local?
+    pin.errors.add(:base, I18n.t('statuses.pin_errors.limit')) if pin.account.status_pins.count >= MAX_PINNED && pin.account.local?
   end
 end
diff --git a/config/initializers/0_duplicate_migrations.rb b/config/initializers/0_duplicate_migrations.rb
index 6c45e4bd2..1b8b59025 100644
--- a/config/initializers/0_duplicate_migrations.rb
+++ b/config/initializers/0_duplicate_migrations.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 # Some migrations have been present in glitch-soc for a long time and have then
 # been merged in upstream Mastodon, under a different version number.
 #
@@ -12,24 +14,26 @@
 # we decided monkey-patching Rails' Migrator to completely ignore the duplicate,
 # keeping only the one that has run, or an arbitrary one.
 
-ALLOWED_DUPLICATES = [20180410220657, 20180831171112].freeze
+ALLOWED_DUPLICATES = [2018_04_10_220657, 2018_08_31_171112].freeze
 
 module ActiveRecord
   class Migrator
     def self.new(direction, migrations, schema_migration, target_version = nil)
       migrated = Set.new(Base.connection.migration_context.get_all_versions)
 
-      migrations.group_by(&:name).each do |name, duplicates|
-        if duplicates.length > 1 && duplicates.all? { |m| ALLOWED_DUPLICATES.include?(m.version) }
-          # We have a set of allowed duplicates. Keep the migrated one, if any.
-          non_migrated = duplicates.reject { |m| migrated.include?(m.version.to_i) }
+      migrations.group_by(&:name).each do |_name, duplicates|
+        next unless duplicates.length > 1 && duplicates.all? { |m| ALLOWED_DUPLICATES.include?(m.version) }
+
+        # We have a set of allowed duplicates. Keep the migrated one, if any.
+        non_migrated = duplicates.reject { |m| migrated.include?(m.version.to_i) }
 
-          if duplicates.length == non_migrated.length || non_migrated.length == 0
+        migrations = begin
+          if duplicates.length == non_migrated.length || non_migrated.empty?
             # There weren't any migrated one, so we have to pick one “canonical” migration
-            migrations = migrations - duplicates[1..-1]
+            migrations - duplicates[1..]
           else
             # Just reject every duplicate which hasn't been migrated yet
-            migrations = migrations - non_migrated
+            migrations - non_migrated
           end
         end
       end
@@ -43,10 +47,10 @@ module ActiveRecord
       # A set of duplicated migrations is considered migrated if at least one of
       # them is migrated.
       migrated = get_all_versions
-      migrations.group_by(&:name).each do |name, duplicates|
+      migrations.group_by(&:name).each do |_name, duplicates|
         return true unless duplicates.any? { |m| migrated.include?(m.version.to_i) }
       end
-      return false
+      false
     end
   end
 end
diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb
index d167a1600..fff4f538e 100644
--- a/config/initializers/simple_form.rb
+++ b/config/initializers/simple_form.rb
@@ -22,6 +22,7 @@ end
 module GlitchOnlyComponent
   def glitch_only(_wrapper_options = nil)
     return unless options[:glitch_only]
+
     options[:label_text] = ->(raw_label_text, _required_label_text, _label_present) { safe_join([raw_label_text, ' ', content_tag(:span, I18n.t('simple_form.glitch_only'), class: 'glitch_only')]) }
     nil
   end
diff --git a/db/migrate/20171009222537_create_keyword_mutes.rb b/db/migrate/20171009222537_create_keyword_mutes.rb
index 66411ba1d..77c88b0a5 100644
--- a/db/migrate/20171009222537_create_keyword_mutes.rb
+++ b/db/migrate/20171009222537_create_keyword_mutes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class CreateKeywordMutes < ActiveRecord::Migration[5.1]
   def change
     create_table :keyword_mutes do |t|
diff --git a/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb b/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb
index 269bb49d6..b6ea537c2 100644
--- a/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb
+++ b/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class MoveKeywordMutesIntoGlitchNamespace < ActiveRecord::Migration[5.1]
   def change
     safety_assured do
diff --git a/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb b/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb
index af1e29d6a..010503b10 100644
--- a/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb
+++ b/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class AddLocalOnlyFlagToStatuses < ActiveRecord::Migration[5.1]
   def change
     add_column :statuses, :local_only, :boolean
diff --git a/db/migrate/20180410220657_create_bookmarks.rb b/db/migrate/20180410220657_create_bookmarks.rb
index bc79022e4..aba21f5ea 100644
--- a/db/migrate/20180410220657_create_bookmarks.rb
+++ b/db/migrate/20180410220657_create_bookmarks.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 # This migration is a duplicate of 20180831171112 and may get ignored, see
 # config/initializers/0_duplicate_migrations.rb
 
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 cd97d0f20..8078a07bf 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
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'mastodon/migration_helpers'
 
 class AddApplyToMentionsFlagToKeywordMutes < ActiveRecord::Migration[5.2]
diff --git a/db/migrate/20180707193142_migrate_filters.rb b/db/migrate/20180707193142_migrate_filters.rb
index 067c53357..8f6b3e1bb 100644
--- a/db/migrate/20180707193142_migrate_filters.rb
+++ b/db/migrate/20180707193142_migrate_filters.rb
@@ -1,7 +1,9 @@
+# frozen_string_literal: true
+
 class MigrateFilters < ActiveRecord::Migration[5.2]
   class GlitchKeywordMute < ApplicationRecord
     # Dummy class, as we removed Glitch::KeywordMute
-    belongs_to :account, required: true
+    belongs_to :account, optional: false
     validates_presence_of :keyword
   end
 
@@ -15,7 +17,7 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
     private
 
     def clean_up_contexts
-      self.context = Array(context).map(&:strip).map(&:presence).compact
+      self.context = Array(context).map(&:strip).filter_map(&:presence)
     end
   end
 
@@ -27,7 +29,8 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
         phrase: filter.keyword,
         context: filter.apply_to_mentions ? %w(home public notifications) : %w(home public),
         whole_word: filter.whole_word,
-        irreversible: true)
+        irreversible: true
+      )
     end
   end
 
@@ -48,7 +51,8 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
       GlitchKeywordMute.where(account: filter.account).create!(
         keyword: filter.phrase,
         whole_word: filter.whole_word,
-        apply_to_mentions: filter.context.include?('notifications'))
+        apply_to_mentions: filter.context.include?('notifications')
+      )
     end
   end
 end
diff --git a/db/migrate/20190512200918_add_content_type_to_statuses.rb b/db/migrate/20190512200918_add_content_type_to_statuses.rb
index efbe2caa7..31c1a4f17 100644
--- a/db/migrate/20190512200918_add_content_type_to_statuses.rb
+++ b/db/migrate/20190512200918_add_content_type_to_statuses.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class AddContentTypeToStatuses < ActiveRecord::Migration[5.2]
   def change
     add_column :statuses, :content_type, :string
diff --git a/db/migrate/20220209175231_add_content_type_to_status_edits.rb b/db/migrate/20220209175231_add_content_type_to_status_edits.rb
index 0e4e52fcb..bb414535d 100644
--- a/db/migrate/20220209175231_add_content_type_to_status_edits.rb
+++ b/db/migrate/20220209175231_add_content_type_to_status_edits.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class AddContentTypeToStatusEdits < ActiveRecord::Migration[6.1]
   def change
     add_column :status_edits, :content_type, :string
diff --git a/db/post_migrate/20180813160548_post_migrate_filters.rb b/db/post_migrate/20180813160548_post_migrate_filters.rb
index 588548c1d..82acf13d5 100644
--- a/db/post_migrate/20180813160548_post_migrate_filters.rb
+++ b/db/post_migrate/20180813160548_post_migrate_filters.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class PostMigrateFilters < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
@@ -5,7 +7,5 @@ class PostMigrateFilters < ActiveRecord::Migration[5.2]
     drop_table :glitch_keyword_mutes if table_exists? :glitch_keyword_mutes
   end
 
-  def down
-  end
+  def down; end
 end
-
diff --git a/lib/sanitize_ext/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb
index dfc586561..4c0e9b858 100644
--- a/lib/sanitize_ext/sanitize_config.rb
+++ b/lib/sanitize_ext/sanitize_config.rb
@@ -48,9 +48,9 @@ class Sanitize
         node.content = "[🖼  #{node['alt']}]"
       else
         url = node['href']
-        prefix = url.match(/\Ahttps?:\/\/(www\.)?/).to_s
+        prefix = url.match(%r{\Ahttps?://(www\.)?}).to_s
         text   = url[prefix.length, 30]
-        text   = text + "…" if url[prefix.length..-1].length > 30
+        text += '…' if url.length - prefix.length > 30
         node.content = "[🖼  #{text}]"
       end
     end
@@ -88,7 +88,7 @@ class Sanitize
       },
 
       protocols: {
-        'a'          => { 'href' => LINK_PROTOCOLS },
+        'a' => { 'href' => LINK_PROTOCOLS },
         'blockquote' => { 'cite' => LINK_PROTOCOLS },
       },
 
@@ -126,7 +126,7 @@ class Sanitize
 
       node = env[:node]
 
-      rel = (node['rel'] || '').split(' ') & ['tag']
+      rel = (node['rel'] || '').split & ['tag']
       rel += ['nofollow', 'noopener', 'noreferrer'] unless TagManager.instance.local_url?(node['href'])
 
       if rel.empty?
diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake
index e1102af33..76e190f70 100644
--- a/lib/tasks/assets.rake
+++ b/lib/tasks/assets.rake
@@ -3,14 +3,14 @@
 namespace :assets do
   desc 'Generate static pages'
   task generate_static_pages: :environment do
-    class StaticApplicationController < ApplicationController
-      def current_user
-        nil
+    def render_static_page(action, dest:, **opts)
+      renderer = Class.new(ApplicationController) do
+        def current_user
+          nil
+        end
       end
-    end
 
-    def render_static_page(action, dest:, **opts)
-      html = StaticApplicationController.render(action, opts)
+      html = renderer.render(action, opts)
       File.write(dest, html)
     end
 
diff --git a/lib/tasks/glitchsoc.rake b/lib/tasks/glitchsoc.rake
index 79e864648..72558fa19 100644
--- a/lib/tasks/glitchsoc.rake
+++ b/lib/tasks/glitchsoc.rake
@@ -1,8 +1,12 @@
+# frozen_string_literal: true
+
 namespace :glitchsoc do
   desc 'Backfill local-only flag on statuses table'
   task backfill_local_only: :environment do
-    Status.local.where(local_only: nil).find_each do |st|
-      ActiveRecord::Base.logger.silence { st.update_attribute(:local_only, st.marked_local_only?) }
+    Status.local.where(local_only: nil).find_each do |status|
+      ActiveRecord::Base.logger.silence do
+        status.update_attribute(:local_only, status.marked_local_only?) # rubocop:disable Rails/SkipsModelValidations
+      end
     end
   end
 end
diff --git a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
index de08dd524..a677aaad0 100644
--- a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
@@ -75,10 +75,10 @@ describe Api::V1::Accounts::CredentialsController do
         end
       end
 
-      describe 'with invalid data' do
+      describe 'with a too long profile bio' do
         before do
           note = 'This is too long. '
-          note = note + 'a' * (Account::MAX_NOTE_LENGTH - note.length + 1)
+          note += 'a' * (Account::MAX_NOTE_LENGTH - note.length + 1)
           patch :update, params: { note: note }
         end
 
diff --git a/spec/controllers/api/v1/timelines/direct_controller_spec.rb b/spec/controllers/api/v1/timelines/direct_controller_spec.rb
index a22c2cbea..def67a0fe 100644
--- a/spec/controllers/api/v1/timelines/direct_controller_spec.rb
+++ b/spec/controllers/api/v1/timelines/direct_controller_spec.rb
@@ -2,7 +2,7 @@
 
 require 'rails_helper'
 
-RSpec.describe Api::V1::Timelines::DirectController, type: :controller do
+RSpec.describe Api::V1::Timelines::DirectController do
   let(:user)  { Fabricate(:user) }
   let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') }
 
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 1aabae0ea..82455d874 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -75,8 +75,8 @@ describe ApplicationController, type: :controller do
 
   describe 'helper_method :current_flavour' do
     it 'returns "glitch" when theme wasn\'t changed in admin settings' do
-      allow(Setting).to receive(:default_settings).and_return({'skin' => 'default'})
-      allow(Setting).to receive(:default_settings).and_return({'flavour' => 'glitch'})
+      allow(Setting).to receive(:default_settings).and_return({ 'skin' => 'default' })
+      allow(Setting).to receive(:default_settings).and_return({ 'flavour' => 'glitch' })
 
       expect(controller.view_context.current_flavour).to eq 'glitch'
     end
diff --git a/spec/controllers/settings/flavours_controller_spec.rb b/spec/controllers/settings/flavours_controller_spec.rb
index f89bde1f9..8c7d4a768 100644
--- a/spec/controllers/settings/flavours_controller_spec.rb
+++ b/spec/controllers/settings/flavours_controller_spec.rb
@@ -1,7 +1,8 @@
 # frozen_string_literal: true
+
 require 'rails_helper'
 
-RSpec.describe Settings::FlavoursController, type: :controller do
+RSpec.describe Settings::FlavoursController do
   let(:user) { Fabricate(:user) }
 
   before do
diff --git a/spec/lib/advanced_text_formatter_spec.rb b/spec/lib/advanced_text_formatter_spec.rb
index c1e469606..8b27b56a1 100644
--- a/spec/lib/advanced_text_formatter_spec.rb
+++ b/spec/lib/advanced_text_formatter_spec.rb
@@ -1,12 +1,14 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 
 RSpec.describe AdvancedTextFormatter do
   describe '#to_s' do
+    subject { described_class.new(text, preloaded_accounts: preloaded_accounts, content_type: content_type).to_s }
+
     let(:preloaded_accounts) { nil }
     let(:content_type) { 'text/markdown' }
 
-    subject { described_class.new(text, preloaded_accounts: preloaded_accounts, content_type: content_type).to_s }
-
     context 'given a markdown source' do
       let(:content_type) { 'text/markdown' }
 
@@ -14,7 +16,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'text' }
 
         it 'paragraphizes the text' do
-          is_expected.to eq '<p>text</p>'
+          expect(subject).to eq '<p>text</p>'
         end
       end
 
@@ -22,7 +24,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { "line\nfeed" }
 
         it 'removes line feeds' do
-          is_expected.not_to include "\n"
+          expect(subject).to_not include "\n"
         end
       end
 
@@ -30,7 +32,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'test `foo` bar' }
 
         it 'formats code using <code>' do
-          is_expected.to include 'test <code>foo</code> bar'
+          expect(subject).to include 'test <code>foo</code> bar'
         end
       end
 
@@ -38,15 +40,15 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { "test\n\n```\nint main(void) {\n  return 0; // https://joinmastodon.org/foo\n}\n```\n" }
 
         it 'formats code using <pre> and <code>' do
-          is_expected.to include '<pre><code>int main'
+          expect(subject).to include '<pre><code>int main'
         end
 
         it 'does not strip leading spaces' do
-          is_expected.to include '>  return 0'
+          expect(subject).to include '>  return 0'
         end
 
         it 'does not format links' do
-          is_expected.to include 'return 0; // https://joinmastodon.org/foo'
+          expect(subject).to include 'return 0; // https://joinmastodon.org/foo'
         end
       end
 
@@ -54,7 +56,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'test `https://foo.bar/bar` bar' }
 
         it 'does not rewrite the link' do
-          is_expected.to include 'test <code>https://foo.bar/bar</code> bar'
+          expect(subject).to include 'test <code>https://foo.bar/bar</code> bar'
         end
       end
 
@@ -62,7 +64,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'foo https://cb6e6126.ngrok.io/about/more' }
 
         it 'creates a link' do
-          is_expected.to include '<a href="https://cb6e6126.ngrok.io/about/more"'
+          expect(subject).to include '<a href="https://cb6e6126.ngrok.io/about/more"'
         end
       end
 
@@ -71,7 +73,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { '@alice' }
 
         it 'creates a mention link' do
-          is_expected.to include '<a href="https://cb6e6126.ngrok.io/@alice" class="u-url mention">@<span>alice</span></a></span>'
+          expect(subject).to include '<a href="https://cb6e6126.ngrok.io/@alice" class="u-url mention">@<span>alice</span></a></span>'
         end
       end
 
@@ -80,7 +82,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { '@alice' }
 
         it 'does not create a mention link' do
-          is_expected.to include '@alice'
+          expect(subject).to include '@alice'
         end
       end
 
@@ -88,7 +90,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4' }
 
         it 'matches the full URL' do
-          is_expected.to include 'href="https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4"'
+          expect(subject).to include 'href="https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4"'
         end
       end
 
@@ -96,7 +98,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'http://google.com' }
 
         it 'matches the full URL' do
-          is_expected.to include 'href="http://google.com"'
+          expect(subject).to include 'href="http://google.com"'
         end
       end
 
@@ -104,7 +106,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'http://example.gay' }
 
         it 'matches the full URL' do
-          is_expected.to include 'href="http://example.gay"'
+          expect(subject).to include 'href="http://example.gay"'
         end
       end
 
@@ -112,11 +114,11 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'https://nic.みんな/' }
 
         it 'matches the full URL' do
-          is_expected.to include 'href="https://nic.みんな/"'
+          expect(subject).to include 'href="https://nic.みんな/"'
         end
 
         it 'has display URL' do
-          is_expected.to include '<span class="">nic.みんな/</span>'
+          expect(subject).to include '<span class="">nic.みんな/</span>'
         end
       end
 
@@ -124,7 +126,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona. ' }
 
         it 'matches the full URL but not the period' do
-          is_expected.to include 'href="http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona"'
+          expect(subject).to include 'href="http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona"'
         end
       end
 
@@ -132,7 +134,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { '(http://google.com/)' }
 
         it 'matches the full URL but not the parentheses' do
-          is_expected.to include 'href="http://google.com/"'
+          expect(subject).to include 'href="http://google.com/"'
         end
       end
 
@@ -140,7 +142,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'http://www.google.com!' }
 
         it 'matches the full URL but not the exclamation point' do
-          is_expected.to include 'href="http://www.google.com"'
+          expect(subject).to include 'href="http://www.google.com"'
         end
       end
 
@@ -148,7 +150,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { "http://www.google.com'" }
 
         it 'matches the full URL but not the single quote' do
-          is_expected.to include 'href="http://www.google.com"'
+          expect(subject).to include 'href="http://www.google.com"'
         end
       end
     end
@@ -157,7 +159,7 @@ RSpec.describe AdvancedTextFormatter do
       let(:text) { 'http://www.google.com>' }
 
       it 'matches the full URL but not the angle bracket' do
-        is_expected.to include 'href="http://www.google.com"'
+        expect(subject).to include 'href="http://www.google.com"'
       end
     end
 
@@ -166,7 +168,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' }
 
         it 'matches the full URL' do
-          is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&amp;q=autolink"'
+          expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&amp;q=autolink"'
         end
       end
 
@@ -174,7 +176,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓&q=autolink' }
 
         it 'matches the full URL' do
-          is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓&amp;q=autolink"'
+          expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=✓&amp;q=autolink"'
         end
       end
 
@@ -182,7 +184,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓' }
 
         it 'matches the full URL' do
-          is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓"'
+          expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=✓"'
         end
       end
 
@@ -190,7 +192,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink' }
 
         it 'preserves escaped unicode characters' do
-          is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&amp;utf81=✓&amp;q=autolink"'
+          expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&amp;utf81=✓&amp;q=autolink"'
         end
       end
 
@@ -198,7 +200,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' }
 
         it 'matches the full URL' do
-          is_expected.to include 'href="https://en.wikipedia.org/wiki/Diaspora_(software)"'
+          expect(subject).to include 'href="https://en.wikipedia.org/wiki/Diaspora_(software)"'
         end
       end
 
@@ -206,7 +208,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { '"https://example.com/"' }
 
         it 'does not match the quotation marks' do
-          is_expected.to include 'href="https://example.com/"'
+          expect(subject).to include 'href="https://example.com/"'
         end
       end
 
@@ -214,19 +216,19 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { '<https://example.com/>' }
 
         it 'does not match the angle brackets' do
-          is_expected.to include 'href="https://example.com/"'
+          expect(subject).to include 'href="https://example.com/"'
         end
       end
 
       context 'given a URL containing unsafe code (XSS attack, invisible part)' do
-        let(:text) { %q{http://example.com/blahblahblahblah/a<script>alert("Hello")</script>} }
+        let(:text) { 'http://example.com/blahblahblahblah/a<script>alert("Hello")</script>' }
 
         it 'does not include the HTML in the URL' do
-          is_expected.to include '"http://example.com/blahblahblahblah/a"'
+          expect(subject).to include '"http://example.com/blahblahblahblah/a"'
         end
 
         it 'does not include a script tag' do
-          is_expected.to_not include '<script>'
+          expect(subject).to_not include '<script>'
         end
       end
 
@@ -234,7 +236,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { '<script>alert("Hello")</script>' }
 
         it 'does not include a script tag' do
-          is_expected.to_not include '<script>'
+          expect(subject).to_not include '<script>'
         end
       end
 
@@ -242,7 +244,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { %q{<img src="javascript:alert('XSS');">} }
 
         it 'does not include the javascript' do
-          is_expected.to_not include 'href="javascript:'
+          expect(subject).to_not include 'href="javascript:'
         end
       end
 
@@ -250,7 +252,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'http://www\.google\.com' }
 
         it 'outputs the raw URL' do
-          is_expected.to eq '<p>http://www\.google\.com</p>'
+          expect(subject).to eq '<p>http://www\.google\.com</p>'
         end
       end
 
@@ -258,7 +260,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text)  { '#hashtag' }
 
         it 'creates a hashtag link' do
-          is_expected.to include '/tags/hashtag" class="mention hashtag" rel="tag">#<span>hashtag</span></a>'
+          expect(subject).to include '/tags/hashtag" class="mention hashtag" rel="tag">#<span>hashtag</span></a>'
         end
       end
 
@@ -266,7 +268,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text)  { '#hashtagタグ' }
 
         it 'creates a hashtag link' do
-          is_expected.to include '/tags/hashtag%E3%82%BF%E3%82%B0" class="mention hashtag" rel="tag">#<span>hashtagタグ</span></a>'
+          expect(subject).to include '/tags/hashtag%E3%82%BF%E3%82%B0" class="mention hashtag" rel="tag">#<span>hashtagタグ</span></a>'
         end
       end
 
@@ -274,7 +276,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'xmpp:user@instance.com' }
 
         it 'matches the full URI' do
-          is_expected.to include 'href="xmpp:user@instance.com"'
+          expect(subject).to include 'href="xmpp:user@instance.com"'
         end
       end
 
@@ -282,7 +284,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'please join xmpp:muc@instance.com?join right now' }
 
         it 'matches the full URI' do
-          is_expected.to include 'href="xmpp:muc@instance.com?join"'
+          expect(subject).to include 'href="xmpp:muc@instance.com?join"'
         end
       end
 
@@ -290,7 +292,7 @@ RSpec.describe AdvancedTextFormatter do
         let(:text) { 'wikipedia gives this example of a magnet uri: magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a' }
 
         it 'matches the full URI' do
-          is_expected.to include 'href="magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a"'
+          expect(subject).to include 'href="magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a"'
         end
       end
     end
diff --git a/spec/models/concerns/account_interactions_spec.rb b/spec/models/concerns/account_interactions_spec.rb
index 863b025af..32e08d5f7 100644
--- a/spec/models/concerns/account_interactions_spec.rb
+++ b/spec/models/concerns/account_interactions_spec.rb
@@ -23,7 +23,7 @@ describe AccountInteractions do
     context 'account with Follow but with reblogs disabled' do
       it 'returns { target_account_id => { reblogs: false } }' do
         Fabricate(:follow, account: account, target_account: target_account, show_reblogs: false)
-        is_expected.to eq(target_account_id => { reblogs: false, notify: false, languages: nil })
+        expect(subject).to eq(target_account_id => { reblogs: false, notify: false, languages: nil })
       end
     end
 
@@ -690,41 +690,4 @@ describe AccountInteractions do
       end
     end
   end
-
-  describe 'ignoring reblogs from an account' do
-    before do
-      @me = Fabricate(:account, username: 'Me')
-      @you = Fabricate(:account, username: 'You')
-    end
-
-    context 'with the reblogs option unspecified' do
-      before do
-        @me.follow!(@you)
-      end
-
-      it 'defaults to showing reblogs' do
-        expect(@me.muting_reblogs?(@you)).to be(false)
-      end
-    end
-
-    context 'with the reblogs option set to false' do
-      before do
-        @me.follow!(@you, reblogs: false)
-      end
-
-      it 'does mute reblogs' do
-        expect(@me.muting_reblogs?(@you)).to be(true)
-      end
-    end
-
-    context 'with the reblogs option set to true' do
-      before do
-        @me.follow!(@you, reblogs: true)
-      end
-
-      it 'does not mute reblogs' do
-        expect(@me.muting_reblogs?(@you)).to be(false)
-      end
-    end
-  end
 end
diff --git a/spec/models/public_feed_spec.rb b/spec/models/public_feed_spec.rb
index f607f10ec..d31aba084 100644
--- a/spec/models/public_feed_spec.rb
+++ b/spec/models/public_feed_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe PublicFeed, type: :model do
         end
 
         it 'does not include local-only statuses' do
-          expect(subject).not_to include(local_only_status.id)
+          expect(subject).to_not include(local_only_status.id)
         end
       end
 
@@ -80,12 +80,14 @@ RSpec.describe PublicFeed, type: :model do
         end
 
         it 'does not include local-only statuses' do
-          expect(subject).not_to include(local_only_status.id)
+          expect(subject).to_not include(local_only_status.id)
         end
       end
     end
 
     context 'without local_only option but allow_local_only' do
+      subject { described_class.new(viewer, allow_local_only: true).get(20).map(&:id) }
+
       let(:viewer) { nil }
 
       let!(:local_account)  { Fabricate(:account, domain: nil) }
@@ -94,8 +96,6 @@ RSpec.describe PublicFeed, type: :model do
       let!(:remote_status)  { Fabricate(:status, account: remote_account) }
       let!(:local_only_status) { Fabricate(:status, account: local_account, local_only: true) }
 
-      subject { described_class.new(viewer, allow_local_only: true).get(20).map(&:id) }
-
       context 'without a viewer' do
         let(:viewer) { nil }
 
@@ -108,7 +108,7 @@ RSpec.describe PublicFeed, type: :model do
         end
 
         it 'does not include local-only statuses' do
-          expect(subject).not_to include(local_only_status.id)
+          expect(subject).to_not include(local_only_status.id)
         end
       end
 
@@ -147,7 +147,7 @@ RSpec.describe PublicFeed, type: :model do
         end
 
         it 'does not include local-only statuses' do
-          expect(subject).not_to include(local_only_status.id)
+          expect(subject).to_not include(local_only_status.id)
         end
       end
 
diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb
index 7022c5f00..04e5c26af 100644
--- a/spec/models/status_spec.rb
+++ b/spec/models/status_spec.rb
@@ -206,14 +206,14 @@ RSpec.describe Status, type: :model do
   end
 
   describe 'on create' do
+    subject { Status.new }
+
     let(:local_account) { Fabricate(:account, username: 'local', domain: nil) }
     let(:remote_account) { Fabricate(:account, username: 'remote', domain: 'example.com') }
 
-    subject { Status.new }
-
     describe 'on a status that ends with the local-only emoji' do
       before do
-        subject.text = 'A toot ' + subject.local_only_emoji
+        subject.text = "A toot #{subject.local_only_emoji}"
       end
 
       context 'if the status originates from this instance' do
@@ -291,52 +291,52 @@ RSpec.describe Status, type: :model do
   end
 
   describe '.as_direct_timeline' do
+    subject(:results) { Status.as_direct_timeline(account) }
+
     let(:account) { Fabricate(:account) }
     let(:followed) { Fabricate(:account) }
     let(:not_followed) { Fabricate(:account) }
 
-    before do
-      Fabricate(:follow, account: account, target_account: followed)
-
-      @self_public_status = Fabricate(:status, account: account, visibility: :public)
-      @self_direct_status = Fabricate(:status, account: account, visibility: :direct)
-      @followed_public_status = Fabricate(:status, account: followed, visibility: :public)
-      @followed_direct_status = Fabricate(:status, account: followed, visibility: :direct)
-      @not_followed_direct_status = Fabricate(:status, account: not_followed, visibility: :direct)
+    let!(:self_public_status) { Fabricate(:status, account: account, visibility: :public) }
+    let!(:self_direct_status) { Fabricate(:status, account: account, visibility: :direct) }
+    let!(:followed_public_status) { Fabricate(:status, account: followed, visibility: :public) }
+    let!(:followed_direct_status) { Fabricate(:status, account: followed, visibility: :direct) }
+    let!(:not_followed_direct_status) { Fabricate(:status, account: not_followed, visibility: :direct) }
 
-      @results = Status.as_direct_timeline(account)
+    before do
+      account.follow!(followed)
     end
 
     it 'does not include public statuses from self' do
-      expect(@results).to_not include(@self_public_status)
+      expect(results).to_not include(self_public_status)
     end
 
     it 'includes direct statuses from self' do
-      expect(@results).to include(@self_direct_status)
+      expect(results).to include(self_direct_status)
     end
 
     it 'does not include public statuses from followed' do
-      expect(@results).to_not include(@followed_public_status)
+      expect(results).to_not include(followed_public_status)
     end
 
     it 'does not include direct statuses not mentioning recipient from followed' do
-      expect(@results).to_not include(@followed_direct_status)
+      expect(results).to_not include(followed_direct_status)
     end
 
     it 'does not include direct statuses not mentioning recipient from non-followed' do
-      expect(@results).to_not include(@not_followed_direct_status)
+      expect(results).to_not include(not_followed_direct_status)
     end
 
     it 'includes direct statuses mentioning recipient from followed' do
-      Fabricate(:mention, account: account, status: @followed_direct_status)
+      Fabricate(:mention, account: account, status: followed_direct_status)
       results2 = Status.as_direct_timeline(account)
-      expect(results2).to include(@followed_direct_status)
+      expect(results2).to include(followed_direct_status)
     end
 
     it 'includes direct statuses mentioning recipient from non-followed' do
-      Fabricate(:mention, account: account, status: @not_followed_direct_status)
+      Fabricate(:mention, account: account, status: not_followed_direct_status)
       results2 = Status.as_direct_timeline(account)
-      expect(results2).to include(@not_followed_direct_status)
+      expect(results2).to include(not_followed_direct_status)
     end
   end
 
diff --git a/spec/models/tag_feed_spec.rb b/spec/models/tag_feed_spec.rb
index b961481c8..d8683b86f 100644
--- a/spec/models/tag_feed_spec.rb
+++ b/spec/models/tag_feed_spec.rb
@@ -67,7 +67,7 @@ describe TagFeed, type: :service do
       expect(results).to include(status)
     end
 
-    context 'on a local-only status' do
+    context 'when the feed contains a local-only status' do
       let!(:status) { Fabricate(:status, tags: [tag1], local_only: true) }
 
       it 'does not show local-only statuses without a viewer' do
diff --git a/spec/policies/status_policy_spec.rb b/spec/policies/status_policy_spec.rb
index 9a30aef3c..38b9c4fdb 100644
--- a/spec/policies/status_policy_spec.rb
+++ b/spec/policies/status_policy_spec.rb
@@ -83,14 +83,14 @@ RSpec.describe StatusPolicy, type: :model do
     end
 
     it 'denies access when local-only and the viewer is not logged in' do
-      allow(status).to receive(:local_only?) { true }
+      allow(status).to receive(:local_only?).and_return(true)
 
       expect(subject).to_not permit(nil, status)
     end
 
     it 'denies access when local-only and the viewer is from another domain' do
       viewer = Fabricate(:account, domain: 'remote-domain')
-      allow(status).to receive(:local_only?) { true }
+      allow(status).to receive(:local_only?).and_return(true)
       expect(subject).to_not permit(viewer, status)
     end
   end
diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb
index 4d66f255c..616a7aa20 100644
--- a/spec/services/notify_service_spec.rb
+++ b/spec/services/notify_service_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe NotifyService, type: :service do
     recipient.suspend!
     expect { subject }.to_not change(Notification, :count)
   end
-  
+
   context 'for direct messages' do
     let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct)) }
     let(:type)     { :mention }
diff --git a/spec/validators/status_length_validator_spec.rb b/spec/validators/status_length_validator_spec.rb
index 2cd369335..7e06b9bd9 100644
--- a/spec/validators/status_length_validator_spec.rb
+++ b/spec/validators/status_length_validator_spec.rb
@@ -65,7 +65,7 @@ describe StatusLengthValidator do
     it 'counts only the front part of remote usernames' do
       username = '@alice'
       chars = StatusLengthValidator::MAX_CHARS - 1 - username.length
-      text   = ('a' * 475) + " #{username}@#{'b' * 30}.com"
+      text   = ('a' * chars) + " #{username}@#{'b' * 30}.com"
       status = double(spoiler_text: '', text: text, errors: double(add: nil), local?: true, reblog?: false)
 
       subject.validate(status)