mirror of
https://github.com/mastodon/mastodon.git
synced 2025-09-05 17:31:12 +00:00
Compare commits
2 Commits
0669e2a843
...
65775172aa
Author | SHA1 | Date | |
---|---|---|---|
![]() |
65775172aa | ||
![]() |
4fa462a9f8 |
|
@ -7,14 +7,14 @@ module Admin
|
|||
def show
|
||||
authorize :follow_recommendation, :show?
|
||||
|
||||
@form = Form::AccountBatch.new
|
||||
@form = Form::FollowRecommendationBatch.new
|
||||
@accounts = filtered_follow_recommendations.page(params[:page])
|
||||
end
|
||||
|
||||
def update
|
||||
authorize :follow_recommendation, :show?
|
||||
|
||||
@form = Form::AccountBatch.new(form_account_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||
@form = Form::FollowRecommendationBatch.new(form_follow_recommendation_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||
@form.save
|
||||
rescue ActionController::ParameterMissing
|
||||
# Do nothing
|
||||
|
@ -36,9 +36,9 @@ module Admin
|
|||
@follow_recommendation_filter ||= FollowRecommendationFilter.new(filter_params)
|
||||
end
|
||||
|
||||
def form_account_batch_params
|
||||
def form_follow_recommendation_batch_params
|
||||
params
|
||||
.expect(form_account_batch: [:action, account_ids: []])
|
||||
.expect(form_follow_recommendation_batch: [:action, account_ids: []])
|
||||
end
|
||||
|
||||
def filter_params
|
||||
|
|
|
@ -10,11 +10,11 @@ class RelationshipsController < ApplicationController
|
|||
helper_method :following_relationship?, :followed_by_relationship?, :mutual_relationship?
|
||||
|
||||
def show
|
||||
@form = Form::AccountBatch.new
|
||||
@form = Form::RelationshipBatch.new
|
||||
end
|
||||
|
||||
def update
|
||||
@form = Form::AccountBatch.new(form_account_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||
@form = Form::RelationshipBatch.new(form_relationship_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||
@form.save
|
||||
rescue ActionController::ParameterMissing
|
||||
# Do nothing
|
||||
|
@ -34,8 +34,8 @@ class RelationshipsController < ApplicationController
|
|||
@relationships = AccountRelationshipsPresenter.new(@accounts, current_user.account_id)
|
||||
end
|
||||
|
||||
def form_account_batch_params
|
||||
params.expect(form_account_batch: [:action, account_ids: []])
|
||||
def form_relationship_batch_params
|
||||
params.expect(form_relationship_batch: [:action, account_ids: []])
|
||||
end
|
||||
|
||||
def following_relationship?
|
||||
|
|
|
@ -9,22 +9,10 @@ class Form::AccountBatch < Form::BaseBatch
|
|||
|
||||
def save
|
||||
case action
|
||||
when 'follow'
|
||||
follow!
|
||||
when 'unfollow'
|
||||
unfollow!
|
||||
when 'remove_from_followers'
|
||||
remove_from_followers!
|
||||
when 'remove_domains_from_followers'
|
||||
remove_domains_from_followers!
|
||||
when 'approve'
|
||||
approve!
|
||||
when 'reject'
|
||||
reject!
|
||||
when 'suppress_follow_recommendation'
|
||||
suppress_follow_recommendation!
|
||||
when 'unsuppress_follow_recommendation'
|
||||
unsuppress_follow_recommendation!
|
||||
when 'suspend'
|
||||
suspend!
|
||||
end
|
||||
|
@ -32,36 +20,6 @@ class Form::AccountBatch < Form::BaseBatch
|
|||
|
||||
private
|
||||
|
||||
def follow!
|
||||
error = nil
|
||||
|
||||
accounts.each do |target_account|
|
||||
FollowService.new.call(current_account, target_account)
|
||||
rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound => e
|
||||
error ||= e
|
||||
end
|
||||
|
||||
raise error if error.present?
|
||||
end
|
||||
|
||||
def unfollow!
|
||||
accounts.each do |target_account|
|
||||
UnfollowService.new.call(current_account, target_account)
|
||||
end
|
||||
end
|
||||
|
||||
def remove_from_followers!
|
||||
RemoveFromFollowersService.new.call(current_account, account_ids)
|
||||
end
|
||||
|
||||
def remove_domains_from_followers!
|
||||
RemoveDomainsFromFollowersService.new.call(current_account, account_domains)
|
||||
end
|
||||
|
||||
def account_domains
|
||||
accounts.group(:domain).pluck(:domain).compact
|
||||
end
|
||||
|
||||
def accounts
|
||||
if select_all_matching?
|
||||
query
|
||||
|
@ -92,20 +50,6 @@ class Form::AccountBatch < Form::BaseBatch
|
|||
end
|
||||
end
|
||||
|
||||
def suppress_follow_recommendation!
|
||||
authorize(:follow_recommendation, :suppress?)
|
||||
|
||||
accounts.find_each do |account|
|
||||
FollowRecommendationSuppression.create(account: account)
|
||||
end
|
||||
end
|
||||
|
||||
def unsuppress_follow_recommendation!
|
||||
authorize(:follow_recommendation, :unsuppress?)
|
||||
|
||||
FollowRecommendationSuppression.where(account_id: account_ids).destroy_all
|
||||
end
|
||||
|
||||
def reject_account(account)
|
||||
authorize(account.user, :reject?)
|
||||
log_action(:reject, account.user)
|
||||
|
|
38
app/models/form/follow_recommendation_batch.rb
Normal file
38
app/models/form/follow_recommendation_batch.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Form::FollowRecommendationBatch < Form::BaseBatch
|
||||
attr_accessor :account_ids
|
||||
|
||||
def save
|
||||
case action
|
||||
when 'suppress_follow_recommendation'
|
||||
suppress!
|
||||
when 'unsuppress_follow_recommendation'
|
||||
unsuppress!
|
||||
end
|
||||
end
|
||||
|
||||
def persisted?
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def suppress!
|
||||
authorize(:follow_recommendation, :suppress?)
|
||||
|
||||
accounts.find_each do |account|
|
||||
FollowRecommendationSuppression.create(account: account)
|
||||
end
|
||||
end
|
||||
|
||||
def unsuppress!
|
||||
authorize(:follow_recommendation, :unsuppress?)
|
||||
|
||||
FollowRecommendationSuppression.where(account_id: account_ids).destroy_all
|
||||
end
|
||||
|
||||
def accounts
|
||||
Account.where(id: account_ids)
|
||||
end
|
||||
end
|
58
app/models/form/relationship_batch.rb
Normal file
58
app/models/form/relationship_batch.rb
Normal file
|
@ -0,0 +1,58 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Form::RelationshipBatch < Form::BaseBatch
|
||||
attr_accessor :account_ids
|
||||
|
||||
def save
|
||||
case action
|
||||
when 'follow'
|
||||
follow!
|
||||
when 'unfollow'
|
||||
unfollow!
|
||||
when 'remove_from_followers'
|
||||
remove_from_followers!
|
||||
when 'remove_domains_from_followers'
|
||||
remove_domains_from_followers!
|
||||
end
|
||||
end
|
||||
|
||||
def persisted?
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def follow!
|
||||
error = nil
|
||||
|
||||
accounts.each do |target_account|
|
||||
FollowService.new.call(current_account, target_account)
|
||||
rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound => e
|
||||
error ||= e
|
||||
end
|
||||
|
||||
raise error if error.present?
|
||||
end
|
||||
|
||||
def unfollow!
|
||||
accounts.each do |target_account|
|
||||
UnfollowService.new.call(current_account, target_account)
|
||||
end
|
||||
end
|
||||
|
||||
def remove_from_followers!
|
||||
RemoveFromFollowersService.new.call(current_account, account_ids)
|
||||
end
|
||||
|
||||
def remove_domains_from_followers!
|
||||
RemoveDomainsFromFollowersService.new.call(current_account, account_domains)
|
||||
end
|
||||
|
||||
def account_domains
|
||||
accounts.group(:domain).pluck(:domain).compact
|
||||
end
|
||||
|
||||
def accounts
|
||||
Account.where(id: account_ids)
|
||||
end
|
||||
end
|
|
@ -21,7 +21,7 @@
|
|||
%li= filter_link_to t('admin.accounts.moderation.active'), status: nil
|
||||
%li= filter_link_to t('admin.follow_recommendations.suppressed'), status: 'suppressed'
|
||||
|
||||
= form_with model: @form, url: admin_follow_recommendations_path, method: :patch do |f|
|
||||
= form_with model: @form, url: admin_follow_recommendations_path do |f|
|
||||
- RelationshipFilter::KEYS.each do |key|
|
||||
= hidden_field_tag key, params[key] if params[key].present?
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
%li= filter_link_to t('relationships.most_recent'), order: nil
|
||||
%li= filter_link_to t('relationships.last_active'), order: 'active'
|
||||
|
||||
= form_with model: @form, url: relationships_path, method: :patch do |f|
|
||||
= form_with model: @form, url: relationships_path do |f|
|
||||
= hidden_field_tag :page, params[:page] || 1
|
||||
|
||||
- RelationshipFilter::KEYS.each do |key|
|
||||
|
|
|
@ -53,7 +53,7 @@ RSpec.describe RelationshipsController do
|
|||
end
|
||||
|
||||
context 'when select parameter is provided' do
|
||||
subject { patch :update, params: { form_account_batch: { account_ids: [alice.id] }, remove_domains_from_followers: '' } }
|
||||
subject { patch :update, params: { form_relationship_batch: { account_ids: [alice.id] }, remove_domains_from_followers: '' } }
|
||||
|
||||
it 'soft-blocks followers from selected domains' do
|
||||
alice.follow!(user.account)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:follow_recommendation_suppression) do
|
||||
account { Fabricate.build(:account) }
|
||||
end
|
|
@ -11,6 +11,7 @@ RSpec.describe Form::AccountBatch do
|
|||
let(:account) { Fabricate(:admin_user).account }
|
||||
let(:account_ids) { [] }
|
||||
let(:query) { Account.none }
|
||||
let(:select_all_matching) { false }
|
||||
|
||||
before do
|
||||
account_batch.assign_attributes(
|
||||
|
@ -77,5 +78,37 @@ RSpec.describe Form::AccountBatch do
|
|||
[target_account.reload, target_account2.reload].map(&:suspended?)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is "approve"' do
|
||||
let(:action) { 'approve' }
|
||||
let(:account_ids) { [unapproved_user_account.id] }
|
||||
let(:unapproved_user_account) { Fabricate :account }
|
||||
|
||||
before { unapproved_user_account.user.update!(approved: false) }
|
||||
|
||||
it 'approves the user of the supplied accounts' do
|
||||
expect { subject }
|
||||
.to change { unapproved_user_account.reload.user.approved? }.to(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is "reject"' do
|
||||
let(:action) { 'reject' }
|
||||
let(:account_ids) { [reject_user_account.id] }
|
||||
let(:reject_user_account) { Fabricate :account }
|
||||
|
||||
before { reject_user_account.user.update!(approved: false) }
|
||||
|
||||
it 'rejects the user of the supplied accounts' do
|
||||
expect { subject }
|
||||
.to change { reject_user_account.reload.suspended? }.to(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is "unknown"' do
|
||||
let(:action) { 'unknown' }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
45
spec/models/form/follow_recommendation_batch_spec.rb
Normal file
45
spec/models/form/follow_recommendation_batch_spec.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Form::FollowRecommendationBatch do
|
||||
describe '#persisted?' do
|
||||
it { is_expected.to be_persisted }
|
||||
end
|
||||
|
||||
describe '#save' do
|
||||
subject { described_class.new(action:, account_ids:, current_account: admin).save }
|
||||
|
||||
let(:account_ids) { [account.id] }
|
||||
let(:account) { Fabricate :account }
|
||||
let(:admin) { Fabricate :account, user: Fabricate(:admin_user) }
|
||||
|
||||
context 'when action is suppress_follow_recommendation' do
|
||||
let(:action) { 'suppress_follow_recommendation' }
|
||||
|
||||
it 'adds a suppression for the accounts' do
|
||||
expect { subject }
|
||||
.to change(FollowRecommendationSuppression, :count).by(1)
|
||||
.and change { account.reload.follow_recommendation_suppression }.from(be_nil).to(be_present)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is unsuppress_follow_recommendation' do
|
||||
let(:action) { 'unsuppress_follow_recommendation' }
|
||||
|
||||
before { Fabricate :follow_recommendation_suppression, account: }
|
||||
|
||||
it 'removes a suppression for the accounts' do
|
||||
expect { subject }
|
||||
.to change(FollowRecommendationSuppression, :count).by(-1)
|
||||
.and change { account.reload.follow_recommendation_suppression }.from(be_present).to(be_nil)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is unknown' do
|
||||
let(:action) { 'unknown' }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
end
|
||||
end
|
87
spec/models/form/relationship_batch_spec.rb
Normal file
87
spec/models/form/relationship_batch_spec.rb
Normal file
|
@ -0,0 +1,87 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Form::RelationshipBatch do
|
||||
describe '#persisted?' do
|
||||
it { is_expected.to be_persisted }
|
||||
end
|
||||
|
||||
describe '#save' do
|
||||
subject { described_class.new(action:, account_ids:, current_account:).save }
|
||||
|
||||
let(:account_ids) { [account.id] }
|
||||
let(:account) { Fabricate :account }
|
||||
let(:current_account) { Fabricate :account }
|
||||
|
||||
context 'when action is follow' do
|
||||
let(:action) { 'follow' }
|
||||
let(:account_ids) { [account.id] }
|
||||
|
||||
it 'adds a follow for the accounts' do
|
||||
expect { subject }
|
||||
.to change(Follow, :count).by(1)
|
||||
.and change { current_account.reload.active_relationships.exists?(target_account: account) }.from(false).to(true)
|
||||
end
|
||||
|
||||
context 'when account cannot be followed' do
|
||||
let(:account) { Fabricate :account, domain: 'test.example' }
|
||||
|
||||
it 'does not save follows and re-raises error' do
|
||||
expect { subject }
|
||||
.to raise_error(Mastodon::NotPermittedError)
|
||||
.and not_change(Follow, :count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is unfollow' do
|
||||
let(:action) { 'unfollow' }
|
||||
|
||||
before { Fabricate :follow, account: current_account, target_account: account }
|
||||
|
||||
it 'removes a follow for the accounts' do
|
||||
expect { subject }
|
||||
.to change(Follow, :count).by(-1)
|
||||
.and change { current_account.reload.active_relationships.exists?(target_account: account) }.from(true).to(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is remove_from_followers' do
|
||||
let(:action) { 'remove_from_followers' }
|
||||
|
||||
before { Fabricate :follow, account: account, target_account: current_account }
|
||||
|
||||
it 'removes followers from the accounts' do
|
||||
expect { subject }
|
||||
.to change(Follow, :count).by(-1)
|
||||
.and change { current_account.reload.passive_relationships.exists?(account: account) }.from(true).to(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is remove_domains_from_followers' do
|
||||
let(:action) { 'remove_domains_from_followers' }
|
||||
|
||||
let(:account) { Fabricate :account, domain: 'host.example' }
|
||||
let(:account_other) { Fabricate :account, domain: 'host.example' }
|
||||
|
||||
before do
|
||||
Fabricate :follow, account: account, target_account: current_account
|
||||
Fabricate :follow, account: account_other, target_account: current_account
|
||||
end
|
||||
|
||||
it 'removes all followers from domains of the accounts' do
|
||||
expect { subject }
|
||||
.to change(Follow, :count).by(-2)
|
||||
.and change { current_account.reload.passive_relationships.exists?(account: account) }.from(true).to(false)
|
||||
.and change { current_account.reload.passive_relationships.exists?(account: account_other) }.from(true).to(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when action is unknown' do
|
||||
let(:action) { 'unknown' }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,7 +7,7 @@ RSpec.describe 'Admin Follow Recommendations' do
|
|||
before { sign_in Fabricate(:admin_user) }
|
||||
|
||||
it 'gracefully handles invalid nested params' do
|
||||
put admin_follow_recommendations_path(form_account_batch: 'invalid')
|
||||
put admin_follow_recommendations_path(form_follow_recommendation_batch: 'invalid')
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(admin_follow_recommendations_path)
|
||||
|
|
|
@ -7,7 +7,7 @@ RSpec.describe 'Relationships' do
|
|||
before { sign_in Fabricate(:user) }
|
||||
|
||||
it 'gracefully handles invalid nested params' do
|
||||
put relationships_path(form_account_batch: 'invalid')
|
||||
put relationships_path(form_relationship_batch: 'invalid')
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(relationships_path)
|
||||
|
|
Loading…
Reference in New Issue
Block a user