Fix most rubocop issues (#2165)

* Run rubocop --autocorrect on app/, config/ and lib/, also manually fix some remaining style issues

* Run rubocop --autocorrect-all on db/

* Run rubocop --autocorrect-all on `spec/` and fix remaining issues
This commit is contained in:
Claire 2023-04-09 11:25:30 +02:00 committed by GitHub
parent 29a91b871e
commit ff168ef202
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 211 additions and 216 deletions

View File

@ -473,6 +473,7 @@ RSpec/ContextWording:
- 'spec/lib/activitypub/activity/create_spec.rb' - 'spec/lib/activitypub/activity/create_spec.rb'
- 'spec/lib/activitypub/activity/follow_spec.rb' - 'spec/lib/activitypub/activity/follow_spec.rb'
- 'spec/lib/activitypub/activity/reject_spec.rb' - 'spec/lib/activitypub/activity/reject_spec.rb'
- 'spec/lib/advanced_text_formatter_spec.rb'
- 'spec/lib/emoji_formatter_spec.rb' - 'spec/lib/emoji_formatter_spec.rb'
- 'spec/lib/entity_cache_spec.rb' - 'spec/lib/entity_cache_spec.rb'
- 'spec/lib/feed_manager_spec.rb' - 'spec/lib/feed_manager_spec.rb'
@ -1321,6 +1322,7 @@ Rails/FilePath:
- 'app/models/setting.rb' - 'app/models/setting.rb'
- 'app/validators/reaction_validator.rb' - 'app/validators/reaction_validator.rb'
- 'config/environments/test.rb' - 'config/environments/test.rb'
- 'config/initializers/locale.rb'
- 'db/migrate/20170716191202_add_hide_notifications_to_mute.rb' - 'db/migrate/20170716191202_add_hide_notifications_to_mute.rb'
- 'db/migrate/20171005171936_add_disabled_to_custom_emojis.rb' - 'db/migrate/20171005171936_add_disabled_to_custom_emojis.rb'
- 'db/migrate/20171028221157_add_reblogs_to_follows.rb' - 'db/migrate/20171028221157_add_reblogs_to_follows.rb'

View File

@ -40,7 +40,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
only_media: truthy_param?(:only_media), only_media: truthy_param?(:only_media),
allow_local_only: truthy_param?(:allow_local_only), allow_local_only: truthy_param?(:allow_local_only),
with_replies: Setting.show_replies_in_public_timelines, 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 end

View File

@ -15,12 +15,6 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
skip_before_action :require_functional! skip_before_action :require_functional!
def new
super
resource.email = current_user.unconfirmed_email || current_user.email if user_signed_in?
end
def show def show
old_session_values = session.to_hash old_session_values = session.to_hash
reset_session reset_session
@ -29,6 +23,12 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
super super
end end
def new
super
resource.email = current_user.unconfirmed_email || current_user.email if user_signed_in?
end
def confirm_captcha def confirm_captcha
check_captcha! do |message| check_captcha! do |message|
flash.now[:alert] = message flash.now[:alert] = message
@ -51,6 +51,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
# step. # step.
confirmation_token = params[:confirmation_token] confirmation_token = params[:confirmation_token]
return if confirmation_token.nil? return if confirmation_token.nil?
@confirmation_user = User.find_first_by_auth_conditions(confirmation_token: confirmation_token) @confirmation_user = User.find_first_by_auth_conditions(confirmation_token: confirmation_token)
end end

View File

@ -12,9 +12,7 @@ class Settings::FlavoursController < Settings::BaseController
end end
def show def show
unless Themes.instance.flavours.include?(params[:flavour]) || (params[:flavour] == current_flavour) redirect_to action: 'show', flavour: current_flavour unless Themes.instance.flavours.include?(params[:flavour]) || (params[:flavour] == current_flavour)
redirect_to action: 'show', flavour: current_flavour
end
@listing = Themes.instance.flavours @listing = Themes.instance.flavours
@selected = params[:flavour] @selected = params[:flavour]

View File

@ -28,7 +28,7 @@ module AccountsHelper
end end
def hide_followers_count?(account) 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 end
def account_description(account) def account_description(account)

View File

@ -15,6 +15,7 @@ class AdvancedTextFormatter < TextFormatter
def autolink(link, link_type) def autolink(link, link_type)
return link if link_type == :email return link if link_type == :email
@format_link.call(link) @format_link.call(link)
end end
end end

View File

@ -306,6 +306,7 @@ class FeedManager
statuses.each do |status| statuses.each do |status|
next if filter_from_direct?(status, account) next if filter_from_direct?(status, account)
added += 1 if add_to_feed(:direct, account.id, status) added += 1 if add_to_feed(:direct, account.id, status)
end end
@ -459,6 +460,7 @@ class FeedManager
# @return [Boolean] # @return [Boolean]
def filter_from_direct?(status, receiver_id) def filter_from_direct?(status, receiver_id)
return false if receiver_id == status.account_id return false if receiver_id == status.account_id
filter_from_mentions?(status, receiver_id) filter_from_mentions?(status, receiver_id)
end end

View File

@ -7,24 +7,23 @@ class Themes
include Singleton include Singleton
def initialize def initialize
core = YAML.load_file(Rails.root.join('app', 'javascript', 'core', 'theme.yml')) 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 result = {}
Dir.glob(Rails.root.join('app', 'javascript', 'flavours', '*', 'theme.yml')) do |path| Rails.root.glob('app/javascript/flavours/*/theme.yml') do |pathname|
data = YAML.load_file(path) data = YAML.load_file(pathname)
next unless data['pack'] next unless data['pack']
dir = File.dirname(path) dir = pathname.dirname
name = File.basename(dir) name = dir.basename.to_s
locales = [] locales = []
screenshots = [] screenshots = []
if data['locales'] if data['locales']
Dir.glob(File.join(dir, data['locales'], '*.{js,json}')) do |locale| Dir.glob(File.join(dir, data['locales'], '*.{js,json}')) do |locale|
localeName = File.basename(locale, File.extname(locale)) locale_name = File.basename(locale, File.extname(locale))
locales.push(localeName) unless localeName.match(/defaultMessages|whitelist|index/) locales.push(locale_name) unless /defaultMessages|whitelist|index/.match?(locale_name)
end end
end end
@ -43,34 +42,30 @@ class Themes
result[name] = data result[name] = data
end end
Dir.glob(Rails.root.join('app', 'javascript', 'skins', '*', '*')) do |path| Rails.root.glob('app/javascript/skins/*/*') do |pathname|
ext = File.extname(path) ext = pathname.extname.to_s
skin = File.basename(path) skin = pathname.basename.to_s
name = File.basename(File.dirname(path)) name = pathname.dirname.basename.to_s
next unless result[name] next unless result[name]
if File.directory?(path) if pathname.directory?
pack = [] pack = []
Dir.glob(File.join(path, '*.{css,scss}')) do |sheet| pathname.glob('*.{css,scss}') do |sheet|
pack.push(File.basename(sheet, File.extname(sheet))) pack.push(sheet.basename(sheet.extname).to_s)
end end
elsif ext.match(/^\.s?css$/i) elsif /^\.s?css$/i.match?(ext)
skin = File.basename(path, ext) skin = pathname.basename(ext).to_s
pack = ['common'] pack = ['common']
end end
if skin != 'default' result[name]['skin'][skin] = pack if skin != 'default'
result[name]['skin'][skin] = pack
end
end end
@core = core @core = core
@conf = result @conf = result
end end
def core attr_reader :core
@core
end
def flavour(name) def flavour(name)
@conf[name] @conf[name]
@ -86,7 +81,7 @@ class Themes
def flavours_and_skins def flavours_and_skins
flavours.map do |flavour| flavours.map do |flavour|
[flavour, skins_for(flavour).map{ |skin| [flavour, skin] }] [flavour, skins_for(flavour).map { |skin| [flavour, skin] }]
end end
end end
end end

View File

@ -4,9 +4,8 @@ class DirectFeed < Feed
include Redisable include Redisable
def initialize(account) def initialize(account)
@type = :direct
@id = account.id
@account = account @account = account
super(:direct, account.id)
end end
def get(limit, max_id = nil, since_id = nil, min_id = nil) def get(limit, max_id = nil, since_id = nil, min_id = nil)
@ -19,10 +18,12 @@ class DirectFeed < Feed
private 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 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? return statuses if statuses.empty?
max_id = statuses.last.id max_id = statuses.last.id
statuses = statuses.reject { |status| FeedManager.instance.filter?(:direct, status, @account) } statuses = statuses.reject { |status| FeedManager.instance.filter?(:direct, status, @account) }
return statuses unless statuses.empty? return statuses unless statuses.empty?

View File

@ -338,7 +338,7 @@ class Status < ApplicationRecord
visibilities.keys - %w(direct limited) visibilities.keys - %w(direct limited)
end 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. # direct timeline is mix of direct message from_me and to_me.
# 2 queries are executed with pagination. # 2 queries are executed with pagination.
# constant expression using arel_table is required for partial index # 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) query_to_me = query_to_me.where('mentions.status_id > ?', since_id)
end end
if cache_ids # returns ActiveRecord.Relation
# returns array of cache_ids object that have id and updated_at items = (query_from_me.select(:id).to_a + query_to_me.select(:id).to_a).uniq(&:id).sort_by(&:id).reverse.take(limit)
(query_from_me.cache_ids.to_a + query_to_me.cache_ids.to_a).uniq(&:id).sort_by(&:id).reverse.take(limit) Status.where(id: items.map(&:id))
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
end end
def favourites_map(status_ids, account_id) def favourites_map(status_ids, account_id)
@ -553,9 +548,9 @@ class Status < ApplicationRecord
end end
def set_locality def set_locality
if account.domain.nil? && !attribute_changed?(:local_only) return unless account.domain.nil? && !attribute_changed?(:local_only)
self.local_only = marked_local_only?
end self.local_only = marked_local_only?
end end
def set_conversation def set_conversation

View File

@ -244,7 +244,6 @@ class User < ApplicationRecord
end end
def functional? def functional?
functional_or_moved? functional_or_moved?
end end

View File

@ -32,6 +32,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
def id def id
raise Mastodon::NotPermittedError, 'Local-only statuses should not be serialized' if object.local_only? && !instance_options[:allow_local_only] 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) ActivityPub::TagManager.instance.uri_for(object)
end end

