Extract Account::Mappings concern from "interactions" (#35119)

This commit is contained in:
Matt Jankowski 2025-06-23 08:02:14 -04:00 committed by GitHub
parent b9b1500fc5
commit b08ccaa5b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 187 additions and 170 deletions

View File

@ -89,6 +89,7 @@ class Account < ApplicationRecord
include Account::FinderConcern include Account::FinderConcern
include Account::Header include Account::Header
include Account::Interactions include Account::Interactions
include Account::Mappings
include Account::Merging include Account::Merging
include Account::Search include Account::Search
include Account::Sensitizes include Account::Sensitizes

View File

@ -3,74 +3,6 @@
module Account::Interactions module Account::Interactions
extend ActiveSupport::Concern extend ActiveSupport::Concern
class_methods do
def following_map(target_account_ids, account_id)
Follow.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |follow, mapping|
mapping[follow.target_account_id] = {
reblogs: follow.show_reblogs?,
notify: follow.notify?,
languages: follow.languages,
}
end
end
def followed_by_map(target_account_ids, account_id)
follow_mapping(Follow.where(account_id: target_account_ids, target_account_id: account_id), :account_id)
end
def blocking_map(target_account_ids, account_id)
follow_mapping(Block.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
end
def blocked_by_map(target_account_ids, account_id)
follow_mapping(Block.where(account_id: target_account_ids, target_account_id: account_id), :account_id)
end
def muting_map(target_account_ids, account_id)
Mute.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |mute, mapping|
mapping[mute.target_account_id] = {
notifications: mute.hide_notifications?,
}
end
end
def requested_map(target_account_ids, account_id)
FollowRequest.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |follow_request, mapping|
mapping[follow_request.target_account_id] = {
reblogs: follow_request.show_reblogs?,
notify: follow_request.notify?,
languages: follow_request.languages,
}
end
end
def requested_by_map(target_account_ids, account_id)
follow_mapping(FollowRequest.where(account_id: target_account_ids, target_account_id: account_id), :account_id)
end
def endorsed_map(target_account_ids, account_id)
follow_mapping(AccountPin.where(account_id: account_id, target_account_id: target_account_ids), :target_account_id)
end
def account_note_map(target_account_ids, account_id)
AccountNote.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |note, mapping|
mapping[note.target_account_id] = {
comment: note.comment,
}
end
end
def domain_blocking_map_by_domain(target_domains, account_id)
follow_mapping(AccountDomainBlock.where(account_id: account_id, domain: target_domains), :domain)
end
private
def follow_mapping(query, field)
query.pluck(field).index_with(true)
end
end
included do included do
# Follow relations # Follow relations
has_many :follow_requests, dependent: :destroy has_many :follow_requests, dependent: :destroy
@ -290,21 +222,6 @@ module Account::Interactions
end end
end end
def relations_map(account_ids, domains = nil, **options)
relations = {
blocked_by: Account.blocked_by_map(account_ids, id),
following: Account.following_map(account_ids, id),
}
return relations if options[:skip_blocking_and_muting]
relations.merge!({
blocking: Account.blocking_map(account_ids, id),
muting: Account.muting_map(account_ids, id),
domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, id),
})
end
def normalized_domain(domain) def normalized_domain(domain)
TagManager.instance.normalize_domain(domain) TagManager.instance.normalize_domain(domain)
end end

View File

@ -0,0 +1,108 @@
# frozen_string_literal: true
module Account::Mappings
extend ActiveSupport::Concern
class_methods do
def following_map(target_account_ids, account_id)
Follow.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |follow, mapping|
mapping[follow.target_account_id] = {
reblogs: follow.show_reblogs?,
notify: follow.notify?,
languages: follow.languages,
}
end
end
def followed_by_map(target_account_ids, account_id)
build_mapping(
Follow.where(account_id: target_account_ids, target_account_id: account_id),
:account_id
)
end
def blocking_map(target_account_ids, account_id)
build_mapping(
Block.where(target_account_id: target_account_ids, account_id: account_id),
:target_account_id
)
end
def blocked_by_map(target_account_ids, account_id)
build_mapping(
Block.where(account_id: target_account_ids, target_account_id: account_id),
:account_id
)
end
def muting_map(target_account_ids, account_id)
Mute.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |mute, mapping|
mapping[mute.target_account_id] = {
notifications: mute.hide_notifications?,
}
end
end
def requested_map(target_account_ids, account_id)
FollowRequest.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |follow_request, mapping|
mapping[follow_request.target_account_id] = {
reblogs: follow_request.show_reblogs?,
notify: follow_request.notify?,
languages: follow_request.languages,
}
end
end
def requested_by_map(target_account_ids, account_id)
build_mapping(
FollowRequest.where(account_id: target_account_ids, target_account_id: account_id),
:account_id
)
end
def endorsed_map(target_account_ids, account_id)
build_mapping(
AccountPin.where(account_id: account_id, target_account_id: target_account_ids),
:target_account_id
)
end
def account_note_map(target_account_ids, account_id)
AccountNote.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |note, mapping|
mapping[note.target_account_id] = {
comment: note.comment,
}
end
end
def domain_blocking_map_by_domain(target_domains, account_id)
build_mapping(
AccountDomainBlock.where(account_id: account_id, domain: target_domains),
:domain
)
end
private
def build_mapping(query, field)
query
.pluck(field)
.index_with(true)
end
end
def relations_map(account_ids, domains = nil, **options)
relations = {
blocked_by: Account.blocked_by_map(account_ids, id),
following: Account.following_map(account_ids, id),
}
return relations if options[:skip_blocking_and_muting]
relations.merge!({
blocking: Account.blocking_map(account_ids, id),
muting: Account.muting_map(account_ids, id),
domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, id),
})
end
end

