Compare commits

...

5 Commits

Author SHA1 Message Date
Matt Jankowski
b3b3b57891
Merge 12e62e3e1d into 74fc4dbacf 2025-07-15 17:05:58 +00:00
diondiondion
74fc4dbacf
refactor: Only remove pointer-events when necessary (#35390)
Some checks failed
Check i18n / check-i18n (push) Waiting to run
Chromatic / Run Chromatic (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
CSS Linting / lint (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Crowdin / Upload translations / upload-translations (push) Has been cancelled
Haml Linting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
2025-07-15 15:57:31 +00:00
Matt Jankowski
12e62e3e1d Extract method for cache key calc 2025-07-15 09:01:03 -04:00
Matt Jankowski
c4d3d740aa Extract RecommendationMaintenance concern 2025-07-15 09:01:02 -04:00
Matt Jankowski
94a71efc5e Add coverage for follow recommendation cache maintenance 2025-07-15 09:00:28 -04:00
15 changed files with 60 additions and 49 deletions

View File

@ -2848,7 +2848,6 @@ a.account__display-name {
&__pane {
height: 100%;
overflow: hidden;
pointer-events: none;
display: flex;
justify-content: flex-end;
min-width: 285px;
@ -2860,7 +2859,6 @@ a.account__display-name {
&__inner {
position: fixed;
width: 285px;
pointer-events: auto;
height: 100%;
}
}

View File

@ -14,12 +14,12 @@
class AccountDomainBlock < ApplicationRecord
include Paginable
include DomainNormalizable
include RecommendationMaintenance
belongs_to :account
validates :domain, presence: true, uniqueness: { scope: :account_id }, domain: true
after_commit :invalidate_domain_blocking_cache
after_commit :invalidate_follow_recommendations_cache
private
@ -27,8 +27,4 @@ class AccountDomainBlock < ApplicationRecord
Rails.cache.delete("exclude_domains_for:#{account_id}")
Rails.cache.delete(['exclude_domains', account_id, domain])
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View File

@ -15,6 +15,7 @@
class Block < ApplicationRecord
include Paginable
include RelationshipCacheable
include RecommendationMaintenance
belongs_to :account
belongs_to :target_account, class_name: 'Account'
@ -27,7 +28,6 @@ class Block < ApplicationRecord
before_validation :set_uri, only: :create
after_commit :invalidate_blocking_cache
after_commit :invalidate_follow_recommendations_cache
private
@ -36,10 +36,6 @@ class Block < ApplicationRecord
Rails.cache.delete("exclude_account_ids_for:#{target_account_id}")
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
def set_uri
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
end

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
module RecommendationMaintenance
extend ActiveSupport::Concern
FOLLOW_RECOMMENDATIONS_SCOPE = 'follow_recommendations'
included do
after_commit :invalidate_follow_recommendations_cache
end
private
def invalidate_follow_recommendations_cache
Rails.cache.delete(follow_recommendations_cache_key)
end
def follow_recommendations_cache_key
[FOLLOW_RECOMMENDATIONS_SCOPE, account_id].join('/')
end
end

View File

@ -20,6 +20,7 @@ class Follow < ApplicationRecord
include RelationshipCacheable
include RateLimitable
include FollowLimitable
include RecommendationMaintenance
rate_limit by: :account, family: :follows
@ -46,7 +47,6 @@ class Follow < ApplicationRecord
after_create :increment_cache_counters
after_destroy :remove_endorsements
after_destroy :decrement_cache_counters
after_commit :invalidate_follow_recommendations_cache
after_commit :invalidate_hash_cache
private
@ -74,8 +74,4 @@ class Follow < ApplicationRecord
Rails.cache.delete("followers_hash:#{target_account_id}:#{account.synchronization_uri_prefix}")
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View File

@ -11,16 +11,10 @@
# updated_at :datetime not null
#
class FollowRecommendationMute < ApplicationRecord
include RecommendationMaintenance
belongs_to :account
belongs_to :target_account, class_name: 'Account'
validates :target_account_id, uniqueness: { scope: :account_id }
after_commit :invalidate_follow_recommendations_cache
private
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View File

@ -20,6 +20,7 @@ class FollowRequest < ApplicationRecord
include RelationshipCacheable
include RateLimitable
include FollowLimitable
include RecommendationMaintenance
rate_limit by: :account, family: :follows
@ -52,15 +53,10 @@ class FollowRequest < ApplicationRecord
end
before_validation :set_uri, only: :create
after_commit :invalidate_follow_recommendations_cache
private
def set_uri
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View File

@ -17,6 +17,7 @@ class Mute < ApplicationRecord
include Paginable
include RelationshipCacheable
include Expireable
include RecommendationMaintenance
belongs_to :account
belongs_to :target_account, class_name: 'Account'
@ -24,15 +25,10 @@ class Mute < ApplicationRecord
validates :account_id, uniqueness: { scope: :target_account_id }
after_commit :invalidate_blocking_cache
after_commit :invalidate_follow_recommendations_cache
private
def invalidate_blocking_cache
Rails.cache.delete("exclude_account_ids_for:#{account_id}")
end
def invalidate_follow_recommendations_cache
Rails.cache.delete("follow_recommendations/#{account_id}")
end
end

View File

@ -5,6 +5,8 @@ require 'rails_helper'
RSpec.describe AccountDomainBlock do
let(:account) { Fabricate(:account) }
it_behaves_like 'Recommendation Maintenance'
it 'removes blocking cache after creation' do
Rails.cache.write("exclude_domains_for:#{account.id}", 'a.domain.already.blocked')

View File

@ -3,6 +3,8 @@
require 'rails_helper'
RSpec.describe Block do
it_behaves_like 'Recommendation Maintenance'
describe 'Associations' do
it { is_expected.to belong_to(:account).required }
it { is_expected.to belong_to(:target_account).required }

View File

@ -3,6 +3,8 @@
require 'rails_helper'
RSpec.describe FollowRecommendationMute do
it_behaves_like 'Recommendation Maintenance'
describe 'Associations' do
it { is_expected.to belong_to(:account) }
it { is_expected.to belong_to(:target_account).class_name('Account') }
@ -13,18 +15,4 @@ RSpec.describe FollowRecommendationMute do
it { is_expected.to validate_uniqueness_of(:target_account_id).scoped_to(:account_id) }
end
describe 'Callbacks' do
describe 'Maintaining the recommendation cache' do
let(:account) { Fabricate :account }
let(:cache_key) { "follow_recommendations/#{account.id}" }
before { Rails.cache.write(cache_key, 123) }
it 'purges on save' do
expect { Fabricate :follow_recommendation_mute, account: account }
.to(change { Rails.cache.exist?(cache_key) }.from(true).to(false))
end
end
end
end

View File

@ -3,6 +3,8 @@
require 'rails_helper'
RSpec.describe FollowRequest do
it_behaves_like 'Recommendation Maintenance'
describe '#authorize!' do
let!(:follow_request) { Fabricate(:follow_request, account: account, target_account: target_account) }
let(:account) { Fabricate(:account) }

View File

@ -3,6 +3,8 @@
require 'rails_helper'
RSpec.describe Follow do
it_behaves_like 'Recommendation Maintenance'
describe 'Associations' do
it { is_expected.to belong_to(:account).required }
it { is_expected.to belong_to(:target_account).required }

View File

@ -4,6 +4,7 @@ require 'rails_helper'
RSpec.describe Mute do
it_behaves_like 'Expireable'
it_behaves_like 'Recommendation Maintenance'
describe 'Associations' do
it { is_expected.to belong_to(:account).required }

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
RSpec.shared_examples 'Recommendation Maintenance' do
describe 'Callbacks' do
describe 'Maintaining the cache' do
let(:account) { Fabricate :account }
let(:cache_key) { "follow_recommendations/#{account.id}" }
before { Rails.cache.write(cache_key, 123) }
it 'purges the cache value when record saved' do
expect { Fabricate factory_name, account: account }
.to(change { Rails.cache.exist?(cache_key) }.from(true).to(false))
end
def factory_name
described_class.name.underscore.to_sym
end
end
end
end