View File

@ -91,7 +91,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
end end
def followers_count 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 end
def display_name def display_name

View File

@ -2,7 +2,7 @@
class REST::MuteSerializer < ActiveModel::Serializer class REST::MuteSerializer < ActiveModel::Serializer
include RoutingHelper include RoutingHelper
attributes :id, :account, :target_account, :created_at, :hide_notifications attributes :id, :account, :target_account, :created_at, :hide_notifications
def account def account
@ -12,4 +12,4 @@ class REST::MuteSerializer < ActiveModel::Serializer
def target_account def target_account
REST::AccountSerializer.new(object.target_account) REST::AccountSerializer.new(object.target_account)
end end
end end

View File

@ -13,7 +13,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
attribute :muted, if: :current_user? attribute :muted, if: :current_user?
attribute :bookmarked, if: :current_user? attribute :bookmarked, if: :current_user?
attribute :pinned, if: :pinnable? attribute :pinned, if: :pinnable?
attribute :local_only if :local? attribute :local_only, if: :local?
has_many :filtered, serializer: REST::FilterResultSerializer, if: :current_user? has_many :filtered, serializer: REST::FilterResultSerializer, if: :current_user?
attribute :content, unless: :source_requested? 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 :preview_card, key: :card, serializer: REST::PreviewCardSerializer
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
delegate :local?, to: :object
def id def id
object.id.to_s object.id.to_s
end end

