From e8bc187845b78e4a94894c69ecf930a524ad2056 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 Sep 2020 11:02:04 +0200 Subject: [PATCH 01/27] Refactor how public and tag timelines are queried (#14728) --- .../api/v1/timelines/public_controller.rb | 29 ++- .../api/v1/timelines/tag_controller.rb | 34 +-- app/controllers/tags_controller.rb | 31 +-- app/models/public_feed.rb | 90 +++++++ app/models/status.rb | 67 +---- app/models/tag_feed.rb | 57 +++++ app/services/hashtag_query_service.rb | 22 -- spec/models/public_feed_spec.rb | 212 ++++++++++++++++ spec/models/status_spec.rb | 235 ------------------ .../tag_feed_spec.rb} | 26 +- .../services/fan_out_on_write_service_spec.rb | 4 +- 11 files changed, 429 insertions(+), 378 deletions(-) create mode 100644 app/models/public_feed.rb create mode 100644 app/models/tag_feed.rb delete mode 100644 app/services/hashtag_query_service.rb create mode 100644 spec/models/public_feed_spec.rb rename spec/{services/hashtag_query_service_spec.rb => models/tag_feed_spec.rb} (65%) diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb index 26d877b00..d253b744f 100644 --- a/app/controllers/api/v1/timelines/public_controller.rb +++ b/app/controllers/api/v1/timelines/public_controller.rb @@ -20,26 +20,25 @@ class Api::V1::Timelines::PublicController < Api::BaseController end def cached_public_statuses_page - cache_collection_paginated_by_id( - public_statuses, - Status, - limit_param(DEFAULT_STATUSES_LIMIT), - params_slice(:max_id, :since_id, :min_id) - ) + cache_collection(public_statuses, Status) end def public_statuses - statuses = public_timeline_statuses - - if truthy_param?(:only_media) - statuses.joins(:media_attachments).group(:id) - else - statuses - end + public_feed.get( + limit_param(DEFAULT_STATUSES_LIMIT), + params[:max_id], + params[:since_id], + params[:min_id] + ) end - def public_timeline_statuses - Status.as_public_timeline(current_account, truthy_param?(:remote) ? :remote : truthy_param?(:local)) + def public_feed + PublicFeed.new( + current_account, + local: truthy_param?(:local), + remote: truthy_param?(:remote), + only_media: truthy_param?(:only_media) + ) end def insert_pagination_headers diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb index 76f7d3590..64a1db58d 100644 --- a/app/controllers/api/v1/timelines/tag_controller.rb +++ b/app/controllers/api/v1/timelines/tag_controller.rb @@ -20,23 +20,29 @@ class Api::V1::Timelines::TagController < Api::BaseController end def cached_tagged_statuses - if @tag.nil? - [] - else - statuses = tag_timeline_statuses - statuses = statuses.joins(:media_attachments) if truthy_param?(:only_media) - - cache_collection_paginated_by_id( - statuses, - Status, - limit_param(DEFAULT_STATUSES_LIMIT), - params_slice(:max_id, :since_id, :min_id) - ) - end + @tag.nil? ? [] : cache_collection(tag_timeline_statuses, Status) end def tag_timeline_statuses - HashtagQueryService.new.call(@tag, params.slice(:any, :all, :none), current_account, truthy_param?(:local)) + tag_feed.get( + limit_param(DEFAULT_STATUSES_LIMIT), + params[:max_id], + params[:since_id], + params[:min_id] + ) + end + + def tag_feed + TagFeed.new( + @tag, + current_account, + any: params[:any], + all: params[:all], + none: params[:none], + local: truthy_param?(:local), + remote: truthy_param?(:remote), + only_media: truthy_param?(:only_media) + ) end def insert_pagination_headers diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 6426a7d69..6616ba107 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -10,8 +10,9 @@ class TagsController < ApplicationController before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? } before_action :authenticate_user!, if: :whitelist_mode? - before_action :set_tag before_action :set_local + before_action :set_tag + before_action :set_statuses before_action :set_body_classes before_action :set_instance_presenter @@ -25,20 +26,11 @@ class TagsController < ApplicationController format.rss do expires_in 0, public: true - - limit = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE - @statuses = HashtagQueryService.new.call(@tag, filter_params, nil, @local).limit(limit) - @statuses = cache_collection(@statuses, Status) - render xml: RSS::TagSerializer.render(@tag, @statuses) end format.json do expires_in 3.minutes, public: public_fetch_mode? - - @statuses = HashtagQueryService.new.call(@tag, filter_params, current_account, @local).paginate_by_max_id(PAGE_SIZE, params[:max_id]) - @statuses = cache_collection(@statuses, Status) - render json: collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json' end end @@ -54,6 +46,15 @@ class TagsController < ApplicationController @local = truthy_param?(:local) end + def set_statuses + case request.format&.to_sym + when :json + @statuses = cache_collection(TagFeed.new(@tag, current_account, local: @local).get(PAGE_SIZE, params[:max_id], params[:since_id], params[:min_id]), Status) + when :rss + @statuses = cache_collection(TagFeed.new(@tag, nil, local: @local).get(limit_param), Status) + end + end + def set_body_classes @body_classes = 'with-modals' end @@ -62,16 +63,16 @@ class TagsController < ApplicationController @instance_presenter = InstancePresenter.new end + def limit_param + params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE + end + def collection_presenter ActivityPub::CollectionPresenter.new( - id: tag_url(@tag, filter_params), + id: tag_url(@tag), type: :ordered, size: @tag.statuses.count, items: @statuses.map { |s| ActivityPub::TagManager.instance.uri_for(s) } ) end - - def filter_params - params.slice(:any, :all, :none).permit(:any, :all, :none) - end end diff --git a/app/models/public_feed.rb b/app/models/public_feed.rb new file mode 100644 index 000000000..c8ce1a140 --- /dev/null +++ b/app/models/public_feed.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +class PublicFeed < Feed + # @param [Account] account + # @param [Hash] options + # @option [Boolean] :with_replies + # @option [Boolean] :with_reblogs + # @option [Boolean] :local + # @option [Boolean] :remote + # @option [Boolean] :only_media + def initialize(account, options = {}) + @account = account + @options = options + end + + # @param [Integer] limit + # @param [Integer] max_id + # @param [Integer] since_id + # @param [Integer] min_id + # @return [Array] + def get(limit, max_id = nil, since_id = nil, min_id = nil) + scope = public_scope + + scope.merge!(without_replies_scope) unless with_replies? + scope.merge!(without_reblogs_scope) unless with_reblogs? + scope.merge!(local_only_scope) if local_only? + scope.merge!(remote_only_scope) if remote_only? + scope.merge!(account_filters_scope) if account? + scope.merge!(media_only_scope) if media_only? + + scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) + end + + private + + def with_reblogs? + @options[:with_reblogs] + end + + def with_replies? + @options[:with_replies] + end + + def local_only? + @options[:local] + end + + def remote_only? + @options[:remote] + end + + def account? + @account.present? + end + + def media_only? + @options[:only_media] + end + + def public_scope + Status.with_public_visibility.joins(:account).merge(Account.without_suspended.without_silenced) + end + + def local_only_scope + Status.local + end + + def remote_only_scope + Status.remote + end + + def without_replies_scope + Status.without_replies + end + + def without_reblogs_scope + Status.without_reblogs + end + + def media_only_scope + Status.joins(:media_attachments).group(:id) + end + + def account_filters_scope + Status.not_excluded_by_account(@account).tap do |scope| + scope.merge!(Status.not_domain_blocked_by_account(@account)) unless local_only? + scope.merge!(Status.in_chosen_languages(@account)) if @account.chosen_languages.present? + end + end +end diff --git a/app/models/status.rb b/app/models/status.rb index 71596ec2f..c6e16ff75 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -85,12 +85,12 @@ class Status < ApplicationRecord scope :recent, -> { reorder(id: :desc) } scope :remote, -> { where(local: false).where.not(uri: nil) } scope :local, -> { where(local: true).or(where(uri: nil)) } - scope :with_accounts, ->(ids) { where(id: ids).includes(:account) } scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') } scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') } scope :with_public_visibility, -> { where(visibility: :public) } scope :tagged_with, ->(tag) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag }) } + scope :in_chosen_languages, ->(account) { where(language: nil).or where(language: account.chosen_languages) } scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) } scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) } scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) } @@ -277,26 +277,6 @@ class Status < ApplicationRecord visibilities.keys - %w(direct limited) end - def in_chosen_languages(account) - where(language: nil).or where(language: account.chosen_languages) - end - - def as_public_timeline(account = nil, local_only = false) - query = timeline_scope(local_only).without_replies - - apply_timeline_filters(query, account, [:local, true].include?(local_only)) - end - - def as_tag_timeline(tag, account = nil, local_only = false) - query = timeline_scope(local_only).tagged_with(tag) - - apply_timeline_filters(query, account, local_only) - end - - def as_outbox_timeline(account) - where(account: account, visibility: :public) - end - def favourites_map(status_ids, account_id) Favourite.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |f, h| h[f.status_id] = true } end @@ -373,51 +353,6 @@ class Status < ApplicationRecord status&.distributable? ? status : nil end.compact end - - private - - def timeline_scope(scope = false) - starting_scope = case scope - when :local, true - Status.local - when :remote - Status.remote - else - Status - end - - starting_scope - .with_public_visibility - .without_reblogs - end - - def apply_timeline_filters(query, account, local_only) - if account.nil? - filter_timeline_default(query) - else - filter_timeline_for_account(query, account, local_only) - end - end - - def filter_timeline_for_account(query, account, local_only) - query = query.not_excluded_by_account(account) - query = query.not_domain_blocked_by_account(account) unless local_only - query = query.in_chosen_languages(account) if account.chosen_languages.present? - query.merge(account_silencing_filter(account)) - end - - def filter_timeline_default(query) - query.excluding_silenced_accounts - end - - def account_silencing_filter(account) - if account.silenced? - including_myself = left_outer_joins(:account).where(account_id: account.id).references(:accounts) - excluding_silenced_accounts.or(including_myself) - else - excluding_silenced_accounts - end - end end def status_stat diff --git a/app/models/tag_feed.rb b/app/models/tag_feed.rb new file mode 100644 index 000000000..50634fe83 --- /dev/null +++ b/app/models/tag_feed.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +class TagFeed < PublicFeed + LIMIT_PER_MODE = 4 + + # @param [Tag] tag + # @param [Account] account + # @param [Hash] options + # @option [Enumerable] :any + # @option [Enumerable] :all + # @option [Enumerable] :none + # @option [Boolean] :local + # @option [Boolean] :remote + # @option [Boolean] :only_media + def initialize(tag, account, options = {}) + @tag = tag + @account = account + @options = options + end + + # @param [Integer] limit + # @param [Integer] max_id + # @param [Integer] since_id + # @param [Integer] min_id + # @return [Array] + def get(limit, max_id = nil, since_id = nil, min_id = nil) + scope = public_scope + + scope.merge!(tagged_with_any_scope) + scope.merge!(tagged_with_all_scope) + scope.merge!(tagged_with_none_scope) + scope.merge!(local_only_scope) if local_only? + scope.merge!(remote_only_scope) if remote_only? + scope.merge!(account_filters_scope) if account? + scope.merge!(media_only_scope) if media_only? + + scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) + end + + private + + def tagged_with_any_scope + Status.group(:id).tagged_with(tags_for(Array(@tag.name) | Array(@options[:any]))) + end + + def tagged_with_all_scope + Status.group(:id).tagged_with_all(tags_for(@options[:all])) + end + + def tagged_with_none_scope + Status.group(:id).tagged_with_none(tags_for(@options[:none])) + end + + def tags_for(names) + Tag.matching_name(Array(names).take(LIMIT_PER_MODE)) if names.present? + end +end diff --git a/app/services/hashtag_query_service.rb b/app/services/hashtag_query_service.rb deleted file mode 100644 index 0bdf60221..000000000 --- a/app/services/hashtag_query_service.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -class HashtagQueryService < BaseService - LIMIT_PER_MODE = 4 - - def call(tag, params, account = nil, local = false) - tags = tags_for(Array(tag.name) | Array(params[:any])).pluck(:id) - all = tags_for(params[:all]) - none = tags_for(params[:none]) - - Status.group(:id) - .as_tag_timeline(tags, account, local) - .tagged_with_all(all) - .tagged_with_none(none) - end - - private - - def tags_for(names) - Tag.matching_name(Array(names).take(LIMIT_PER_MODE)) if names.present? - end -end diff --git a/spec/models/public_feed_spec.rb b/spec/models/public_feed_spec.rb new file mode 100644 index 000000000..0392a582c --- /dev/null +++ b/spec/models/public_feed_spec.rb @@ -0,0 +1,212 @@ +require 'rails_helper' + +RSpec.describe PublicFeed, type: :model do + let(:account) { Fabricate(:account) } + + describe '#get' do + subject { described_class.new(nil).get(20).map(&:id) } + + it 'only includes statuses with public visibility' do + public_status = Fabricate(:status, visibility: :public) + private_status = Fabricate(:status, visibility: :private) + + expect(subject).to include(public_status.id) + expect(subject).not_to include(private_status.id) + end + + it 'does not include replies' do + status = Fabricate(:status) + reply = Fabricate(:status, in_reply_to_id: status.id) + + expect(subject).to include(status.id) + expect(subject).not_to include(reply.id) + end + + it 'does not include boosts' do + status = Fabricate(:status) + boost = Fabricate(:status, reblog_of_id: status.id) + + expect(subject).to include(status.id) + expect(subject).not_to include(boost.id) + end + + it 'filters out silenced accounts' do + account = Fabricate(:account) + silenced_account = Fabricate(:account, silenced: true) + status = Fabricate(:status, account: account) + silenced_status = Fabricate(:status, account: silenced_account) + + expect(subject).to include(status.id) + expect(subject).not_to include(silenced_status.id) + end + + context 'without local_only option' do + let(:viewer) { nil } + + let!(:local_account) { Fabricate(:account, domain: nil) } + let!(:remote_account) { Fabricate(:account, domain: 'test.com') } + let!(:local_status) { Fabricate(:status, account: local_account) } + let!(:remote_status) { Fabricate(:status, account: remote_account) } + + subject { described_class.new(viewer).get(20).map(&:id) } + + context 'without a viewer' do + let(:viewer) { nil } + + it 'includes remote instances statuses' do + expect(subject).to include(remote_status.id) + end + + it 'includes local statuses' do + expect(subject).to include(local_status.id) + end + end + + context 'with a viewer' do + let(:viewer) { Fabricate(:account, username: 'viewer') } + + it 'includes remote instances statuses' do + expect(subject).to include(remote_status.id) + end + + it 'includes local statuses' do + expect(subject).to include(local_status.id) + end + end + end + + context 'with a local_only option set' do + let!(:local_account) { Fabricate(:account, domain: nil) } + let!(:remote_account) { Fabricate(:account, domain: 'test.com') } + let!(:local_status) { Fabricate(:status, account: local_account) } + let!(:remote_status) { Fabricate(:status, account: remote_account) } + + subject { described_class.new(viewer, local: true).get(20).map(&:id) } + + context 'without a viewer' do + let(:viewer) { nil } + + it 'does not include remote instances statuses' do + expect(subject).to include(local_status.id) + expect(subject).not_to include(remote_status.id) + end + end + + context 'with a viewer' do + let(:viewer) { Fabricate(:account, username: 'viewer') } + + it 'does not include remote instances statuses' do + expect(subject).to include(local_status.id) + expect(subject).not_to include(remote_status.id) + end + + it 'is not affected by personal domain blocks' do + viewer.block_domain!('test.com') + expect(subject).to include(local_status.id) + expect(subject).not_to include(remote_status.id) + end + end + end + + context 'with a remote_only option set' do + let!(:local_account) { Fabricate(:account, domain: nil) } + let!(:remote_account) { Fabricate(:account, domain: 'test.com') } + let!(:local_status) { Fabricate(:status, account: local_account) } + let!(:remote_status) { Fabricate(:status, account: remote_account) } + + subject { described_class.new(viewer, remote: true).get(20).map(&:id) } + + context 'without a viewer' do + let(:viewer) { nil } + + it 'does not include local instances statuses' do + expect(subject).not_to include(local_status.id) + expect(subject).to include(remote_status.id) + end + end + + context 'with a viewer' do + let(:viewer) { Fabricate(:account, username: 'viewer') } + + it 'does not include local instances statuses' do + expect(subject).not_to include(local_status.id) + expect(subject).to include(remote_status.id) + end + end + end + + describe 'with an account passed in' do + before do + @account = Fabricate(:account) + end + + subject { described_class.new(@account).get(20).map(&:id) } + + it 'excludes statuses from accounts blocked by the account' do + blocked = Fabricate(:account) + @account.block!(blocked) + blocked_status = Fabricate(:status, account: blocked) + + expect(subject).not_to include(blocked_status.id) + end + + it 'excludes statuses from accounts who have blocked the account' do + blocker = Fabricate(:account) + blocker.block!(@account) + blocked_status = Fabricate(:status, account: blocker) + + expect(subject).not_to include(blocked_status.id) + end + + it 'excludes statuses from accounts muted by the account' do + muted = Fabricate(:account) + @account.mute!(muted) + muted_status = Fabricate(:status, account: muted) + + expect(subject).not_to include(muted_status.id) + end + + it 'excludes statuses from accounts from personally blocked domains' do + blocked = Fabricate(:account, domain: 'example.com') + @account.block_domain!(blocked.domain) + blocked_status = Fabricate(:status, account: blocked) + + expect(subject).not_to include(blocked_status.id) + end + + context 'with language preferences' do + it 'excludes statuses in languages not allowed by the account user' do + user = Fabricate(:user, chosen_languages: [:en, :es]) + @account.update(user: user) + en_status = Fabricate(:status, language: 'en') + es_status = Fabricate(:status, language: 'es') + fr_status = Fabricate(:status, language: 'fr') + + expect(subject).to include(en_status.id) + expect(subject).to include(es_status.id) + expect(subject).not_to include(fr_status.id) + end + + it 'includes all languages when user does not have a setting' do + user = Fabricate(:user, chosen_languages: nil) + @account.update(user: user) + + en_status = Fabricate(:status, language: 'en') + es_status = Fabricate(:status, language: 'es') + + expect(subject).to include(en_status.id) + expect(subject).to include(es_status.id) + end + + it 'includes all languages when account does not have a user' do + expect(@account.user).to be_nil + en_status = Fabricate(:status, language: 'en') + es_status = Fabricate(:status, language: 'es') + + expect(subject).to include(en_status.id) + expect(subject).to include(es_status.id) + end + end + end + end +end diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index 4aee14cbd..20fb894e7 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -267,241 +267,6 @@ RSpec.describe Status, type: :model do end end - describe '.as_public_timeline' do - it 'only includes statuses with public visibility' do - public_status = Fabricate(:status, visibility: :public) - private_status = Fabricate(:status, visibility: :private) - - results = Status.as_public_timeline - expect(results).to include(public_status) - expect(results).not_to include(private_status) - end - - it 'does not include replies' do - status = Fabricate(:status) - reply = Fabricate(:status, in_reply_to_id: status.id) - - results = Status.as_public_timeline - expect(results).to include(status) - expect(results).not_to include(reply) - end - - it 'does not include boosts' do - status = Fabricate(:status) - boost = Fabricate(:status, reblog_of_id: status.id) - - results = Status.as_public_timeline - expect(results).to include(status) - expect(results).not_to include(boost) - end - - it 'filters out silenced accounts' do - account = Fabricate(:account) - silenced_account = Fabricate(:account, silenced: true) - status = Fabricate(:status, account: account) - silenced_status = Fabricate(:status, account: silenced_account) - - results = Status.as_public_timeline - expect(results).to include(status) - expect(results).not_to include(silenced_status) - end - - context 'without local_only option' do - let(:viewer) { nil } - - let!(:local_account) { Fabricate(:account, domain: nil) } - let!(:remote_account) { Fabricate(:account, domain: 'test.com') } - let!(:local_status) { Fabricate(:status, account: local_account) } - let!(:remote_status) { Fabricate(:status, account: remote_account) } - - subject { Status.as_public_timeline(viewer, false) } - - context 'without a viewer' do - let(:viewer) { nil } - - it 'includes remote instances statuses' do - expect(subject).to include(remote_status) - end - - it 'includes local statuses' do - expect(subject).to include(local_status) - end - end - - context 'with a viewer' do - let(:viewer) { Fabricate(:account, username: 'viewer') } - - it 'includes remote instances statuses' do - expect(subject).to include(remote_status) - end - - it 'includes local statuses' do - expect(subject).to include(local_status) - end - end - end - - context 'with a local_only option set' do - let!(:local_account) { Fabricate(:account, domain: nil) } - let!(:remote_account) { Fabricate(:account, domain: 'test.com') } - let!(:local_status) { Fabricate(:status, account: local_account) } - let!(:remote_status) { Fabricate(:status, account: remote_account) } - - subject { Status.as_public_timeline(viewer, true) } - - context 'without a viewer' do - let(:viewer) { nil } - - it 'does not include remote instances statuses' do - expect(subject).to include(local_status) - expect(subject).not_to include(remote_status) - end - end - - context 'with a viewer' do - let(:viewer) { Fabricate(:account, username: 'viewer') } - - it 'does not include remote instances statuses' do - expect(subject).to include(local_status) - expect(subject).not_to include(remote_status) - end - - it 'is not affected by personal domain blocks' do - viewer.block_domain!('test.com') - expect(subject).to include(local_status) - expect(subject).not_to include(remote_status) - end - end - end - - context 'with a remote_only option set' do - let!(:local_account) { Fabricate(:account, domain: nil) } - let!(:remote_account) { Fabricate(:account, domain: 'test.com') } - let!(:local_status) { Fabricate(:status, account: local_account) } - let!(:remote_status) { Fabricate(:status, account: remote_account) } - - subject { Status.as_public_timeline(viewer, :remote) } - - context 'without a viewer' do - let(:viewer) { nil } - - it 'does not include local instances statuses' do - expect(subject).not_to include(local_status) - expect(subject).to include(remote_status) - end - end - - context 'with a viewer' do - let(:viewer) { Fabricate(:account, username: 'viewer') } - - it 'does not include local instances statuses' do - expect(subject).not_to include(local_status) - expect(subject).to include(remote_status) - end - end - end - - describe 'with an account passed in' do - before do - @account = Fabricate(:account) - end - - it 'excludes statuses from accounts blocked by the account' do - blocked = Fabricate(:account) - Fabricate(:block, account: @account, target_account: blocked) - blocked_status = Fabricate(:status, account: blocked) - - results = Status.as_public_timeline(@account) - expect(results).not_to include(blocked_status) - end - - it 'excludes statuses from accounts who have blocked the account' do - blocked = Fabricate(:account) - Fabricate(:block, account: blocked, target_account: @account) - blocked_status = Fabricate(:status, account: blocked) - - results = Status.as_public_timeline(@account) - expect(results).not_to include(blocked_status) - end - - it 'excludes statuses from accounts muted by the account' do - muted = Fabricate(:account) - Fabricate(:mute, account: @account, target_account: muted) - muted_status = Fabricate(:status, account: muted) - - results = Status.as_public_timeline(@account) - expect(results).not_to include(muted_status) - end - - it 'excludes statuses from accounts from personally blocked domains' do - blocked = Fabricate(:account, domain: 'example.com') - @account.block_domain!(blocked.domain) - blocked_status = Fabricate(:status, account: blocked) - - results = Status.as_public_timeline(@account) - expect(results).not_to include(blocked_status) - end - - context 'with language preferences' do - it 'excludes statuses in languages not allowed by the account user' do - user = Fabricate(:user, chosen_languages: [:en, :es]) - @account.update(user: user) - en_status = Fabricate(:status, language: 'en') - es_status = Fabricate(:status, language: 'es') - fr_status = Fabricate(:status, language: 'fr') - - results = Status.as_public_timeline(@account) - expect(results).to include(en_status) - expect(results).to include(es_status) - expect(results).not_to include(fr_status) - end - - it 'includes all languages when user does not have a setting' do - user = Fabricate(:user, chosen_languages: nil) - @account.update(user: user) - - en_status = Fabricate(:status, language: 'en') - es_status = Fabricate(:status, language: 'es') - - results = Status.as_public_timeline(@account) - expect(results).to include(en_status) - expect(results).to include(es_status) - end - - it 'includes all languages when account does not have a user' do - expect(@account.user).to be_nil - en_status = Fabricate(:status, language: 'en') - es_status = Fabricate(:status, language: 'es') - - results = Status.as_public_timeline(@account) - expect(results).to include(en_status) - expect(results).to include(es_status) - end - end - end - end - - describe '.as_tag_timeline' do - it 'includes statuses with a tag' do - tag = Fabricate(:tag) - status = Fabricate(:status, tags: [tag]) - other = Fabricate(:status) - - results = Status.as_tag_timeline(tag) - expect(results).to include(status) - expect(results).not_to include(other) - end - - it 'allows replies to be included' do - original = Fabricate(:status) - tag = Fabricate(:tag) - status = Fabricate(:status, tags: [tag], in_reply_to_id: original.id) - - results = Status.as_tag_timeline(tag) - expect(results).to include(status) - end - end - describe '.permitted_for' do subject { described_class.permitted_for(target_account, account).pluck(:visibility) } diff --git a/spec/services/hashtag_query_service_spec.rb b/spec/models/tag_feed_spec.rb similarity index 65% rename from spec/services/hashtag_query_service_spec.rb rename to spec/models/tag_feed_spec.rb index 24282d2f0..17d88eb99 100644 --- a/spec/services/hashtag_query_service_spec.rb +++ b/spec/models/tag_feed_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' -describe HashtagQueryService, type: :service do - describe '.call' do +describe TagFeed, type: :service do + describe '#get' do let(:account) { Fabricate(:account) } let(:tag1) { Fabricate(:tag) } let(:tag2) { Fabricate(:tag) } @@ -10,35 +10,35 @@ describe HashtagQueryService, type: :service do let!(:both) { Fabricate(:status, tags: [tag1, tag2]) } it 'can add tags in "any" mode' do - results = subject.call(tag1, { any: [tag2.name] }) + results = described_class.new(tag1, nil, any: [tag2.name]).get(20) expect(results).to include status1 expect(results).to include status2 expect(results).to include both end it 'can remove tags in "all" mode' do - results = subject.call(tag1, { all: [tag2.name] }) + results = described_class.new(tag1, nil, all: [tag2.name]).get(20) expect(results).to_not include status1 expect(results).to_not include status2 expect(results).to include both end it 'can remove tags in "none" mode' do - results = subject.call(tag1, { none: [tag2.name] }) + results = described_class.new(tag1, nil, none: [tag2.name]).get(20) expect(results).to include status1 expect(results).to_not include status2 expect(results).to_not include both end it 'ignores an invalid mode' do - results = subject.call(tag1, { wark: [tag2.name] }) + results = described_class.new(tag1, nil, wark: [tag2.name]).get(20) expect(results).to include status1 expect(results).to_not include status2 expect(results).to include both end it 'handles being passed non existant tag names' do - results = subject.call(tag1, { any: ['wark'] }) + results = described_class.new(tag1, nil, any: ['wark']).get(20) expect(results).to include status1 expect(results).to_not include status2 expect(results).to include both @@ -46,15 +46,23 @@ describe HashtagQueryService, type: :service do it 'can restrict to an account' do BlockService.new.call(account, status1.account) - results = subject.call(tag1, { none: [tag2.name] }, account) + results = described_class.new(tag1, account, none: [tag2.name]).get(20) expect(results).to_not include status1 end it 'can restrict to local' do status1.account.update(domain: 'example.com') status1.update(local: false, uri: 'example.com/toot') - results = subject.call(tag1, { any: [tag2.name] }, nil, true) + results = described_class.new(tag1, nil, any: [tag2.name], local: true).get(20) expect(results).to_not include status1 end + + it 'allows replies to be included' do + original = Fabricate(:status) + status = Fabricate(:status, tags: [tag1], in_reply_to_id: original.id) + + results = described_class.new(tag1, nil).get(20) + expect(results).to include(status) + end end end diff --git a/spec/services/fan_out_on_write_service_spec.rb b/spec/services/fan_out_on_write_service_spec.rb index b7fc7f7ed..538dc2592 100644 --- a/spec/services/fan_out_on_write_service_spec.rb +++ b/spec/services/fan_out_on_write_service_spec.rb @@ -28,10 +28,10 @@ RSpec.describe FanOutOnWriteService, type: :service do end it 'delivers status to hashtag' do - expect(Tag.find_by!(name: 'test').statuses.pluck(:id)).to include status.id + expect(TagFeed.new(Tag.find_by(name: 'test'), alice).get(20).map(&:id)).to include status.id end it 'delivers status to public timeline' do - expect(Status.as_public_timeline(alice).map(&:id)).to include status.id + expect(PublicFeed.new(alice).get(20).map(&:id)).to include status.id end end From e79d719e92e120ba3dd6ec2d8521f7aaa9482634 Mon Sep 17 00:00:00 2001 From: abcang Date: Tue, 8 Sep 2020 00:47:41 +0900 Subject: [PATCH 02/27] Changed tag most_used to recently_used (#14760) --- .../api/v1/featured_tags/suggestions_controller.rb | 8 ++++---- app/controllers/settings/featured_tags_controller.rb | 8 ++++---- app/models/tag.rb | 2 +- app/views/settings/featured_tags/index.html.haml | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/v1/featured_tags/suggestions_controller.rb b/app/controllers/api/v1/featured_tags/suggestions_controller.rb index 8c1b81a0f..75545d3c7 100644 --- a/app/controllers/api/v1/featured_tags/suggestions_controller.rb +++ b/app/controllers/api/v1/featured_tags/suggestions_controller.rb @@ -3,15 +3,15 @@ class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index before_action :require_user! - before_action :set_most_used_tags, only: :index + before_action :set_recently_used_tags, only: :index def index - render json: @most_used_tags, each_serializer: REST::TagSerializer + render json: @recently_used_tags, each_serializer: REST::TagSerializer end private - def set_most_used_tags - @most_used_tags = Tag.most_used(current_account).where.not(id: current_account.featured_tags).limit(10) + def set_recently_used_tags + @recently_used_tags = Tag.recently_used(current_account).where.not(id: current_account.featured_tags).limit(10) end end diff --git a/app/controllers/settings/featured_tags_controller.rb b/app/controllers/settings/featured_tags_controller.rb index 3a3241425..e9861da56 100644 --- a/app/controllers/settings/featured_tags_controller.rb +++ b/app/controllers/settings/featured_tags_controller.rb @@ -6,7 +6,7 @@ class Settings::FeaturedTagsController < Settings::BaseController before_action :authenticate_user! before_action :set_featured_tags, only: :index before_action :set_featured_tag, except: [:index, :create] - before_action :set_most_used_tags, only: :index + before_action :set_recently_used_tags, only: :index def index @featured_tag = FeaturedTag.new @@ -20,7 +20,7 @@ class Settings::FeaturedTagsController < Settings::BaseController redirect_to settings_featured_tags_path else set_featured_tags - set_most_used_tags + set_recently_used_tags render :index end @@ -41,8 +41,8 @@ class Settings::FeaturedTagsController < Settings::BaseController @featured_tags = current_account.featured_tags.order(statuses_count: :desc).reject(&:new_record?) end - def set_most_used_tags - @most_used_tags = Tag.most_used(current_account).where.not(id: @featured_tags.map(&:id)).limit(10) + def set_recently_used_tags + @recently_used_tags = Tag.recently_used(current_account).where.not(id: @featured_tags.map(&:id)).limit(10) end def featured_tag_params diff --git a/app/models/tag.rb b/app/models/tag.rb index bce76fc16..df2f86d95 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -39,7 +39,7 @@ class Tag < ApplicationRecord scope :listable, -> { where(listable: [true, nil]) } scope :trendable, -> { Setting.trendable_by_default ? where(trendable: [true, nil]) : where(trendable: true) } scope :discoverable, -> { listable.joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).order(Arel.sql('account_tag_stats.accounts_count desc')) } - scope :most_used, ->(account) { joins(:statuses).where(statuses: { account: account }).group(:id).order(Arel.sql('count(*) desc')) } + scope :recently_used, ->(account) { joins(:statuses).where(statuses: { id: account.statuses.select(:id).limit(1000) }).group(:id).order(Arel.sql('count(*) desc')) } scope :matches_name, ->(value) { where(arel_table[:name].matches("#{value}%")) } delegate :accounts_count, diff --git a/app/views/settings/featured_tags/index.html.haml b/app/views/settings/featured_tags/index.html.haml index 6734d027c..297379893 100644 --- a/app/views/settings/featured_tags/index.html.haml +++ b/app/views/settings/featured_tags/index.html.haml @@ -9,7 +9,7 @@ = render 'shared/error_messages', object: @featured_tag .fields-group - = f.input :name, wrapper: :with_block_label, hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@most_used_tags.map { |tag| link_to("##{tag.name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' ') + = f.input :name, wrapper: :with_block_label, hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@recently_used_tags.map { |tag| link_to("##{tag.name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' ') .actions = f.button :button, t('featured_tags.add_new'), type: :submit From 517af45e32535efe1494c0e1e59304a5a7771dba Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 7 Sep 2020 18:00:15 +0200 Subject: [PATCH 03/27] Fix multiple boosts of a same toot erroneously appearing in TL (#14759) * Check for and record reblog info atomically Instead of using ZREVRANK to determine whether a reblog is a new reblog or not, use ZADD's NX option to perform the check/addition option atomically. * Replace ZREVRANK call with ZSCORE key which is more efficient * Make tests a bit stricter * Fix off-by-one --- app/lib/feed_manager.rb | 20 +++++++++----------- spec/lib/feed_manager_spec.rb | 4 ++-- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 9ab7b53be..785009b52 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -77,9 +77,11 @@ class FeedManager # Get the score of the REBLOG_FALLOFF'th item in our feed, and stop # tracking anything after it for deduplication purposes. - falloff_rank = FeedManager::REBLOG_FALLOFF - 1 + falloff_rank = FeedManager::REBLOG_FALLOFF falloff_range = redis.zrevrange(timeline_key, falloff_rank, falloff_rank, with_scores: true) - falloff_score = falloff_range&.first&.last&.to_i || 0 + falloff_score = falloff_range&.first&.last&.to_i + + return if falloff_score.nil? # Get any reblogs we might have to clean up after. redis.zrangebyscore(reblog_key, 0, falloff_score).each do |reblogged_id| @@ -279,14 +281,12 @@ class FeedManager return false if !rank.nil? && rank < FeedManager::REBLOG_FALLOFF - reblog_rank = redis.zrevrank(reblog_key, status.reblog_of_id) - - if reblog_rank.nil? + # The ordered set at `reblog_key` holds statuses which have a reblog + # in the top `REBLOG_FALLOFF` statuses of the timeline + if redis.zadd(reblog_key, status.id, status.reblog_of_id, nx: true) # This is not something we've already seen reblogged, so we - # can just add it to the feed (and note that we're - # reblogging it). + # can just add it to the feed (and note that we're reblogging it). redis.zadd(timeline_key, status.id, status.id) - redis.zadd(reblog_key, status.id, status.reblog_of_id) else # Another reblog of the same status was already in the # REBLOG_FALLOFF most recent statuses, so we note that this @@ -300,9 +300,7 @@ class FeedManager # delay of the worker deliverying the original status, the late addition # by merging timelines, and other reasons. # If such a reblog already exists, just do not re-insert it into the feed. - rank = redis.zrevrank(reblog_key, status.id) - - return false unless rank.nil? + return false unless redis.zscore(reblog_key, status.id).nil? redis.zadd(timeline_key, status.id, status.id) end diff --git a/spec/lib/feed_manager_spec.rb b/spec/lib/feed_manager_spec.rb index 5088d1742..d86dd7993 100644 --- a/spec/lib/feed_manager_spec.rb +++ b/spec/lib/feed_manager_spec.rb @@ -444,8 +444,8 @@ RSpec.describe FeedManager do expect(Redis.current.exists?(reblog_set_key)).to be true expect(Redis.current.zrange(reblogs_key, 0, -1)).to eq [reblogged.id.to_s] - # Push everything off the end of the feed. - FeedManager::MAX_ITEMS.times do + # Push everything past the reblog falloff. + FeedManager::REBLOG_FALLOFF.times do FeedManager.instance.push_to_home(receiver, Fabricate(:status)) end From e2dc61d0f4dea0c6c503cece19d5f7a821d4c07a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:05:24 +0900 Subject: [PATCH 04/27] Bump tar from 6.0.2 to 6.0.5 (#14758) Bumps [tar](https://github.com/npm/node-tar) from 6.0.2 to 6.0.5. - [Release notes](https://github.com/npm/node-tar/releases) - [Changelog](https://github.com/npm/node-tar/blob/master/CHANGELOG.md) - [Commits](https://github.com/npm/node-tar/compare/v6.0.2...v6.0.5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2591d4162..156ecef3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7061,7 +7061,7 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" -minizlib@^2.1.0: +minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -10254,14 +10254,14 @@ tapable@^1.0.0, tapable@^1.1.3: integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tar@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.2.tgz#5df17813468a6264ff14f766886c622b84ae2f39" - integrity sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg== + version "6.0.5" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" + integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" minipass "^3.0.0" - minizlib "^2.1.0" + minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" From 4c2f87e24ed68ba2617b5a8e6f3ed8a1105e24a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:06:23 +0900 Subject: [PATCH 05/27] Bump sidekiq-unique-jobs from 6.0.22 to 6.0.23 (#14735) Bumps [sidekiq-unique-jobs](https://github.com/mhenrixon/sidekiq-unique-jobs) from 6.0.22 to 6.0.23. - [Release notes](https://github.com/mhenrixon/sidekiq-unique-jobs/releases) - [Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/CHANGELOG.md) - [Commits](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.22...v6.0.23) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1e289c30a..3f771c017 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -577,10 +577,10 @@ GEM sidekiq (>= 3) thwait tilt (>= 1.4.0) - sidekiq-unique-jobs (6.0.22) + sidekiq-unique-jobs (6.0.23) concurrent-ruby (~> 1.0, >= 1.0.5) sidekiq (>= 4.0, < 7.0) - thor (~> 0) + thor (>= 0.20, < 2.0) simple-navigation (4.1.0) activesupport (>= 2.3.2) simple_form (5.0.2) From 507ed519835dfcf0c254b4aae1995af0453b9c5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:08:17 +0900 Subject: [PATCH 06/27] Bump rubocop-rails from 2.6.0 to 2.8.0 (#14734) Bumps [rubocop-rails](https://github.com/rubocop-hq/rubocop-rails) from 2.6.0 to 2.8.0. - [Release notes](https://github.com/rubocop-hq/rubocop-rails/releases) - [Changelog](https://github.com/rubocop-hq/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop-hq/rubocop-rails/compare/v2.6.0...v2.8.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 6a683d586..1d50d6373 100644 --- a/Gemfile +++ b/Gemfile @@ -141,7 +141,7 @@ group :development do gem 'letter_opener_web', '~> 1.4' gem 'memory_profiler' gem 'rubocop', '~> 0.88', require: false - gem 'rubocop-rails', '~> 2.6', require: false + gem 'rubocop-rails', '~> 2.8', require: false gem 'brakeman', '~> 4.9', require: false gem 'bundler-audit', '~> 0.7', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 3f771c017..1f8064e62 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -355,7 +355,7 @@ GEM mimemagic (0.3.5) mini_mime (1.0.2) mini_portile2 (2.4.0) - minitest (5.14.1) + minitest (5.14.2) msgpack (1.3.3) multi_json (1.15.0) multipart-post (2.1.1) @@ -546,10 +546,10 @@ GEM unicode-display_width (>= 1.4.0, < 2.0) rubocop-ast (0.3.0) parser (>= 2.7.1.4) - rubocop-rails (2.6.0) + rubocop-rails (2.8.0) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.82.0) + rubocop (>= 0.87.0) ruby-progressbar (1.10.1) ruby-saml (1.11.0) nokogiri (>= 1.5.10) @@ -779,7 +779,7 @@ DEPENDENCIES rspec-sidekiq (~> 3.1) rspec_junit_formatter (~> 0.4) rubocop (~> 0.88) - rubocop-rails (~> 2.6) + rubocop-rails (~> 2.8) ruby-progressbar (~> 1.10) sanitize (~> 5.2) sidekiq (~> 6.1) From 081571549ca05b94b571c90cd19ae06a86b12434 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:08:59 +0900 Subject: [PATCH 07/27] Bump rdf from 3.1.5 to 3.1.6 (#14736) Bumps [rdf](https://github.com/ruby-rdf/rdf) from 3.1.5 to 3.1.6. - [Release notes](https://github.com/ruby-rdf/rdf/releases) - [Changelog](https://github.com/ruby-rdf/rdf/blob/develop/CHANGES.md) - [Commits](https://github.com/ruby-rdf/rdf/compare/3.1.5...3.1.6) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1f8064e62..104bc51af 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -476,7 +476,7 @@ GEM thor (>= 0.19.0, < 2.0) rainbow (3.0.0) rake (13.0.1) - rdf (3.1.5) + rdf (3.1.6) hamster (~> 3.0) link_header (~> 0.0, >= 0.0.8) rdf-normalize (0.4.0) From 16b9074a5d2c438b2cb03c21c6360f2a43c61b75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:09:18 +0900 Subject: [PATCH 08/27] Bump electron-to-chromium from 1.3.545 to 1.3.562 (#14757) Bumps [electron-to-chromium](https://github.com/kilian/electron-to-chromium) from 1.3.545 to 1.3.562. - [Release notes](https://github.com/kilian/electron-to-chromium/releases) - [Changelog](https://github.com/Kilian/electron-to-chromium/blob/master/CHANGELOG.md) - [Commits](https://github.com/kilian/electron-to-chromium/compare/v1.3.545...v1.3.562) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 156ecef3c..3abb7f681 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3822,9 +3822,9 @@ ejs@^2.3.4, ejs@^2.6.1: integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== electron-to-chromium@^1.3.523: - version "1.3.545" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.545.tgz#d9add694c78554b8c00bc6e6fc929d5ccd7d1b99" - integrity sha512-+0R/i17u5E1cwF3g0W8Niq3UUKTUMyyT4kLkutZUHG8mDNvFsAckK3HIanzGVtixe3b6rknD8k7gHiR6nKFkgg== + version "1.3.562" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.562.tgz#79c20277ee1c8d0173a22af00e38433b752bc70f" + integrity sha512-WhRe6liQ2q/w1MZc8mD8INkenHivuHdrr4r5EQHNomy3NJux+incP6M6lDMd0paShP3MD0WGe5R1TWmEClf+Bg== elliptic@^6.5.3: version "6.5.3" From 0f39fc609f8c9eb43d18a47654857ad289611b3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:09:44 +0900 Subject: [PATCH 09/27] Bump brakeman from 4.9.0 to 4.9.1 (#14737) Bumps [brakeman](https://github.com/presidentbeef/brakeman) from 4.9.0 to 4.9.1. - [Release notes](https://github.com/presidentbeef/brakeman/releases) - [Changelog](https://github.com/presidentbeef/brakeman/blob/main/CHANGES.md) - [Commits](https://github.com/presidentbeef/brakeman/compare/v4.9.0...v4.9.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 104bc51af..78a7e9235 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -106,7 +106,7 @@ GEM ffi (~> 1.10.0) bootsnap (1.4.8) msgpack (~> 1.0) - brakeman (4.9.0) + brakeman (4.9.1) browser (4.2.0) builder (3.2.4) bullet (6.1.0) From 5179a8051c5683a67266bde27fd6b306e19d58bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:10:49 +0900 Subject: [PATCH 10/27] Bump warden from 1.2.8 to 1.2.9 (#14738) Bumps [warden](https://github.com/hassox/warden) from 1.2.8 to 1.2.9. - [Release notes](https://github.com/hassox/warden/releases) - [Changelog](https://github.com/wardencommunity/warden/blob/master/CHANGELOG.md) - [Commits](https://github.com/hassox/warden/compare/v1.2.8...v1.2.9) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 78a7e9235..44ac22e85 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -641,8 +641,8 @@ GEM unf_ext (0.0.7.7) unicode-display_width (1.7.0) uniform_notifier (1.13.0) - warden (1.2.8) - rack (>= 2.0.6) + warden (1.2.9) + rack (>= 2.0.9) webauthn (3.0.0.alpha1) android_key_attestation (~> 0.3.0) awrence (~> 1.1) From 744aeefb4e634e6acdd0cc2908eeb09479f776ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:11:21 +0900 Subject: [PATCH 11/27] Bump bcrypt from 3.1.15 to 3.1.16 (#14739) Bumps [bcrypt](https://github.com/codahale/bcrypt-ruby) from 3.1.15 to 3.1.16. - [Release notes](https://github.com/codahale/bcrypt-ruby/releases) - [Changelog](https://github.com/codahale/bcrypt-ruby/blob/master/CHANGELOG) - [Commits](https://github.com/codahale/bcrypt-ruby/compare/v3.1.15...v3.1.16) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 44ac22e85..1db9f3d8a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -94,7 +94,7 @@ GEM aws-sigv4 (~> 1.1) aws-sigv4 (1.2.2) aws-eventstream (~> 1, >= 1.0.2) - bcrypt (3.1.15) + bcrypt (3.1.16) better_errors (2.7.1) coderay (>= 1.0.0) erubi (>= 1.0.0) From c3b5e38c78c504f6e39ba434d7d941bbaac90377 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:12:16 +0900 Subject: [PATCH 12/27] Bump eventemitter3 from 4.0.5 to 4.0.7 (#14742) Bumps [eventemitter3](https://github.com/primus/eventemitter3) from 4.0.5 to 4.0.7. - [Release notes](https://github.com/primus/eventemitter3/releases) - [Commits](https://github.com/primus/eventemitter3/compare/4.0.5...4.0.7) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3abb7f681..469c38510 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4328,9 +4328,9 @@ event-emitter@~0.3.5: es5-ext "~0.10.14" eventemitter3@^4.0.0: - version "4.0.5" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.5.tgz#51d81e4f1ccc8311a04f0c20121ea824377ea6d9" - integrity sha512-QR0rh0YiPuxuDQ6+T9GAO/xWTExXpxIes1Nl9RykNGTnE1HJmkuEfxJH9cubjIOQZ/GH4qNBR4u8VSHaKiWs4g== + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.0.0: version "3.2.0" From 2c3b3c2235f4b0230da141ccd77c40a4af999355 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:13:04 +0900 Subject: [PATCH 13/27] Bump @babel/core from 7.11.1 to 7.11.6 (#14755) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.11.1 to 7.11.6. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.11.6/packages/babel-core) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 83 ++++++++++++++++++---------------------------------- 2 files changed, 29 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index dcfbde7d4..fb43592c5 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ }, "private": true, "dependencies": { - "@babel/core": "^7.11.1", + "@babel/core": "^7.11.6", "@babel/plugin-proposal-class-properties": "^7.8.3", "@babel/plugin-proposal-decorators": "^7.10.5", "@babel/plugin-transform-react-inline-elements": "^7.10.4", diff --git a/yarn.lock b/yarn.lock index 469c38510..977f16992 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,19 +18,19 @@ invariant "^2.2.4" semver "^5.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.7.5": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.4.tgz#4301dfdfafa01eeb97f1896c5501a3f0655d4229" - integrity sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg== +"@babel/core@^7.1.0", "@babel/core@^7.11.6", "@babel/core@^7.7.2", "@babel/core@^7.7.5": + version "7.11.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" + integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.4" + "@babel/generator" "^7.11.6" "@babel/helper-module-transforms" "^7.11.0" "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.4" + "@babel/parser" "^7.11.5" "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.0" - "@babel/types" "^7.11.0" + "@babel/traverse" "^7.11.5" + "@babel/types" "^7.11.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -40,34 +40,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.11.1", "@babel/core@^7.7.2": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.1.tgz#2c55b604e73a40dc21b0e52650b11c65cf276643" - integrity sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ== +"@babel/generator@^7.11.5", "@babel/generator@^7.11.6": + version "7.11.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" + integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.0" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.1" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.0" - "@babel/types" "^7.11.0" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.11.0", "@babel/generator@^7.11.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.4.tgz#1ec7eec00defba5d6f83e50e3ee72ae2fee482be" - integrity sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g== - dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.11.5" jsesc "^2.5.1" source-map "^0.5.0" @@ -311,15 +289,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.4.tgz#6fa1a118b8b0d80d0267b719213dc947e88cc0ca" - integrity sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA== - -"@babel/parser@^7.11.1", "@babel/parser@^7.7.0": - version "7.11.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.3.tgz#9e1eae46738bcd08e23e867bab43e7b95299a8f9" - integrity sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA== +"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.7.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" + integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== "@babel/plugin-proposal-async-generator-functions@^7.10.4": version "7.10.4" @@ -998,25 +971,25 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.7.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24" - integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.7.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" + integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.0" + "@babel/generator" "^7.11.5" "@babel/helper-function-name" "^7.10.4" "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.0" - "@babel/types" "^7.11.0" + "@babel/parser" "^7.11.5" + "@babel/types" "^7.11.5" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" - integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" + integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" From 1fb01185a9957063a4fd5205993a12ab25540a65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:15:39 +0900 Subject: [PATCH 14/27] Bump public_suffix from 4.0.5 to 4.0.6 (#14743) Bumps [public_suffix](https://github.com/weppos/publicsuffix-ruby) from 4.0.5 to 4.0.6. - [Release notes](https://github.com/weppos/publicsuffix-ruby/releases) - [Changelog](https://github.com/weppos/publicsuffix-ruby/blob/master/CHANGELOG.md) - [Commits](https://github.com/weppos/publicsuffix-ruby/compare/v4.0.5...v4.0.6) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1db9f3d8a..8c9d4872d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -426,7 +426,7 @@ GEM pry (~> 0.13.0) pry-rails (0.3.9) pry (>= 0.10.4) - public_suffix (4.0.5) + public_suffix (4.0.6) puma (4.3.5) nio4r (~> 2.0) pundit (2.1.0) From 0ea5718415634fc39508fe0c2fa15b96b30df018 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:17:08 +0900 Subject: [PATCH 15/27] Bump @babel/plugin-transform-runtime from 7.11.0 to 7.11.5 (#14754) Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.11.0 to 7.11.5. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.11.5/packages/babel-plugin-transform-runtime) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fb43592c5..d315b8a67 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@babel/plugin-proposal-class-properties": "^7.8.3", "@babel/plugin-proposal-decorators": "^7.10.5", "@babel/plugin-transform-react-inline-elements": "^7.10.4", - "@babel/plugin-transform-runtime": "^7.11.0", + "@babel/plugin-transform-runtime": "^7.11.5", "@babel/preset-env": "^7.11.0", "@babel/preset-react": "^7.10.4", "@babel/runtime": "^7.11.2", diff --git a/yarn.lock b/yarn.lock index 977f16992..37fa1cf86 100644 --- a/yarn.lock +++ b/yarn.lock @@ -779,10 +779,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-runtime@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz#e27f78eb36f19448636e05c33c90fd9ad9b8bccf" - integrity sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw== +"@babel/plugin-transform-runtime@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.5.tgz#f108bc8e0cf33c37da031c097d1df470b3a293fc" + integrity sha512-9aIoee+EhjySZ6vY5hnLjigHzunBlscx9ANKutkeWTJTx6m5Rbq6Ic01tLvO54lSusR+BxV7u4UDdCmXv5aagg== dependencies: "@babel/helper-module-imports" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" From da12b5b1121e070d268143108779725279263f35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:17:46 +0900 Subject: [PATCH 16/27] Bump postcss-calc from 7.0.3 to 7.0.4 (#14752) Bumps [postcss-calc](https://github.com/postcss/postcss-calc) from 7.0.3 to 7.0.4. - [Release notes](https://github.com/postcss/postcss-calc/releases) - [Changelog](https://github.com/postcss/postcss-calc/blob/master/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss-calc/compare/v7.0.3...v7.0.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 37fa1cf86..4136bb2ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7940,9 +7940,9 @@ posix-character-classes@^0.1.0: integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= postcss-calc@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.3.tgz#d65cca92a3c52bf27ad37a5f732e0587b74f1623" - integrity sha512-IB/EAEmZhIMEIhG7Ov4x+l47UaXOS1n2f4FBUk/aKllQhtSCxWhTzn0nJgkqN7fo/jcWySvWTSB6Syk9L+31bA== + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.4.tgz#5e177ddb417341e6d4a193c5d9fd8ada79094f8b" + integrity sha512-0I79VRAd1UTkaHzY9w83P39YGO/M3bG7/tNLrHGEunBolfoGM0hSjrGvjoeaj0JE/zIw5GsI2KZ0UwDJqv5hjw== dependencies: postcss "^7.0.27" postcss-selector-parser "^6.0.2" From cf743785435e3971789ab026f968e5d046f78c27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:18:10 +0900 Subject: [PATCH 17/27] Bump postgres-date from 1.0.6 to 1.0.7 (#14745) Bumps [postgres-date](https://github.com/bendrucker/postgres-date) from 1.0.6 to 1.0.7. - [Release notes](https://github.com/bendrucker/postgres-date/releases) - [Commits](https://github.com/bendrucker/postgres-date/compare/v1.0.6...v1.0.7) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4136bb2ea..023915210 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8304,9 +8304,9 @@ postgres-bytea@~1.0.0: integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= postgres-date@~1.0.0: - version "1.0.6" - resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.6.tgz#4925e8085b30c2ba1a06ac91b9a3473954a2ce2d" - integrity sha512-o2a4gxeFcox+CgB3Ig/kNHBP23PiEXHCXx7pcIIsvzoNz4qv+lKTyiSkjOXIMNUl12MO/mOYl2K6wR9X5K6Plg== + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== postgres-interval@^1.1.0: version "1.2.0" From af06c2d15a22ed5733c6cba5e65d899484151fff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:19:03 +0900 Subject: [PATCH 18/27] Bump esrecurse from 4.2.1 to 4.3.0 (#14746) Bumps [esrecurse](https://github.com/estools/esrecurse) from 4.2.1 to 4.3.0. - [Release notes](https://github.com/estools/esrecurse/releases) - [Commits](https://github.com/estools/esrecurse/compare/v4.2.1...v4.3.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 023915210..62973410d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4266,21 +4266,21 @@ esquery@^1.2.0: estraverse "^5.1.0" esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" - integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== esutils@^2.0.2: version "2.0.3" From 50f763fcd9fccda2e974ca7349b3c2cea102b115 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:21:01 +0900 Subject: [PATCH 19/27] Bump aws-partitions from 1.363.0 to 1.365.0 (#14748) Bumps [aws-partitions](https://github.com/aws/aws-sdk-ruby) from 1.363.0 to 1.365.0. - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-partitions/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-ruby/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8c9d4872d..e32e68260 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -79,7 +79,7 @@ GEM cocaine (~> 0.5.3) awrence (1.1.1) aws-eventstream (1.1.0) - aws-partitions (1.363.0) + aws-partitions (1.365.0) aws-sdk-core (3.105.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) From 0d38c911dd6570ca76d0f09236e0d27cae1b4f22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:22:10 +0900 Subject: [PATCH 20/27] Bump sass-loader from 9.0.3 to 10.0.2 (#14741) Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 9.0.3 to 10.0.2. - [Release notes](https://github.com/webpack-contrib/sass-loader/releases) - [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/sass-loader/compare/v9.0.3...v10.0.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 49 +++++++++++++++++++++++++++---------------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index d315b8a67..a1d393fb7 100644 --- a/package.json +++ b/package.json @@ -153,7 +153,7 @@ "reselect": "^4.0.0", "rimraf": "^3.0.2", "sass": "^1.26.10", - "sass-loader": "^9.0.3", + "sass-loader": "^10.0.2", "stacktrace-js": "^2.0.2", "stringz": "^2.1.0", "substring-trie": "^1.0.2", diff --git a/yarn.lock b/yarn.lock index 62973410d..11a67a668 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1466,10 +1466,10 @@ jest-diff "^25.2.1" pretty-format "^25.2.1" -"@types/json-schema@^7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" - integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== +"@types/json-schema@^7.0.5": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== "@types/json5@^0.0.29": version "0.0.29" @@ -1771,6 +1771,11 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + ajv@^4.7.0: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -1779,7 +1784,7 @@ ajv@^4.7.0: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.9.1: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.9.1: version "6.12.4" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== @@ -6581,10 +6586,10 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -klona@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/klona/-/klona-1.1.2.tgz#a79e292518a5a5412ec8d097964bff1571a64db0" - integrity sha512-xf88rTeHiXk+XE2Vhi6yj8Wm3gMZrygGdKjJqN8HkV+PwF/t50/LdAKHoHpPcxFAlmQszTZ1CugrK25S7qDRLA== +klona@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.3.tgz#98274552c513583ad7a01456a789a2a0b4a2a538" + integrity sha512-CgPOT3ZadDpXxKcfV56lEQ9OQSZ42Mk26gnozI+uN/k39vzD8toUhRQoqsX0m9Q3eMPEfsLWmtyUpK/yqST4yg== knot.js@^1.1.5: version "1.1.5" @@ -9364,15 +9369,15 @@ sass-lint@^1.13.1: path-is-absolute "^1.0.0" util "^0.10.3" -sass-loader@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-9.0.3.tgz#086adcf0bfdcc9d920413e2cdc3ba3321373d547" - integrity sha512-fOwsP98ac1VMme+V3+o0HaaMHp8Q/C9P+MUazLFVi3Jl7ORGHQXL1XeRZt3zLSGZQQPC8xE42Y2WptItvGjDQg== +sass-loader@^10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.0.2.tgz#c7b73010848b264792dd45372eea0b87cba4401e" + integrity sha512-wV6NDUVB8/iEYMalV/+139+vl2LaRFlZGEd5/xmdcdzQcgmis+npyco6NsDTVOlNA3y2NV9Gcz+vHyFMIT+ffg== dependencies: - klona "^1.1.2" + klona "^2.0.3" loader-utils "^2.0.0" neo-async "^2.6.2" - schema-utils "^2.7.0" + schema-utils "^2.7.1" semver "^7.3.2" sass@^1.26.10: @@ -9411,14 +9416,14 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.2.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== +schema-utils@^2.2.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0, schema-utils@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" scroll-behavior@^0.9.1: version "0.9.12" From ae36540455b5b01cafe3c42ccbb43b5d7fce58c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:22:33 +0900 Subject: [PATCH 21/27] Bump oj from 3.10.13 to 3.10.14 (#14749) Bumps [oj](https://github.com/ohler55/oj) from 3.10.13 to 3.10.14. - [Release notes](https://github.com/ohler55/oj/releases) - [Changelog](https://github.com/ohler55/oj/blob/develop/CHANGELOG.md) - [Commits](https://github.com/ohler55/oj/compare/v3.10.13...v3.10.14) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index e32e68260..0191f0972 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -373,7 +373,7 @@ GEM concurrent-ruby (~> 1.0, >= 1.0.2) sidekiq (>= 3.5) statsd-ruby (~> 1.4, >= 1.4.0) - oj (3.10.13) + oj (3.10.14) omniauth (1.9.1) hashie (>= 3.4.6) rack (>= 1.6.2, < 3) From 4dfa9a58dee9d30df04e55386963e6c2da2ba8a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:22:50 +0900 Subject: [PATCH 22/27] Bump ox from 2.13.2 to 2.13.3 (#14751) Bumps [ox](https://github.com/ohler55/ox) from 2.13.2 to 2.13.3. - [Release notes](https://github.com/ohler55/ox/releases) - [Changelog](https://github.com/ohler55/ox/blob/develop/CHANGELOG.md) - [Commits](https://github.com/ohler55/ox/compare/v2.13.2...v2.13.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0191f0972..24371a4dc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -387,7 +387,7 @@ GEM openssl (2.2.0) openssl-signature_algorithm (0.4.0) orm_adapter (0.5.0) - ox (2.13.2) + ox (2.13.3) paperclip (6.0.0) activemodel (>= 4.2.0) activesupport (>= 4.2.0) From ac58059cc5c8c34bae9c5d02726e139214cd6960 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:45:50 +0900 Subject: [PATCH 23/27] Bump caniuse-lite from 1.0.30001120 to 1.0.30001124 (#14756) Bumps [caniuse-lite](https://github.com/ben-eb/caniuse-lite) from 1.0.30001120 to 1.0.30001124. - [Release notes](https://github.com/ben-eb/caniuse-lite/releases) - [Changelog](https://github.com/ben-eb/caniuse-lite/blob/master/CHANGELOG.md) - [Commits](https://github.com/ben-eb/caniuse-lite/compare/v1.0.30001120...v1.0.30001124) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 11a67a668..e65d54325 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2677,9 +2677,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111: - version "1.0.30001120" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001120.tgz#cd21d35e537214e19f7b9f4f161f7b0f2710d46c" - integrity sha512-JBP68okZs1X8D7MQTY602jxMYBmXEKOFkzTBaNSkubooMPFOAv2TXWaKle7qgHpjLDhUzA/TMT0qsNleVyXGUQ== + version "1.0.30001124" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001124.tgz#5d9998190258e11630d674fc50ea8e579ae0ced2" + integrity sha512-zQW8V3CdND7GHRH6rxm6s59Ww4g/qGWTheoboW9nfeMg7sUoopIfKCcNZUjwYRCOrvereh3kwDpZj4VLQ7zGtA== capture-exit@^2.0.0: version "2.0.0" From 60282931c10fa5dec371caac8d7945870cd1736a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 08:22:54 +0900 Subject: [PATCH 24/27] Bump rubocop from 0.88.0 to 0.90.0 (#14747) Bumps [rubocop](https://github.com/rubocop-hq/rubocop) from 0.88.0 to 0.90.0. - [Release notes](https://github.com/rubocop-hq/rubocop/releases) - [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.88.0...v0.90.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 1d50d6373..f549f447a 100644 --- a/Gemfile +++ b/Gemfile @@ -140,7 +140,7 @@ group :development do gem 'letter_opener', '~> 1.7' gem 'letter_opener_web', '~> 1.4' gem 'memory_profiler' - gem 'rubocop', '~> 0.88', require: false + gem 'rubocop', '~> 0.90', require: false gem 'rubocop-rails', '~> 2.8', require: false gem 'brakeman', '~> 4.9', require: false gem 'bundler-audit', '~> 0.7', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 24371a4dc..c8d008e1b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -535,13 +535,13 @@ GEM rspec-support (3.9.3) rspec_junit_formatter (0.4.1) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (0.88.0) + rubocop (0.90.0) parallel (~> 1.10) parser (>= 2.7.1.1) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.7) rexml - rubocop-ast (>= 0.1.0, < 1.0) + rubocop-ast (>= 0.3.0, < 1.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) rubocop-ast (0.3.0) @@ -778,7 +778,7 @@ DEPENDENCIES rspec-rails (~> 4.0) rspec-sidekiq (~> 3.1) rspec_junit_formatter (~> 0.4) - rubocop (~> 0.88) + rubocop (~> 0.90) rubocop-rails (~> 2.8) ruby-progressbar (~> 1.10) sanitize (~> 5.2) From d1c68aa0d821b88720508f1a2959cbcf26927dc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 08:23:13 +0900 Subject: [PATCH 25/27] Bump puma from 4.3.5 to 4.3.6 (#14750) Bumps [puma](https://github.com/puma/puma) from 4.3.5 to 4.3.6. - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/compare/v4.3.5...v4.3.6) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c8d008e1b..21c857669 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -363,7 +363,7 @@ GEM net-scp (3.0.0) net-ssh (>= 2.6.5, < 7.0.0) net-ssh (6.1.0) - nio4r (2.5.2) + nio4r (2.5.3) nokogiri (1.10.10) mini_portile2 (~> 2.4.0) nokogumbo (2.0.2) @@ -427,7 +427,7 @@ GEM pry-rails (0.3.9) pry (>= 0.10.4) public_suffix (4.0.6) - puma (4.3.5) + puma (4.3.6) nio4r (~> 2.0) pundit (2.1.0) activesupport (>= 3.0.0) From 169f9105ef9b65380ff6af177c11a7b247025684 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2020 02:43:22 +0200 Subject: [PATCH 26/27] Bump browserslist from 4.14.0 to 4.14.1 (#14753) Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.14.0 to 4.14.1. - [Release notes](https://github.com/browserslist/browserslist/releases) - [Changelog](https://github.com/browserslist/browserslist/blob/master/CHANGELOG.md) - [Commits](https://github.com/browserslist/browserslist/compare/4.14.0...4.14.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index e65d54325..18f212004 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2501,12 +2501,12 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.8.5: - version "4.14.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.0.tgz#2908951abfe4ec98737b72f34c3bcedc8d43b000" - integrity sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ== + version "4.14.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.1.tgz#cb2b490ba881d45dc3039078c7ed04411eaf3fa3" + integrity sha512-zyBTIHydW37pnb63c7fHFXUG6EcqWOqoMdDx6cdyaDFriZ20EoVxcE95S54N+heRqY8m8IUgB5zYta/gCwSaaA== dependencies: - caniuse-lite "^1.0.30001111" - electron-to-chromium "^1.3.523" + caniuse-lite "^1.0.30001124" + electron-to-chromium "^1.3.562" escalade "^3.0.2" node-releases "^1.1.60" @@ -2676,7 +2676,7 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001124: version "1.0.30001124" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001124.tgz#5d9998190258e11630d674fc50ea8e579ae0ced2" integrity sha512-zQW8V3CdND7GHRH6rxm6s59Ww4g/qGWTheoboW9nfeMg7sUoopIfKCcNZUjwYRCOrvereh3kwDpZj4VLQ7zGtA== @@ -3799,7 +3799,7 @@ ejs@^2.3.4, ejs@^2.6.1: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== -electron-to-chromium@^1.3.523: +electron-to-chromium@^1.3.562: version "1.3.562" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.562.tgz#79c20277ee1c8d0173a22af00e38433b752bc70f" integrity sha512-WhRe6liQ2q/w1MZc8mD8INkenHivuHdrr4r5EQHNomy3NJux+incP6M6lDMd0paShP3MD0WGe5R1TWmEClf+Bg== From 65760f59df46e388919a9f7ccba1958d967b2695 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 8 Sep 2020 03:41:16 +0200 Subject: [PATCH 27/27] Refactor feed manager (#14761) --- app/lib/feed_manager.rb | 236 +++++++++++++++++++----- app/services/after_block_service.rb | 2 +- app/services/notify_service.rb | 6 +- app/services/precompute_feed_service.rb | 2 +- app/workers/feed_insert_worker.rb | 9 +- app/workers/merge_worker.rb | 4 +- app/workers/mute_worker.rb | 7 +- app/workers/unmerge_worker.rb | 4 +- spec/lib/feed_manager_spec.rb | 88 +++------ 9 files changed, 235 insertions(+), 123 deletions(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 785009b52..0876d107b 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -6,31 +6,54 @@ class FeedManager include Singleton include Redisable + # Maximum number of items stored in a single feed MAX_ITEMS = 400 - # Must be <= MAX_ITEMS or the tracking sets will grow forever + # Number of items in the feed since last reblog of status + # before the new reblog will be inserted. Must be <= MAX_ITEMS + # or the tracking sets will grow forever REBLOG_FALLOFF = 40 + # Execute block for every active account + # @yield [Account] + # @return [void] def with_active_accounts(&block) Account.joins(:user).where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago).find_each(&block) end + # Redis key of a feed + # @param [Symbol] type + # @param [Integer] id + # @param [Symbol] subtype + # @return [String] def key(type, id, subtype = nil) return "feed:#{type}:#{id}" unless subtype "feed:#{type}:#{id}:#{subtype}" end - def filter?(timeline_type, status, receiver_id) - if timeline_type == :home - filter_from_home?(status, receiver_id, build_crutches(receiver_id, [status])) - elsif timeline_type == :mentions - filter_from_mentions?(status, receiver_id) + # Check if the status should not be added to a feed + # @param [Symbol] timeline_type + # @param [Status] status + # @param [Account|List] receiver + # @return [Boolean] + def filter?(timeline_type, status, receiver) + case timeline_type + when :home + filter_from_home?(status, receiver.id, build_crutches(receiver.id, [status])) + when :list + filter_from_list?(status, receiver) || filter_from_home?(status, receiver.account_id, build_crutches(receiver.account_id, [status])) + when :mentions + filter_from_mentions?(status, receiver.id) else false end end + # Add a status to a home feed and send a streaming API update + # @param [Account] account + # @param [Status] status + # @return [Boolean] def push_to_home(account, status) return false unless add_to_feed(:home, account.id, status, account.user&.aggregates_reblogs?) @@ -39,6 +62,10 @@ class FeedManager true end + # Remove a status from a home feed and send a streaming API update + # @param [Account] account + # @param [Status] status + # @return [Boolean] def unpush_from_home(account, status) return false unless remove_from_feed(:home, account.id, status, account.user&.aggregates_reblogs?) @@ -46,21 +73,22 @@ class FeedManager true end + # Add a status to a list feed and send a streaming API update + # @param [List] list + # @param [Status] status + # @return [Boolean] def push_to_list(list, status) - if status.reply? && status.in_reply_to_account_id != status.account_id - should_filter = status.in_reply_to_account_id != list.account_id - should_filter &&= !list.show_all_replies? - should_filter &&= !(list.show_list_replies? && ListAccount.where(list_id: list.id, account_id: status.in_reply_to_account_id).exists?) - return false if should_filter - end - - return false unless add_to_feed(:list, list.id, status, list.account.user&.aggregates_reblogs?) + return false if filter_from_list?(status, list) || !add_to_feed(:list, list.id, status, list.account.user&.aggregates_reblogs?) trim(:list, list.id) PushUpdateWorker.perform_async(list.account_id, status.id, "timeline:list:#{list.id}") if push_update_required?("timeline:list:#{list.id}") true end + # Remove a status from a list feed and send a streaming API update + # @param [List] list + # @param [Status] status + # @return [Boolean] def unpush_from_list(list, status) return false unless remove_from_feed(:list, list.id, status, list.account.user&.aggregates_reblogs?) @@ -68,36 +96,39 @@ class FeedManager true end - def trim(type, account_id) - timeline_key = key(type, account_id) - reblog_key = key(type, account_id, 'reblogs') + # Fill a home feed with an account's statuses + # @param [Account] from_account + # @param [Account] into_account + # @return [void] + def merge_into_home(from_account, into_account) + timeline_key = key(:home, into_account.id) + aggregate = into_account.user&.aggregates_reblogs? + query = from_account.statuses.where(visibility: [:public, :unlisted, :private]).includes(:preloadable_poll, reblog: :account).limit(FeedManager::MAX_ITEMS / 4) - # Remove any items past the MAX_ITEMS'th entry in our feed - redis.zremrangebyrank(timeline_key, 0, -(FeedManager::MAX_ITEMS + 1)) + if redis.zcard(timeline_key) >= FeedManager::MAX_ITEMS / 4 + oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true).first.last.to_i + query = query.where('id > ?', oldest_home_score) + end - # Get the score of the REBLOG_FALLOFF'th item in our feed, and stop - # tracking anything after it for deduplication purposes. - falloff_rank = FeedManager::REBLOG_FALLOFF - falloff_range = redis.zrevrange(timeline_key, falloff_rank, falloff_rank, with_scores: true) - falloff_score = falloff_range&.first&.last&.to_i + statuses = query.to_a + crutches = build_crutches(into_account.id, statuses) - return if falloff_score.nil? + statuses.each do |status| + next if filter_from_home?(status, into_account.id, crutches) - # Get any reblogs we might have to clean up after. - redis.zrangebyscore(reblog_key, 0, falloff_score).each do |reblogged_id| - # Remove it from the set of reblogs we're tracking *first* to avoid races. - redis.zrem(reblog_key, reblogged_id) - # Just drop any set we might have created to track additional reblogs. - # This means that if this reblog is deleted, we won't automatically insert - # another reblog, but also that any new reblog can be inserted into the - # feed. - redis.del(key(type, account_id, "reblogs:#{reblogged_id}")) + add_to_feed(:home, into_account.id, status, aggregate) end + + trim(:home, into_account.id) end - def merge_into_timeline(from_account, into_account) - timeline_key = key(:home, into_account.id) - aggregate = into_account.user&.aggregates_reblogs? + # Fill a list feed with an account's statuses + # @param [Account] from_account + # @param [List] list + # @return [void] + def merge_into_list(from_account, list) + timeline_key = key(:list, list.id) + aggregate = list.account.user&.aggregates_reblogs? query = from_account.statuses.where(visibility: [:public, :unlisted, :private]).includes(:preloadable_poll, reblog: :account).limit(FeedManager::MAX_ITEMS / 4) if redis.zcard(timeline_key) >= FeedManager::MAX_ITEMS / 4 @@ -106,18 +137,22 @@ class FeedManager end statuses = query.to_a - crutches = build_crutches(into_account.id, statuses) + crutches = build_crutches(list.account_id, statuses) statuses.each do |status| - next if filter_from_home?(status, into_account.id, crutches) + next if filter_from_home?(status, list.account_id, crutches) || filter_from_list?(status, list) - add_to_feed(:home, into_account.id, status, aggregate) + add_to_feed(:list, list.id, status, aggregate) end - trim(:home, into_account.id) + trim(:list, list.id) end - def unmerge_from_timeline(from_account, into_account) + # Remove an account's statuses from a home feed + # @param [Account] from_account + # @param [Account] into_account + # @return [void] + def unmerge_from_home(from_account, into_account) timeline_key = key(:home, into_account.id) oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true)&.first&.last&.to_i || 0 @@ -126,14 +161,31 @@ class FeedManager end end - def clear_from_timeline(account, target_account) - # Clear from timeline all statuses from or mentionning target_account + # Remove an account's statuses from a list feed + # @param [Account] from_account + # @param [List] list + # @return [void] + def unmerge_from_list(from_account, list) + timeline_key = key(:list, list.id) + oldest_list_score = redis.zrange(timeline_key, 0, 0, with_scores: true)&.first&.last&.to_i || 0 + + from_account.statuses.select('id, reblog_of_id').where('id > ?', oldest_list_score).reorder(nil).find_each do |status| + remove_from_feed(:list, list.id, status, list.account.user&.aggregates_reblogs?) + end + end + + # Clear all statuses from or mentioning target_account from a home feed + # @param [Account] account + # @param [Account] target_account + # @return [void] + def clear_from_home(account, target_account) timeline_key = key(:home, account.id) timeline_status_ids = redis.zrange(timeline_key, 0, -1) statuses = Status.where(id: timeline_status_ids).select(:id, :reblog_of_id, :account_id).to_a reblogged_ids = Status.where(id: statuses.map(&:reblog_of_id).compact, account: target_account).pluck(:id) with_mentions_ids = Mention.active.where(status_id: statuses.flat_map { |s| [s.id, s.reblog_of_id] }.compact, account: target_account).pluck(:status_id) - target_statuses = statuses.filter do |status| + + target_statuses = statuses.select do |status| status.account_id == target_account.id || reblogged_ids.include?(status.reblog_of_id) || with_mentions_ids.include?(status.id) || with_mentions_ids.include?(status.reblog_of_id) end @@ -142,7 +194,10 @@ class FeedManager end end - def populate_feed(account) + # Populate home feed of account from scratch + # @param [Account] account + # @return [void] + def populate_home(account) limit = FeedManager::MAX_ITEMS / 2 aggregate = account.user&.aggregates_reblogs? timeline_key = key(:home, account.id) @@ -177,15 +232,59 @@ class FeedManager private - def push_update_required?(timeline_id) - redis.exists?("subscribed:#{timeline_id}") + # Trim a feed to maximum size by removing older items + # @param [Symbol] type + # @param [Integer] timeline_id + # @return [void] + def trim(type, timeline_id) + timeline_key = key(type, timeline_id) + reblog_key = key(type, timeline_id, 'reblogs') + + # Remove any items past the MAX_ITEMS'th entry in our feed + redis.zremrangebyrank(timeline_key, 0, -(FeedManager::MAX_ITEMS + 1)) + + # Get the score of the REBLOG_FALLOFF'th item in our feed, and stop + # tracking anything after it for deduplication purposes. + falloff_rank = FeedManager::REBLOG_FALLOFF + falloff_range = redis.zrevrange(timeline_key, falloff_rank, falloff_rank, with_scores: true) + falloff_score = falloff_range&.first&.last&.to_i + + return if falloff_score.nil? + + # Get any reblogs we might have to clean up after. + redis.zrangebyscore(reblog_key, 0, falloff_score).each do |reblogged_id| + # Remove it from the set of reblogs we're tracking *first* to avoid races. + redis.zrem(reblog_key, reblogged_id) + # Just drop any set we might have created to track additional reblogs. + # This means that if this reblog is deleted, we won't automatically insert + # another reblog, but also that any new reblog can be inserted into the + # feed. + redis.del(key(type, timeline_id, "reblogs:#{reblogged_id}")) + end end + # Check if there is a streaming API client connected + # for the given feed + # @param [String] timeline_key + # @return [Boolean] + def push_update_required?(timeline_key) + redis.exists?("subscribed:#{timeline_key}") + end + + # Check if the account is blocking or muting any of the given accounts + # @param [Integer] receiver_id + # @param [Array] account_ids + # @param [Symbol] context def blocks_or_mutes?(receiver_id, account_ids, context) Block.where(account_id: receiver_id, target_account_id: account_ids).any? || (context == :home ? Mute.where(account_id: receiver_id, target_account_id: account_ids).any? : Mute.where(account_id: receiver_id, target_account_id: account_ids, hide_notifications: true).any?) end + # Check if status should not be added to the home feed + # @param [Status] status + # @param [Integer] receiver_id + # @param [Hash] crutches + # @return [Boolean] def filter_from_home?(status, receiver_id, crutches) return false if receiver_id == status.account_id return true if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?) @@ -218,6 +317,11 @@ class FeedManager false end + # Check if status should not be added to the mentions feed + # @see NotifyService + # @param [Status] status + # @param [Integer] receiver_id + # @return [Boolean] def filter_from_mentions?(status, receiver_id) return true if receiver_id == status.account_id return true if phrase_filtered?(status, receiver_id, :notifications) @@ -234,6 +338,27 @@ class FeedManager should_filter end + # Check if status should not be added to the list feed + # @param [Status] status + # @param [List] list + # @return [Boolean] + def filter_from_list?(status, list) + if status.reply? && status.in_reply_to_account_id != status.account_id + should_filter = status.in_reply_to_account_id != list.account_id + should_filter &&= !list.show_all_replies? + should_filter &&= !(list.show_list_replies? && ListAccount.where(list_id: list.id, account_id: status.in_reply_to_account_id).exists?) + + return !!should_filter + end + + false + end + + # Check if the status hits a phrase filter + # @param [Status] status + # @param [Integer] receiver_id + # @param [Symbol] context + # @return [Boolean] def phrase_filtered?(status, receiver_id, context) active_filters = Rails.cache.fetch("filters:#{receiver_id}") { CustomFilter.where(account_id: receiver_id).active_irreversible.to_a }.to_a @@ -269,6 +394,11 @@ class FeedManager # added, and false if it was not added to the feed. Note that this is # an internal helper: callers must call trim or push updates if # either action is appropriate. + # @param [Symbol] timeline_type + # @param [Integer] account_id + # @param [Status] status + # @param [Boolean] aggregate_reblogs + # @return [Boolean] def add_to_feed(timeline_type, account_id, status, aggregate_reblogs = true) timeline_key = key(timeline_type, account_id) reblog_key = key(timeline_type, account_id, 'reblogs') @@ -312,6 +442,11 @@ class FeedManager # with reblogs, and returning true if a status was removed. As with # `add_to_feed`, this does not trigger push updates, so callers must # do so if appropriate. + # @param [Symbol] timeline_type + # @param [Integer] account_id + # @param [Status] status + # @param [Boolean] aggregate_reblogs + # @return [Boolean] def remove_from_feed(timeline_type, account_id, status, aggregate_reblogs = true) timeline_key = key(timeline_type, account_id) reblog_key = key(timeline_type, account_id, 'reblogs') @@ -346,6 +481,11 @@ class FeedManager redis.zrem(timeline_key, status.id) end + # Pre-fetch various objects and relationships for given statuses that + # are going to be checked by the filtering methods + # @param [Integer] receiver_id + # @param [Array] statuses + # @return [Hash] def build_crutches(receiver_id, statuses) crutches = {} diff --git a/app/services/after_block_service.rb b/app/services/after_block_service.rb index 2a0e10a79..314919df8 100644 --- a/app/services/after_block_service.rb +++ b/app/services/after_block_service.rb @@ -13,7 +13,7 @@ class AfterBlockService < BaseService private def clear_home_feed! - FeedManager.instance.clear_from_timeline(@account, @target_account) + FeedManager.instance.clear_from_home(@account, @target_account) end def clear_conversations! diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index abd676494..e4ca10eb1 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -13,15 +13,13 @@ class NotifyService < BaseService push_to_conversation! if direct_message? send_email! if email_enabled? rescue ActiveRecord::RecordInvalid - # rubocop:disable Style/RedundantReturn - return - # rubocop:enable Style/RedundantReturn + nil end private def blocked_mention? - FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient.id) + FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient) end def blocked_favourite? diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb index 076dedaca..61f573534 100644 --- a/app/services/precompute_feed_service.rb +++ b/app/services/precompute_feed_service.rb @@ -2,7 +2,7 @@ class PrecomputeFeedService < BaseService def call(account) - FeedManager.instance.populate_feed(account) + FeedManager.instance.populate_home(account) ensure Redis.current.del("account:#{account.id}:regeneration") end diff --git a/app/workers/feed_insert_worker.rb b/app/workers/feed_insert_worker.rb index 1ae3c877b..633ec91bd 100644 --- a/app/workers/feed_insert_worker.rb +++ b/app/workers/feed_insert_worker.rb @@ -27,9 +27,12 @@ class FeedInsertWorker end def feed_filtered? - # Note: Lists are a variation of home, so the filtering rules - # of home apply to both - FeedManager.instance.filter?(:home, @status, @follower.id) + case @type + when :home + FeedManager.instance.filter?(:home, @status, @follower) + when :list + FeedManager.instance.filter?(:list, @status, @list) + end end def perform_push diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb index d745cb99c..74ef7d4da 100644 --- a/app/workers/merge_worker.rb +++ b/app/workers/merge_worker.rb @@ -6,6 +6,8 @@ class MergeWorker sidekiq_options queue: 'pull' def perform(from_account_id, into_account_id) - FeedManager.instance.merge_into_timeline(Account.find(from_account_id), Account.find(into_account_id)) + FeedManager.instance.merge_into_home(Account.find(from_account_id), Account.find(into_account_id)) + rescue ActiveRecord::RecordNotFound + true end end diff --git a/app/workers/mute_worker.rb b/app/workers/mute_worker.rb index 7bf0923a5..c74f657cb 100644 --- a/app/workers/mute_worker.rb +++ b/app/workers/mute_worker.rb @@ -4,9 +4,8 @@ class MuteWorker include Sidekiq::Worker def perform(account_id, target_account_id) - FeedManager.instance.clear_from_timeline( - Account.find(account_id), - Account.find(target_account_id) - ) + FeedManager.instance.clear_from_home(Account.find(account_id), Account.find(target_account_id)) + rescue ActiveRecord::RecordNotFound + true end end diff --git a/app/workers/unmerge_worker.rb b/app/workers/unmerge_worker.rb index ea6aacebf..1a23faae5 100644 --- a/app/workers/unmerge_worker.rb +++ b/app/workers/unmerge_worker.rb @@ -6,6 +6,8 @@ class UnmergeWorker sidekiq_options queue: 'pull' def perform(from_account_id, into_account_id) - FeedManager.instance.unmerge_from_timeline(Account.find(from_account_id), Account.find(into_account_id)) + FeedManager.instance.unmerge_from_home(Account.find(from_account_id), Account.find(into_account_id)) + rescue ActiveRecord::RecordNotFound + true end end diff --git a/spec/lib/feed_manager_spec.rb b/spec/lib/feed_manager_spec.rb index d86dd7993..d9c17470f 100644 --- a/spec/lib/feed_manager_spec.rb +++ b/spec/lib/feed_manager_spec.rb @@ -29,14 +29,14 @@ RSpec.describe FeedManager do it 'returns false for followee\'s status' do status = Fabricate(:status, text: 'Hello world', account: alice) bob.follow!(alice) - expect(FeedManager.instance.filter?(:home, status, bob.id)).to be false + expect(FeedManager.instance.filter?(:home, status, bob)).to be false end it 'returns false for reblog by followee' do status = Fabricate(:status, text: 'Hello world', account: jeff) reblog = Fabricate(:status, reblog: status, account: alice) bob.follow!(alice) - expect(FeedManager.instance.filter?(:home, reblog, bob.id)).to be false + expect(FeedManager.instance.filter?(:home, reblog, bob)).to be false end it 'returns true for reblog by followee of blocked account' do @@ -44,7 +44,7 @@ RSpec.describe FeedManager do reblog = Fabricate(:status, reblog: status, account: alice) bob.follow!(alice) bob.block!(jeff) - expect(FeedManager.instance.filter?(:home, reblog, bob.id)).to be true + expect(FeedManager.instance.filter?(:home, reblog, bob)).to be true end it 'returns true for reblog by followee of muted account' do @@ -52,7 +52,7 @@ RSpec.describe FeedManager do reblog = Fabricate(:status, reblog: status, account: alice) bob.follow!(alice) bob.mute!(jeff) - expect(FeedManager.instance.filter?(:home, reblog, bob.id)).to be true + expect(FeedManager.instance.filter?(:home, reblog, bob)).to be true end it 'returns true for reblog by followee of someone who is blocking recipient' do @@ -60,14 +60,14 @@ RSpec.describe FeedManager do reblog = Fabricate(:status, reblog: status, account: alice) bob.follow!(alice) jeff.block!(bob) - expect(FeedManager.instance.filter?(:home, reblog, bob.id)).to be true + expect(FeedManager.instance.filter?(:home, reblog, bob)).to be true end it 'returns true for reblog from account with reblogs disabled' do status = Fabricate(:status, text: 'Hello world', account: jeff) reblog = Fabricate(:status, reblog: status, account: alice) bob.follow!(alice, reblogs: false) - expect(FeedManager.instance.filter?(:home, reblog, bob.id)).to be true + expect(FeedManager.instance.filter?(:home, reblog, bob)).to be true end it 'returns false for reply by followee to another followee' do @@ -75,48 +75,48 @@ RSpec.describe FeedManager do reply = Fabricate(:status, text: 'Nay', thread: status, account: alice) bob.follow!(alice) bob.follow!(jeff) - expect(FeedManager.instance.filter?(:home, reply, bob.id)).to be false + expect(FeedManager.instance.filter?(:home, reply, bob)).to be false end it 'returns false for reply by followee to recipient' do status = Fabricate(:status, text: 'Hello world', account: bob) reply = Fabricate(:status, text: 'Nay', thread: status, account: alice) bob.follow!(alice) - expect(FeedManager.instance.filter?(:home, reply, bob.id)).to be false + expect(FeedManager.instance.filter?(:home, reply, bob)).to be false end it 'returns false for reply by followee to self' do status = Fabricate(:status, text: 'Hello world', account: alice) reply = Fabricate(:status, text: 'Nay', thread: status, account: alice) bob.follow!(alice) - expect(FeedManager.instance.filter?(:home, reply, bob.id)).to be false + expect(FeedManager.instance.filter?(:home, reply, bob)).to be false end it 'returns true for reply by followee to non-followed account' do status = Fabricate(:status, text: 'Hello world', account: jeff) reply = Fabricate(:status, text: 'Nay', thread: status, account: alice) bob.follow!(alice) - expect(FeedManager.instance.filter?(:home, reply, bob.id)).to be true + expect(FeedManager.instance.filter?(:home, reply, bob)).to be true end it 'returns true for the second reply by followee to a non-federated status' do reply = Fabricate(:status, text: 'Reply 1', reply: true, account: alice) second_reply = Fabricate(:status, text: 'Reply 2', thread: reply, account: alice) bob.follow!(alice) - expect(FeedManager.instance.filter?(:home, second_reply, bob.id)).to be true + expect(FeedManager.instance.filter?(:home, second_reply, bob)).to be true end it 'returns false for status by followee mentioning another account' do bob.follow!(alice) status = PostStatusService.new.call(alice, text: 'Hey @jeff') - expect(FeedManager.instance.filter?(:home, status, bob.id)).to be false + expect(FeedManager.instance.filter?(:home, status, bob)).to be false end it 'returns true for status by followee mentioning blocked account' do bob.block!(jeff) bob.follow!(alice) status = PostStatusService.new.call(alice, text: 'Hey @jeff') - expect(FeedManager.instance.filter?(:home, status, bob.id)).to be true + expect(FeedManager.instance.filter?(:home, status, bob)).to be true end it 'returns true for reblog of a personally blocked domain' do @@ -124,7 +124,7 @@ RSpec.describe FeedManager do alice.follow!(jeff) status = Fabricate(:status, text: 'Hello world', account: bob) reblog = Fabricate(:status, reblog: status, account: jeff) - expect(FeedManager.instance.filter?(:home, reblog, alice.id)).to be true + expect(FeedManager.instance.filter?(:home, reblog, alice)).to be true end context 'for irreversibly muted phrases' do @@ -132,7 +132,7 @@ RSpec.describe FeedManager do alice.custom_filters.create!(phrase: 'bob', context: %w(home), irreversible: true) alice.follow!(jeff) status = Fabricate(:status, text: 'bobcats', account: jeff) - expect(FeedManager.instance.filter?(:home, status, alice.id)).to be_falsy + expect(FeedManager.instance.filter?(:home, status, alice)).to be_falsy end it 'returns true if phrase is contained' do @@ -140,14 +140,14 @@ RSpec.describe FeedManager do alice.custom_filters.create!(phrase: 'pop tarts', context: %w(home), irreversible: true) alice.follow!(jeff) status = Fabricate(:status, text: 'i sure like POP TARts', account: jeff) - expect(FeedManager.instance.filter?(:home, status, alice.id)).to be true + expect(FeedManager.instance.filter?(:home, status, alice)).to be true end it 'matches substrings if whole_word is false' do alice.custom_filters.create!(phrase: 'take', context: %w(home), whole_word: false, irreversible: true) alice.follow!(jeff) status = Fabricate(:status, text: 'shiitake', account: jeff) - expect(FeedManager.instance.filter?(:home, status, alice.id)).to be true + expect(FeedManager.instance.filter?(:home, status, alice)).to be true end it 'returns true if phrase is contained in a poll option' do @@ -155,7 +155,7 @@ RSpec.describe FeedManager do alice.custom_filters.create!(phrase: 'pop tarts', context: %w(home), irreversible: true) alice.follow!(jeff) status = Fabricate(:status, text: 'what do you prefer', poll: Fabricate(:poll, options: %w(farts POP TARts)), account: jeff) - expect(FeedManager.instance.filter?(:home, status, alice.id)).to be true + expect(FeedManager.instance.filter?(:home, status, alice)).to be true end end end @@ -164,27 +164,27 @@ RSpec.describe FeedManager do it 'returns true for status that mentions blocked account' do bob.block!(jeff) status = PostStatusService.new.call(alice, text: 'Hey @jeff') - expect(FeedManager.instance.filter?(:mentions, status, bob.id)).to be true + expect(FeedManager.instance.filter?(:mentions, status, bob)).to be true end it 'returns true for status that replies to a blocked account' do status = Fabricate(:status, text: 'Hello world', account: jeff) reply = Fabricate(:status, text: 'Nay', thread: status, account: alice) bob.block!(jeff) - expect(FeedManager.instance.filter?(:mentions, reply, bob.id)).to be true + expect(FeedManager.instance.filter?(:mentions, reply, bob)).to be true end it 'returns true for status by silenced account who recipient is not following' do status = Fabricate(:status, text: 'Hello world', account: alice) alice.silence! - expect(FeedManager.instance.filter?(:mentions, status, bob.id)).to be true + expect(FeedManager.instance.filter?(:mentions, status, bob)).to be true end it 'returns false for status by followed silenced account' do status = Fabricate(:status, text: 'Hello world', account: alice) alice.silence! bob.follow!(alice) - expect(FeedManager.instance.filter?(:mentions, status, bob.id)).to be false + expect(FeedManager.instance.filter?(:mentions, status, bob)).to be false end end end @@ -414,52 +414,20 @@ RSpec.describe FeedManager do end end - describe '#merge_into_timeline' do + describe '#merge_into_home' do it "does not push source account's statuses whose reblogs are already inserted" do account = Fabricate(:account, id: 0) reblog = Fabricate(:status) status = Fabricate(:status, reblog: reblog) FeedManager.instance.push_to_home(account, status) - FeedManager.instance.merge_into_timeline(account, reblog.account) + FeedManager.instance.merge_into_home(account, reblog.account) expect(Redis.current.zscore("feed:home:0", reblog.id)).to eq nil end end - describe '#trim' do - let(:receiver) { Fabricate(:account) } - - it 'cleans up reblog tracking keys' do - reblogged = Fabricate(:status) - status = Fabricate(:status, reblog: reblogged) - another_status = Fabricate(:status, reblog: reblogged) - reblogs_key = FeedManager.instance.key('home', receiver.id, 'reblogs') - reblog_set_key = FeedManager.instance.key('home', receiver.id, "reblogs:#{reblogged.id}") - - FeedManager.instance.push_to_home(receiver, status) - FeedManager.instance.push_to_home(receiver, another_status) - - # We should have a tracking set and an entry in reblogs. - expect(Redis.current.exists?(reblog_set_key)).to be true - expect(Redis.current.zrange(reblogs_key, 0, -1)).to eq [reblogged.id.to_s] - - # Push everything past the reblog falloff. - FeedManager::REBLOG_FALLOFF.times do - FeedManager.instance.push_to_home(receiver, Fabricate(:status)) - end - - # `trim` should be called automatically, but do it anyway, as - # we're testing `trim`, not side effects of `push`. - FeedManager.instance.trim('home', receiver.id) - - # We should not have any reblog tracking data. - expect(Redis.current.exists?(reblog_set_key)).to be false - expect(Redis.current.zrange(reblogs_key, 0, -1)).to be_empty - end - end - - describe '#unpush' do + describe '#unpush_from_home' do let(:receiver) { Fabricate(:account) } it 'leaves a reblogged status if original was on feed' do @@ -525,7 +493,7 @@ RSpec.describe FeedManager do end end - describe '#clear_from_timeline' do + describe '#clear_from_home' do let(:account) { Fabricate(:account) } let(:followed_account) { Fabricate(:account) } let(:target_account) { Fabricate(:account) } @@ -543,8 +511,8 @@ RSpec.describe FeedManager do end end - it 'correctly cleans the timeline' do - FeedManager.instance.clear_from_timeline(account, target_account) + it 'correctly cleans the home timeline' do + FeedManager.instance.clear_from_home(account, target_account) expect(Redis.current.zrange("feed:home:#{account.id}", 0, -1)).to eq [status_1.id.to_s, status_7.id.to_s] end