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
main
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/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'

View File

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

View File

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

View File

@ -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]

View File

@ -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)

View File

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

View File

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

View File

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

View File

@ -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?

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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?

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

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
# 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) }
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
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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AddLocalOnlyFlagToStatuses < ActiveRecord::Migration[5.1]
def change
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
# config/initializers/0_duplicate_migrations.rb

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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?

View File

@ -3,14 +3,14 @@
namespace :assets do
desc 'Generate static pages'
task generate_static_pages: :environment do
class StaticApplicationController < ApplicationController
def current_user
nil
end
end
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)
end

View File

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

View File

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

View File

@ -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') }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) }
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
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)
@results = Status.as_direct_timeline(account)
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

View File

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

View File

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

View File

@ -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)