View File

@ -154,7 +154,7 @@ class BackupService < BaseService
object, object,
serializer: serializer, serializer: serializer,
adapter: ActivityPub::Adapter, adapter: ActivityPub::Adapter,
allow_local_only: true, allow_local_only: true
).as_json ).as_json
end end

View File

@ -116,7 +116,7 @@ class FanOutOnWriteService < BaseService
end end
def deliver_to_direct_timelines! 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? }] [@status.id, account.id, 'direct', { 'update' => update? }]
end end
end end

View File

@ -61,17 +61,22 @@ class PostStatusService < BaseService
private private
def preprocess_attributes! def fill_blank_text!
if @text.blank? && @options[:spoiler_text].present? return unless @text.blank? && @options[:spoiler_text].present?
@text = '.'
if @media&.find(&:video?) || @media&.find(&:gifv?) if @media&.any?(&:video?) || @media&.any?(&:gifv?)
@text = '📹' @text = '📹'
elsif @media&.find(&:audio?) elsif @media&.any?(&:audio?)
@text = '🎵' @text = '🎵'
elsif @media&.find(&:image?) elsif @media&.any?(&:image?)
@text = '🖼' @text = '🖼'
end else
@text = '.'
end end
end
def preprocess_attributes!
fill_blank_text!
@sensitive = (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present? @sensitive = (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?
@visibility = @options[:visibility] || @account.user&.setting_default_privacy @visibility = @options[:visibility] || @account.user&.setting_default_privacy
@visibility = :unlisted if @visibility&.to_sym == :public && @account.silenced? @visibility = :unlisted if @visibility&.to_sym == :public && @account.silenced?

View File

@ -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.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.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.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
end end

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
# Some migrations have been present in glitch-soc for a long time and have then # 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. # 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, # we decided monkey-patching Rails' Migrator to completely ignore the duplicate,
# keeping only the one that has run, or an arbitrary one. # 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 module ActiveRecord
class Migrator class Migrator
def self.new(direction, migrations, schema_migration, target_version = nil) def self.new(direction, migrations, schema_migration, target_version = nil)
migrated = Set.new(Base.connection.migration_context.get_all_versions) migrated = Set.new(Base.connection.migration_context.get_all_versions)
migrations.group_by(&:name).each do |name, duplicates| migrations.group_by(&:name).each do |_name, duplicates|
if duplicates.length > 1 && duplicates.all? { |m| ALLOWED_DUPLICATES.include?(m.version) } 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 # 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 = begin
if duplicates.length == non_migrated.length || non_migrated.empty?
# There weren't any migrated one, so we have to pick one “canonical” migration # There weren't any migrated one, so we have to pick one “canonical” migration
migrations = migrations - duplicates[1..-1] migrations - duplicates[1..]
else else
# Just reject every duplicate which hasn't been migrated yet # Just reject every duplicate which hasn't been migrated yet
migrations = migrations - non_migrated migrations - non_migrated
end end
end end
end end
@ -43,10 +47,10 @@ module ActiveRecord
# A set of duplicated migrations is considered migrated if at least one of # A set of duplicated migrations is considered migrated if at least one of
# them is migrated. # them is migrated.
migrated = get_all_versions 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) } return true unless duplicates.any? { |m| migrated.include?(m.version.to_i) }
end end
return false false
end end
end end
end end