View File

@ -4,94 +4,7 @@ require 'rails_helper'
RSpec.describe Account::Interactions do RSpec.describe Account::Interactions do
let(:account) { Fabricate(:account) } let(:account) { Fabricate(:account) }
let(:account_id) { account.id }
let(:account_ids) { [account_id] }
let(:target_account) { Fabricate(:account) } let(:target_account) { Fabricate(:account) }
let(:target_account_id) { target_account.id }
let(:target_account_ids) { [target_account_id] }
describe '.following_map' do
subject { Account.following_map(target_account_ids, account_id) }
context 'when Account with Follow' do
it 'returns { target_account_id => true }' do
Fabricate(:follow, account: account, target_account: target_account)
expect(subject).to eq(target_account_id => { reblogs: true, notify: false, languages: nil })
end
end
context 'when Account without Follow' do
it 'returns {}' do
expect(subject).to eq({})
end
end
end
describe '.followed_by_map' do
subject { Account.followed_by_map(target_account_ids, account_id) }
context 'when Account with Follow' do
it 'returns { target_account_id => true }' do
Fabricate(:follow, account: target_account, target_account: account)
expect(subject).to eq(target_account_id => true)
end
end
context 'when Account without Follow' do
it 'returns {}' do
expect(subject).to eq({})
end
end
end
describe '.blocking_map' do
subject { Account.blocking_map(target_account_ids, account_id) }
context 'when Account with Block' do
it 'returns { target_account_id => true }' do
Fabricate(:block, account: account, target_account: target_account)
expect(subject).to eq(target_account_id => true)
end
end
context 'when Account without Block' do
it 'returns {}' do
expect(subject).to eq({})
end
end
end
describe '.muting_map' do
subject { Account.muting_map(target_account_ids, account_id) }
context 'when Account with Mute' do
before do
Fabricate(:mute, target_account: target_account, account: account, hide_notifications: hide)
end
context 'when Mute#hide_notifications?' do
let(:hide) { true }
it 'returns { target_account_id => { notifications: true } }' do
expect(subject).to eq(target_account_id => { notifications: true })
end
end
context 'when not Mute#hide_notifications?' do
let(:hide) { false }
it 'returns { target_account_id => { notifications: false } }' do
expect(subject).to eq(target_account_id => { notifications: false })
end
end
end
context 'when Account without Mute' do
it 'returns {}' do
expect(subject).to eq({})
end
end
end
describe '#follow!' do describe '#follow!' do
it 'creates and returns Follow' do it 'creates and returns Follow' do

View File

@ -0,0 +1,78 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Account::Mappings do
let(:account) { Fabricate(:account) }
let(:account_id) { account.id }
let(:account_ids) { [account_id] }
let(:target_account) { Fabricate(:account) }
let(:target_account_id) { target_account.id }
let(:target_account_ids) { [target_account_id] }
describe '.following_map' do
subject { Account.following_map(target_account_ids, account_id) }
context 'when Account has a Follow' do
before { Fabricate(:follow, account: account, target_account: target_account) }
it { is_expected.to eq(target_account_id => { reblogs: true, notify: false, languages: nil }) }
end
context 'when Account is without Follow' do
it { is_expected.to eq({}) }
end
end
describe '.followed_by_map' do
subject { Account.followed_by_map(target_account_ids, account_id) }
context 'when Account has a Follow' do
before { Fabricate(:follow, account: target_account, target_account: account) }
it { is_expected.to eq(target_account_id => true) }
end
context 'when Account is without Follow' do
it { is_expected.to eq({}) }
end
end
describe '.blocking_map' do
subject { Account.blocking_map(target_account_ids, account_id) }
context 'when Account has a Block' do
before { Fabricate(:block, account: account, target_account: target_account) }
it { is_expected.to eq(target_account_id => true) }
end
context 'when Account is without Block' do
it { is_expected.to eq({}) }
end
end
describe '.muting_map' do
subject { Account.muting_map(target_account_ids, account_id) }
context 'when Account has a Mute' do
before { Fabricate(:mute, target_account: target_account, account: account, hide_notifications: hide) }
context 'when Mute#hide_notifications?' do
let(:hide) { true }
it { is_expected.to eq(target_account_id => { notifications: true }) }
end
context 'when not Mute#hide_notifications?' do
let(:hide) { false }
it { is_expected.to eq(target_account_id => { notifications: false }) }
end
end
context 'when Account without Mute' do
it { is_expected.to eq({}) }
end
end
end