View File

@ -22,6 +22,7 @@ end
module GlitchOnlyComponent module GlitchOnlyComponent
def glitch_only(_wrapper_options = nil) def glitch_only(_wrapper_options = nil)
return unless options[:glitch_only] 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')]) } 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 nil
end end

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CreateKeywordMutes < ActiveRecord::Migration[5.1] class CreateKeywordMutes < ActiveRecord::Migration[5.1]
def change def change
create_table :keyword_mutes do |t| create_table :keyword_mutes do |t|

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
class MoveKeywordMutesIntoGlitchNamespace < ActiveRecord::Migration[5.1] class MoveKeywordMutesIntoGlitchNamespace < ActiveRecord::Migration[5.1]
def change def change
safety_assured do safety_assured do

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AddLocalOnlyFlagToStatuses < ActiveRecord::Migration[5.1] class AddLocalOnlyFlagToStatuses < ActiveRecord::Migration[5.1]
def change def change
add_column :statuses, :local_only, :boolean add_column :statuses, :local_only, :boolean

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
# This migration is a duplicate of 20180831171112 and may get ignored, see # This migration is a duplicate of 20180831171112 and may get ignored, see
# config/initializers/0_duplicate_migrations.rb # config/initializers/0_duplicate_migrations.rb

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'mastodon/migration_helpers' require 'mastodon/migration_helpers'
class AddApplyToMentionsFlagToKeywordMutes < ActiveRecord::Migration[5.2] class AddApplyToMentionsFlagToKeywordMutes < ActiveRecord::Migration[5.2]

View File

@ -1,7 +1,9 @@
# frozen_string_literal: true
class MigrateFilters < ActiveRecord::Migration[5.2] class MigrateFilters < ActiveRecord::Migration[5.2]
class GlitchKeywordMute < ApplicationRecord class GlitchKeywordMute < ApplicationRecord
# Dummy class, as we removed Glitch::KeywordMute # Dummy class, as we removed Glitch::KeywordMute
belongs_to :account, required: true belongs_to :account, optional: false
validates_presence_of :keyword validates_presence_of :keyword
end end
@ -15,7 +17,7 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
private private
def clean_up_contexts def clean_up_contexts
self.context = Array(context).map(&:strip).map(&:presence).compact self.context = Array(context).map(&:strip).filter_map(&:presence)
end end
end end
@ -27,7 +29,8 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
phrase: filter.keyword, phrase: filter.keyword,
context: filter.apply_to_mentions ? %w(home public notifications) : %w(home public), context: filter.apply_to_mentions ? %w(home public notifications) : %w(home public),
whole_word: filter.whole_word, whole_word: filter.whole_word,
irreversible: true) irreversible: true
)
end end
end end
@ -48,7 +51,8 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
GlitchKeywordMute.where(account: filter.account).create!( GlitchKeywordMute.where(account: filter.account).create!(
keyword: filter.phrase, keyword: filter.phrase,
whole_word: filter.whole_word, whole_word: filter.whole_word,
apply_to_mentions: filter.context.include?('notifications')) apply_to_mentions: filter.context.include?('notifications')
)
end end
end end
end end

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AddContentTypeToStatuses < ActiveRecord::Migration[5.2] class AddContentTypeToStatuses < ActiveRecord::Migration[5.2]
def change def change
add_column :statuses, :content_type, :string add_column :statuses, :content_type, :string

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AddContentTypeToStatusEdits < ActiveRecord::Migration[6.1] class AddContentTypeToStatusEdits < ActiveRecord::Migration[6.1]
def change def change
add_column :status_edits, :content_type, :string add_column :status_edits, :content_type, :string

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
class PostMigrateFilters < ActiveRecord::Migration[5.2] class PostMigrateFilters < ActiveRecord::Migration[5.2]
disable_ddl_transaction! disable_ddl_transaction!
@ -5,7 +7,5 @@ class PostMigrateFilters < ActiveRecord::Migration[5.2]
drop_table :glitch_keyword_mutes if table_exists? :glitch_keyword_mutes drop_table :glitch_keyword_mutes if table_exists? :glitch_keyword_mutes
end end
def down def down; end
end
end end

View File

@ -48,9 +48,9 @@ class Sanitize
node.content = "[🖼 #{node['alt']}]" node.content = "[🖼 #{node['alt']}]"
else else
url = node['href'] url = node['href']
prefix = url.match(/\Ahttps?:\/\/(www\.)?/).to_s prefix = url.match(%r{\Ahttps?://(www\.)?}).to_s
text = url[prefix.length, 30] text = url[prefix.length, 30]
text = text + "" if url[prefix.length..-1].length > 30 text += '…' if url.length - prefix.length > 30
node.content = "[🖼 #{text}]" node.content = "[🖼 #{text}]"
end end
end end
@ -88,7 +88,7 @@ class Sanitize
}, },
protocols: { protocols: {
'a' => { 'href' => LINK_PROTOCOLS }, 'a' => { 'href' => LINK_PROTOCOLS },
'blockquote' => { 'cite' => LINK_PROTOCOLS }, 'blockquote' => { 'cite' => LINK_PROTOCOLS },
}, },
@ -126,7 +126,7 @@ class Sanitize
node = env[:node] node = env[:node]
rel = (node['rel'] || '').split(' ') & ['tag'] rel = (node['rel'] || '').split & ['tag']
rel += ['nofollow', 'noopener', 'noreferrer'] unless TagManager.instance.local_url?(node['href']) rel += ['nofollow', 'noopener', 'noreferrer'] unless TagManager.instance.local_url?(node['href'])
if rel.empty? if rel.empty?

View File

@ -3,14 +3,14 @@
namespace :assets do namespace :assets do
desc 'Generate static pages' desc 'Generate static pages'
task generate_static_pages: :environment do task generate_static_pages: :environment do
class StaticApplicationController < ApplicationController
def current_user
nil
end
end
def render_static_page(action, dest:, **opts) def render_static_page(action, dest:, **opts)
html = StaticApplicationController.render(action, opts) renderer = Class.new(ApplicationController) do
def current_user
nil
end
end
html = renderer.render(action, opts)
File.write(dest, html) File.write(dest, html)
end end

View File

@ -1,8 +1,12 @@
# frozen_string_literal: true
namespace :glitchsoc do namespace :glitchsoc do
desc 'Backfill local-only flag on statuses table' desc 'Backfill local-only flag on statuses table'
task backfill_local_only: :environment do task backfill_local_only: :environment do
Status.local.where(local_only: nil).find_each do |st| Status.local.where(local_only: nil).find_each do |status|
ActiveRecord::Base.logger.silence { st.update_attribute(:local_only, st.marked_local_only?) } ActiveRecord::Base.logger.silence do
status.update_attribute(:local_only, status.marked_local_only?) # rubocop:disable Rails/SkipsModelValidations
end
end end
end end
end end

View File

@ -75,10 +75,10 @@ describe Api::V1::Accounts::CredentialsController do
end end
end end
describe 'with invalid data' do describe 'with a too long profile bio' do
before do before do
note = 'This is too long. ' 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 } patch :update, params: { note: note }
end end

View File

@ -2,7 +2,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Api::V1::Timelines::DirectController, type: :controller do RSpec.describe Api::V1::Timelines::DirectController do
let(:user) { Fabricate(:user) } let(:user) { Fabricate(:user) }
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') }

View File

@ -75,8 +75,8 @@ describe ApplicationController, type: :controller do
describe 'helper_method :current_flavour' do describe 'helper_method :current_flavour' do
it 'returns "glitch" when theme wasn\'t changed in admin settings' 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({ 'skin' => 'default' })
allow(Setting).to receive(:default_settings).and_return({'flavour' => 'glitch'}) allow(Setting).to receive(:default_settings).and_return({ 'flavour' => 'glitch' })
expect(controller.view_context.current_flavour).to eq 'glitch' expect(controller.view_context.current_flavour).to eq 'glitch'
end end

View File

@ -1,7 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'rails_helper' require 'rails_helper'
RSpec.describe Settings::FlavoursController, type: :controller do RSpec.describe Settings::FlavoursController do
let(:user) { Fabricate(:user) } let(:user) { Fabricate(:user) }
before do before do

View File

@ -1,12 +1,14 @@
# frozen_string_literal: true
require 'rails_helper' require 'rails_helper'
RSpec.describe AdvancedTextFormatter do RSpec.describe AdvancedTextFormatter do
describe '#to_s' 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(:preloaded_accounts) { nil }
let(:content_type) { 'text/markdown' } 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 context 'given a markdown source' do
let(:content_type) { 'text/markdown' } let(:content_type) { 'text/markdown' }
@ -14,7 +16,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'text' } let(:text) { 'text' }
it 'paragraphizes the text' do it 'paragraphizes the text' do
is_expected.to eq '<p>text</p>' expect(subject).to eq '<p>text</p>'
end end
end end
@ -22,7 +24,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { "line\nfeed" } let(:text) { "line\nfeed" }
it 'removes line feeds' do it 'removes line feeds' do
is_expected.not_to include "\n" expect(subject).to_not include "\n"
end end
end end
@ -30,7 +32,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'test `foo` bar' } let(:text) { 'test `foo` bar' }
it 'formats code using <code>' do 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
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" } 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 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 end
it 'does not strip leading spaces' do it 'does not strip leading spaces' do
is_expected.to include '> return 0' expect(subject).to include '> return 0'
end end
it 'does not format links' do 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
end end
@ -54,7 +56,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'test `https://foo.bar/bar` bar' } let(:text) { 'test `https://foo.bar/bar` bar' }
it 'does not rewrite the link' do 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
end end
@ -62,7 +64,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'foo https://cb6e6126.ngrok.io/about/more' } let(:text) { 'foo https://cb6e6126.ngrok.io/about/more' }
it 'creates a link' do 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
end end
@ -71,7 +73,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { '@alice' } let(:text) { '@alice' }
it 'creates a mention link' do 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
end end
@ -80,7 +82,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { '@alice' } let(:text) { '@alice' }
it 'does not create a mention link' do it 'does not create a mention link' do
is_expected.to include '@alice' expect(subject).to include '@alice'
end end
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' } let(:text) { 'https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4' }
it 'matches the full URL' do 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
end end
@ -96,7 +98,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'http://google.com' } let(:text) { 'http://google.com' }
it 'matches the full URL' do it 'matches the full URL' do
is_expected.to include 'href="http://google.com"' expect(subject).to include 'href="http://google.com"'
end end
end end
@ -104,7 +106,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'http://example.gay' } let(:text) { 'http://example.gay' }
it 'matches the full URL' do it 'matches the full URL' do
is_expected.to include 'href="http://example.gay"' expect(subject).to include 'href="http://example.gay"'
end end
end end
@ -112,11 +114,11 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'https://nic.みんな/' } let(:text) { 'https://nic.みんな/' }
it 'matches the full URL' do it 'matches the full URL' do
is_expected.to include 'href="https://nic.みんな/"' expect(subject).to include 'href="https://nic.みんな/"'
end end
it 'has display URL' do it 'has display URL' do
is_expected.to include '<span class="">nic.みんな/</span>' expect(subject).to include '<span class="">nic.みんな/</span>'
end end
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. ' } 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 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
end end
@ -132,7 +134,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { '(http://google.com/)' } let(:text) { '(http://google.com/)' }
it 'matches the full URL but not the parentheses' do 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
end end
@ -140,7 +142,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'http://www.google.com!' } let(:text) { 'http://www.google.com!' }
it 'matches the full URL but not the exclamation point' do 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
end end
@ -148,7 +150,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { "http://www.google.com'" } let(:text) { "http://www.google.com'" }
it 'matches the full URL but not the single quote' do 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 end
end end
@ -157,7 +159,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'http://www.google.com>' } let(:text) { 'http://www.google.com>' }
it 'matches the full URL but not the angle bracket' do 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
end end
@ -166,7 +168,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' } let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' }
it 'matches the full URL' do 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
end end
@ -174,7 +176,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓&q=autolink' } let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓&q=autolink' }
it 'matches the full URL' do 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
end end
@ -182,7 +184,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓' } let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓' }
it 'matches the full URL' do 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
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' } let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink' }
it 'preserves escaped unicode characters' do 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
end end
@ -198,7 +200,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' } let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' }
it 'matches the full URL' do 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
end end
@ -206,7 +208,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { '"https://example.com/"' } let(:text) { '"https://example.com/"' }
it 'does not match the quotation marks' do 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
end end
@ -214,19 +216,19 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { '<https://example.com/>' } let(:text) { '<https://example.com/>' }
it 'does not match the angle brackets' do 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
end end
context 'given a URL containing unsafe code (XSS attack, invisible part)' do 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 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 end
it 'does not include a script tag' do it 'does not include a script tag' do
is_expected.to_not include '<script>' expect(subject).to_not include '<script>'
end end
end end
@ -234,7 +236,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { '<script>alert("Hello")</script>' } let(:text) { '<script>alert("Hello")</script>' }
it 'does not include a script tag' do it 'does not include a script tag' do
is_expected.to_not include '<script>' expect(subject).to_not include '<script>'
end end
end end
@ -242,7 +244,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { %q{<img src="javascript:alert('XSS');">} } let(:text) { %q{<img src="javascript:alert('XSS');">} }
it 'does not include the javascript' do it 'does not include the javascript' do
is_expected.to_not include 'href="javascript:' expect(subject).to_not include 'href="javascript:'
end end
end end
@ -250,7 +252,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'http://www\.google\.com' } let(:text) { 'http://www\.google\.com' }
it 'outputs the raw URL' do 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
end end
@ -258,7 +260,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { '#hashtag' } let(:text) { '#hashtag' }
it 'creates a hashtag link' do 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
end end
@ -266,7 +268,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { '#hashtagタグ' } let(:text) { '#hashtagタグ' }
it 'creates a hashtag link' do 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
end end
@ -274,7 +276,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'xmpp:user@instance.com' } let(:text) { 'xmpp:user@instance.com' }
it 'matches the full URI' do 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
end end
@ -282,7 +284,7 @@ RSpec.describe AdvancedTextFormatter do
let(:text) { 'please join xmpp:muc@instance.com?join right now' } let(:text) { 'please join xmpp:muc@instance.com?join right now' }
it 'matches the full URI' do 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
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' } let(:text) { 'wikipedia gives this example of a magnet uri: magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a' }
it 'matches the full URI' do 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 end
end end

View File

@ -23,7 +23,7 @@ describe AccountInteractions do
context 'account with Follow but with reblogs disabled' do context 'account with Follow but with reblogs disabled' do
it 'returns { target_account_id => { reblogs: false } }' do it 'returns { target_account_id => { reblogs: false } }' do
Fabricate(:follow, account: account, target_account: target_account, show_reblogs: false) 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
end end
@ -690,41 +690,4 @@ describe AccountInteractions do
end end
end 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 end

View File

@ -64,7 +64,7 @@ RSpec.describe PublicFeed, type: :model do
end end
it 'does not include local-only statuses' do 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 end
@ -80,12 +80,14 @@ RSpec.describe PublicFeed, type: :model do
end end
it 'does not include local-only statuses' do 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 end
end end
context 'without local_only option but allow_local_only' do 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(:viewer) { nil }
let!(:local_account) { Fabricate(:account, domain: 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!(:remote_status) { Fabricate(:status, account: remote_account) }
let!(:local_only_status) { Fabricate(:status, account: local_account, local_only: true) } 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 context 'without a viewer' do
let(:viewer) { nil } let(:viewer) { nil }
@ -108,7 +108,7 @@ RSpec.describe PublicFeed, type: :model do
end end
it 'does not include local-only statuses' do 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 end
@ -147,7 +147,7 @@ RSpec.describe PublicFeed, type: :model do
end end
it 'does not include local-only statuses' do 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 end

View File

@ -206,14 +206,14 @@ RSpec.describe Status, type: :model do
end end
describe 'on create' do describe 'on create' do
subject { Status.new }
let(:local_account) { Fabricate(:account, username: 'local', domain: nil) } let(:local_account) { Fabricate(:account, username: 'local', domain: nil) }
let(:remote_account) { Fabricate(:account, username: 'remote', domain: 'example.com') } 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 describe 'on a status that ends with the local-only emoji' do
before do before do
subject.text = 'A toot ' + subject.local_only_emoji subject.text = "A toot #{subject.local_only_emoji}"
end end
context 'if the status originates from this instance' do context 'if the status originates from this instance' do
@ -291,52 +291,52 @@ RSpec.describe Status, type: :model do
end end
describe '.as_direct_timeline' do describe '.as_direct_timeline' do
subject(:results) { Status.as_direct_timeline(account) }
let(:account) { Fabricate(:account) } let(:account) { Fabricate(:account) }
let(:followed) { Fabricate(:account) } let(:followed) { Fabricate(:account) }
let(:not_followed) { Fabricate(:account) } let(:not_followed) { Fabricate(:account) }
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) }
before do before do
Fabricate(:follow, account: account, target_account: followed) account.follow!(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)
@results = Status.as_direct_timeline(account)
end end
it 'does not include public statuses from self' do 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 end
it 'includes direct statuses from self' do it 'includes direct statuses from self' do
expect(@results).to include(@self_direct_status) expect(results).to include(self_direct_status)
end end
it 'does not include public statuses from followed' do 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 end
it 'does not include direct statuses not mentioning recipient from followed' do 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 end
it 'does not include direct statuses not mentioning recipient from non-followed' do 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 end
it 'includes direct statuses mentioning recipient from followed' do 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) results2 = Status.as_direct_timeline(account)
expect(results2).to include(@followed_direct_status) expect(results2).to include(followed_direct_status)
end end
it 'includes direct statuses mentioning recipient from non-followed' do 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) results2 = Status.as_direct_timeline(account)
expect(results2).to include(@not_followed_direct_status) expect(results2).to include(not_followed_direct_status)
end end
end end

View File

@ -67,7 +67,7 @@ describe TagFeed, type: :service do
expect(results).to include(status) expect(results).to include(status)
end 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) } let!(:status) { Fabricate(:status, tags: [tag1], local_only: true) }
it 'does not show local-only statuses without a viewer' do it 'does not show local-only statuses without a viewer' do

View File

@ -83,14 +83,14 @@ RSpec.describe StatusPolicy, type: :model do
end end
it 'denies access when local-only and the viewer is not logged in' do 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) expect(subject).to_not permit(nil, status)
end end
it 'denies access when local-only and the viewer is from another domain' do it 'denies access when local-only and the viewer is from another domain' do
viewer = Fabricate(:account, domain: 'remote-domain') 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) expect(subject).to_not permit(viewer, status)
end end
end end

View File

@ -48,7 +48,7 @@ RSpec.describe NotifyService, type: :service do
recipient.suspend! recipient.suspend!
expect { subject }.to_not change(Notification, :count) expect { subject }.to_not change(Notification, :count)
end end
context 'for direct messages' do context 'for direct messages' do
let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct)) } let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct)) }
let(:type) { :mention } let(:type) { :mention }

View File

@ -65,7 +65,7 @@ describe StatusLengthValidator do
it 'counts only the front part of remote usernames' do it 'counts only the front part of remote usernames' do
username = '@alice' username = '@alice'
chars = StatusLengthValidator::MAX_CHARS - 1 - username.length 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) status = double(spoiler_text: '', text: text, errors: double(add: nil), local?: true, reblog?: false)
subject.validate(status) subject.validate(status)