Merge pull request #1650 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes
This commit is contained in:
		
						commit
						3b9a6049ad
					
				| @ -117,6 +117,16 @@ module Admin | ||||
|       redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.removed_header_msg', username: @account.acct) | ||||
|     end | ||||
| 
 | ||||
|     def unblock_email | ||||
|       authorize @account, :unblock_email? | ||||
| 
 | ||||
|       CanonicalEmailBlock.where(reference_account: @account).delete_all | ||||
| 
 | ||||
|       log_action :unblock_email, @account | ||||
| 
 | ||||
|       redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.unblocked_email_msg', username: @account.acct) | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def set_account | ||||
|  | ||||
| @ -14,6 +14,15 @@ module Admin | ||||
|       authorize :instance, :show? | ||||
|     end | ||||
| 
 | ||||
|     def destroy | ||||
|       authorize :instance, :destroy? | ||||
| 
 | ||||
|       Admin::DomainPurgeWorker.perform_async(@instance.domain) | ||||
| 
 | ||||
|       log_action :destroy, @instance | ||||
|       redirect_to admin_instances_path, notice: I18n.t('admin.instances.destroyed_msg', domain: @instance.domain) | ||||
|     end | ||||
| 
 | ||||
|     def clear_delivery_errors | ||||
|       authorize :delivery, :clear_delivery_errors? | ||||
| 
 | ||||
|  | ||||
| @ -31,6 +31,8 @@ module Admin::ActionLogsHelper | ||||
|       link_to truncate(record.text), edit_admin_announcement_path(record.id) | ||||
|     when 'IpBlock' | ||||
|       "#{record.ip}/#{record.ip.prefix} (#{I18n.t("simple_form.labels.ip_block.severities.#{record.severity}")})" | ||||
|     when 'Instance' | ||||
|       record.domain | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
| @ -54,6 +56,8 @@ module Admin::ActionLogsHelper | ||||
|       truncate(attributes['text'].is_a?(Array) ? attributes['text'].last : attributes['text']) | ||||
|     when 'IpBlock' | ||||
|       "#{attributes['ip']}/#{attributes['ip'].prefix} (#{I18n.t("simple_form.labels.ip_block.severities.#{attributes['severity']}")})" | ||||
|     when 'Instance' | ||||
|       attributes['domain'] | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -42,6 +42,7 @@ export default class Retention extends React.PureComponent { | ||||
| 
 | ||||
|   render () { | ||||
|     const { loading, data } = this.state; | ||||
|     const { frequency } = this.props; | ||||
| 
 | ||||
|     let content; | ||||
| 
 | ||||
| @ -129,9 +130,18 @@ export default class Retention extends React.PureComponent { | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     let title = null; | ||||
|     switch(frequency) { | ||||
|     case 'day': | ||||
|       title = <FormattedMessage id='admin.dashboard.daily_retention' defaultMessage='User retention rate by day after sign-up' />; | ||||
|       break; | ||||
|     default: | ||||
|       title = <FormattedMessage id='admin.dashboard.monthly_retention' defaultMessage='User retention rate by month after sign-up' />; | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|       <div className='retention'> | ||||
|         <h4><FormattedMessage id='admin.dashboard.retention' defaultMessage='Retention' /></h4> | ||||
|         <h4>{title}</h4> | ||||
| 
 | ||||
|         {content} | ||||
|       </div> | ||||
|  | ||||
| @ -42,6 +42,7 @@ export default class Retention extends React.PureComponent { | ||||
| 
 | ||||
|   render () { | ||||
|     const { loading, data } = this.state; | ||||
|     const { frequency } = this.props; | ||||
| 
 | ||||
|     let content; | ||||
| 
 | ||||
| @ -129,9 +130,18 @@ export default class Retention extends React.PureComponent { | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     let title = null; | ||||
|     switch(frequency) { | ||||
|     case 'day': | ||||
|       title = <FormattedMessage id='admin.dashboard.daily_retention' defaultMessage='User retention rate by day after sign-up' />; | ||||
|       break; | ||||
|     default: | ||||
|       title = <FormattedMessage id='admin.dashboard.monthly_retention' defaultMessage='User retention rate by month after sign-up' />; | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|       <div className='retention'> | ||||
|         <h4><FormattedMessage id='admin.dashboard.retention' defaultMessage='Retention' /></h4> | ||||
|         <h4>{title}</h4> | ||||
| 
 | ||||
|         {content} | ||||
|       </div> | ||||
|  | ||||
| @ -3074,17 +3074,20 @@ a.account__display-name { | ||||
|   box-sizing: border-box; | ||||
|   width: 100%; | ||||
|   margin: 0; | ||||
|   color: $inverted-text-color; | ||||
|   background: $simple-background-color; | ||||
|   padding: 10px; | ||||
|   color: $darker-text-color; | ||||
|   background: transparent; | ||||
|   padding: 7px 0; | ||||
|   font-family: inherit; | ||||
|   font-size: 14px; | ||||
|   resize: vertical; | ||||
|   border: 0; | ||||
|   border-bottom: 2px solid $ui-primary-color; | ||||
|   outline: 0; | ||||
|   border-radius: 4px; | ||||
| 
 | ||||
|   &:focus { | ||||
|   &:focus, | ||||
|   &:active { | ||||
|     color: $primary-text-color; | ||||
|     border-bottom-color: $ui-highlight-color; | ||||
|     outline: 0; | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -26,6 +26,7 @@ class Admin::ActionLogFilter | ||||
|     destroy_domain_allow: { target_type: 'DomainAllow', action: 'destroy' }.freeze, | ||||
|     destroy_domain_block: { target_type: 'DomainBlock', action: 'destroy' }.freeze, | ||||
|     destroy_email_domain_block: { target_type: 'EmailDomainBlock', action: 'destroy' }.freeze, | ||||
|     destroy_instance: { target_type: 'Instance', action: 'destroy' }.freeze, | ||||
|     destroy_unavailable_domain: { target_type: 'UnavailableDomain', action: 'destroy' }.freeze, | ||||
|     destroy_status: { target_type: 'Status', action: 'destroy' }.freeze, | ||||
|     disable_2fa_user: { target_type: 'User', action: 'disable' }.freeze, | ||||
| @ -49,6 +50,7 @@ class Admin::ActionLogFilter | ||||
|     update_announcement: { target_type: 'Announcement', action: 'update' }.freeze, | ||||
|     update_custom_emoji: { target_type: 'CustomEmoji', action: 'update' }.freeze, | ||||
|     update_status: { target_type: 'Status', action: 'update' }.freeze, | ||||
|     unblock_email_account: { target_type: 'Account', action: 'unblock_email' }.freeze, | ||||
|   }.freeze | ||||
| 
 | ||||
|   attr_reader :params | ||||
|  | ||||
| @ -24,4 +24,8 @@ class CanonicalEmailBlock < ApplicationRecord | ||||
|   def self.block?(email) | ||||
|     where(canonical_email_hash: email_to_canonical_email_hash(email)).exists? | ||||
|   end | ||||
| 
 | ||||
|   def self.find_blocks(email) | ||||
|     where(canonical_email_hash: email_to_canonical_email_hash(email)) | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -64,4 +64,8 @@ class AccountPolicy < ApplicationPolicy | ||||
|   def memorialize? | ||||
|     admin? && !record.user&.admin? && !record.instance_actor? | ||||
|   end | ||||
| 
 | ||||
|   def unblock_email? | ||||
|     staff? | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -8,4 +8,8 @@ class InstancePolicy < ApplicationPolicy | ||||
|   def show? | ||||
|     admin? | ||||
|   end | ||||
| 
 | ||||
|   def destroy? | ||||
|     admin? | ||||
|   end | ||||
| end | ||||
|  | ||||
							
								
								
									
										10
									
								
								app/services/purge_domain_service.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/services/purge_domain_service.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| # frozen_string_literal: true | ||||
| 
 | ||||
| class PurgeDomainService < BaseService | ||||
|   def call(domain) | ||||
|     Account.remote.where(domain: domain).reorder(nil).find_each do |account| | ||||
|       DeleteAccountService.new.call(account, reserve_username: false, skip_side_effects: true) | ||||
|     end | ||||
|     Instance.refresh | ||||
|   end | ||||
| end | ||||
| @ -71,7 +71,9 @@ | ||||
|           = t('admin.accounts.no_limits_imposed') | ||||
|       .dashboard__counters__label= t 'admin.accounts.login_status' | ||||
| 
 | ||||
| - unless @account.local? && @account.user.nil? | ||||
| - if @account.local? && @account.user.nil? | ||||
|   = link_to t('admin.accounts.unblock_email'), unblock_email_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unblock_email, @account) && CanonicalEmailBlock.where(reference_account_id: @account.id).exists? | ||||
| - else | ||||
|   .table-wrapper | ||||
|     %table.table.inline-table | ||||
|       %tbody | ||||
|  | ||||
| @ -84,3 +84,5 @@ | ||||
|       = link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button' | ||||
|     - else | ||||
|       = link_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button' | ||||
|     - unless @instance.delivery_failure_tracker.available? && @instance.accounts_count > 0 | ||||
|       = link_to t('admin.instances.purge'), admin_instance_path(@instance), data: { confirm: t('admin.instances.confirm_purge'), method: :delete }, class: 'button' | ||||
|  | ||||
							
								
								
									
										9
									
								
								app/workers/admin/domain_purge_worker.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								app/workers/admin/domain_purge_worker.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| # frozen_string_literal: true | ||||
| 
 | ||||
| class Admin::DomainPurgeWorker | ||||
|   include Sidekiq::Worker | ||||
| 
 | ||||
|   def perform(domain) | ||||
|     PurgeDomainService.new.call(domain) | ||||
|   end | ||||
| end | ||||
| @ -208,6 +208,8 @@ en: | ||||
|       suspension_irreversible: The data of this account has been irreversibly deleted. You can unsuspend the account to make it usable but it will not recover any data it previously had. | ||||
|       suspension_reversible_hint_html: The account has been suspended, and the data will be fully removed on %{date}. Until then, the account can be restored without any ill effects. If you wish to remove all of the account's data immediately, you can do so below. | ||||
|       title: Accounts | ||||
|       unblock_email: Unblock email address | ||||
|       unblocked_email_msg: Successfully unblocked %{username}'s email address | ||||
|       unconfirmed_email: Unconfirmed email | ||||
|       undo_sensitized: Undo force-sensitive | ||||
|       undo_silenced: Undo limit | ||||
| @ -240,6 +242,7 @@ en: | ||||
|         destroy_domain_allow: Delete Domain Allow | ||||
|         destroy_domain_block: Delete Domain Block | ||||
|         destroy_email_domain_block: Delete E-mail Domain Block | ||||
|         destroy_instance: Purge Domain | ||||
|         destroy_ip_block: Delete IP rule | ||||
|         destroy_status: Delete Post | ||||
|         destroy_unavailable_domain: Delete Unavailable Domain | ||||
| @ -261,6 +264,7 @@ en: | ||||
|         silence_account: Limit Account | ||||
|         suspend_account: Suspend Account | ||||
|         unassigned_report: Unassign Report | ||||
|         unblock_email_account: Unblock email address | ||||
|         unsensitive_account: Undo Force-Sensitive Account | ||||
|         unsilence_account: Undo Limit Account | ||||
|         unsuspend_account: Unsuspend Account | ||||
| @ -287,6 +291,7 @@ en: | ||||
|         destroy_domain_allow_html: "%{name} disallowed federation with domain %{target}" | ||||
|         destroy_domain_block_html: "%{name} unblocked domain %{target}" | ||||
|         destroy_email_domain_block_html: "%{name} unblocked e-mail domain %{target}" | ||||
|         destroy_instance_html: "%{name} purged domain %{target}" | ||||
|         destroy_ip_block_html: "%{name} deleted rule for IP %{target}" | ||||
|         destroy_status_html: "%{name} removed post by %{target}" | ||||
|         destroy_unavailable_domain_html: "%{name} resumed delivery to domain %{target}" | ||||
| @ -308,6 +313,7 @@ en: | ||||
|         silence_account_html: "%{name} limited %{target}'s account" | ||||
|         suspend_account_html: "%{name} suspended %{target}'s account" | ||||
|         unassigned_report_html: "%{name} unassigned report %{target}" | ||||
|         unblock_email_account_html: "%{name} unblocked %{target}'s email address" | ||||
|         unsensitive_account_html: "%{name} unmarked %{target}'s media as sensitive" | ||||
|         unsilence_account_html: "%{name} undid limit of %{target}'s account" | ||||
|         unsuspend_account_html: "%{name} unsuspended %{target}'s account" | ||||
| @ -465,6 +471,7 @@ en: | ||||
|       back_to_limited: Limited | ||||
|       back_to_warning: Warning | ||||
|       by_domain: Domain | ||||
|       confirm_purge: Are you sure you want to permanently delete data from this domain? | ||||
|       delivery: | ||||
|         all: All | ||||
|         clear: Clear delivery errors | ||||
| @ -480,6 +487,7 @@ en: | ||||
|       delivery_available: Delivery is available | ||||
|       delivery_error_days: Delivery error days | ||||
|       delivery_error_hint: If delivery is not possible for %{count} days, it will be automatically marked as undeliverable. | ||||
|       destroyed_msg: Data from %{domain} is now queued for imminent deletion. | ||||
|       empty: No domains found. | ||||
|       known_accounts: | ||||
|         one: "%{count} known account" | ||||
| @ -490,6 +498,7 @@ en: | ||||
|         title: Moderation | ||||
|       private_comment: Private comment | ||||
|       public_comment: Public comment | ||||
|       purge: Purge | ||||
|       title: Federation | ||||
|       total_blocked_by_us: Blocked by us | ||||
|       total_followed_by_them: Followed by them | ||||
|  | ||||
| @ -216,7 +216,7 @@ Rails.application.routes.draw do | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     resources :instances, only: [:index, :show], constraints: { id: /[^\/]+/ } do | ||||
|     resources :instances, only: [:index, :show, :destroy], constraints: { id: /[^\/]+/ } do | ||||
|       member do | ||||
|         post :clear_delivery_errors | ||||
|         post :restart_delivery | ||||
| @ -251,6 +251,7 @@ Rails.application.routes.draw do | ||||
|         post :memorialize | ||||
|         post :approve | ||||
|         post :reject | ||||
|         post :unblock_email | ||||
|       end | ||||
| 
 | ||||
|       collection do | ||||
|  | ||||
| @ -13,6 +13,7 @@ require_relative 'mastodon/preview_cards_cli' | ||||
| require_relative 'mastodon/cache_cli' | ||||
| require_relative 'mastodon/upgrade_cli' | ||||
| require_relative 'mastodon/email_domain_blocks_cli' | ||||
| require_relative 'mastodon/canonical_email_blocks_cli' | ||||
| require_relative 'mastodon/ip_blocks_cli' | ||||
| require_relative 'mastodon/maintenance_cli' | ||||
| require_relative 'mastodon/version' | ||||
| @ -62,6 +63,9 @@ module Mastodon | ||||
|     desc 'ip_blocks SUBCOMMAND ...ARGS', 'Manage IP blocks' | ||||
|     subcommand 'ip_blocks', Mastodon::IpBlocksCLI | ||||
| 
 | ||||
|     desc 'canonical_email_blocks SUBCOMMAND ...ARGS', 'Manage canonical e-mail blocks' | ||||
|     subcommand 'canonical_email_blocks', Mastodon::CanonicalEmailBlocksCLI | ||||
| 
 | ||||
|     desc 'maintenance SUBCOMMAND ...ARGS', 'Various maintenance utilities' | ||||
|     subcommand 'maintenance', Mastodon::MaintenanceCLI | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										64
									
								
								lib/mastodon/canonical_email_blocks_cli.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								lib/mastodon/canonical_email_blocks_cli.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| # frozen_string_literal: true | ||||
| 
 | ||||
| require 'concurrent' | ||||
| require_relative '../../config/boot' | ||||
| require_relative '../../config/environment' | ||||
| require_relative 'cli_helper' | ||||
| 
 | ||||
| module Mastodon | ||||
|   class CanonicalEmailBlocksCLI < Thor | ||||
|     include CLIHelper | ||||
| 
 | ||||
|     def self.exit_on_failure? | ||||
|       true | ||||
|     end | ||||
| 
 | ||||
|     desc 'find EMAIL', 'Find a given e-mail address in the canonical e-mail blocks' | ||||
|     long_desc <<-LONG_DESC | ||||
|       When suspending a local user, a hash of a "canonical" version of their e-mail | ||||
|       address is stored to prevent them from signing up again. | ||||
| 
 | ||||
|       This command can be used to find whether a known email address is blocked, | ||||
|       and if so, which account it was attached to. | ||||
|     LONG_DESC | ||||
|     def find(email) | ||||
|       accts = CanonicalEmailBlock.find_blocks(email).map(&:reference_account).map(&:acct).to_a | ||||
|       if accts.empty? | ||||
|         say("#{email} is not blocked", :yellow) | ||||
|       else | ||||
|         accts.each do |acct| | ||||
|           say(acct, :white) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     desc 'remove EMAIL', 'Remove a canonical e-mail block' | ||||
|     long_desc <<-LONG_DESC | ||||
|       When suspending a local user, a hash of a "canonical" version of their e-mail | ||||
|       address is stored to prevent them from signing up again. | ||||
| 
 | ||||
|       This command allows removing a canonical email block. | ||||
|     LONG_DESC | ||||
|     def remove(email) | ||||
|       blocks = CanonicalEmailBlock.find_blocks(email) | ||||
|       if blocks.empty? | ||||
|         say("#{email} is not blocked", :yellow) | ||||
|       else | ||||
|         blocks.destroy_all | ||||
|         say("Removed canonical email block for #{email}", :green) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def color(processed, failed) | ||||
|       if !processed.zero? && failed.zero? | ||||
|         :green | ||||
|       elsif failed.zero? | ||||
|         :yellow | ||||
|       else | ||||
|         :red | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -192,4 +192,36 @@ RSpec.describe Admin::AccountsController, type: :controller do | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'POST #unblock_email' do | ||||
|     subject do | ||||
|       -> { post :unblock_email, params: { id: account.id } } | ||||
|     end | ||||
| 
 | ||||
|     let(:current_user) { Fabricate(:user, admin: admin) } | ||||
|     let(:account) { Fabricate(:account, suspended: true) } | ||||
|     let!(:email_block) { Fabricate(:canonical_email_block, reference_account: account) } | ||||
| 
 | ||||
|     context 'when user is admin' do | ||||
|       let(:admin) { true } | ||||
| 
 | ||||
|       it 'succeeds in removing email blocks' do | ||||
|         is_expected.to change { CanonicalEmailBlock.where(reference_account: account).count }.from(1).to(0) | ||||
|       end | ||||
| 
 | ||||
|       it 'redirects to admin account path' do | ||||
|         subject.call | ||||
|         expect(response).to redirect_to admin_account_path(account.id) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'when user is not admin' do | ||||
|       let(:admin) { false } | ||||
| 
 | ||||
|       it 'fails to remove avatar' do | ||||
|         subject.call | ||||
|         expect(response).to have_http_status :forbidden | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -3,8 +3,14 @@ require 'rails_helper' | ||||
| RSpec.describe Admin::InstancesController, type: :controller do | ||||
|   render_views | ||||
| 
 | ||||
|   let(:current_user) { Fabricate(:user, admin: true) } | ||||
| 
 | ||||
|   let!(:account)     { Fabricate(:account, domain: 'popular') } | ||||
|   let!(:account2)    { Fabricate(:account, domain: 'popular') } | ||||
|   let!(:account3)    { Fabricate(:account, domain: 'less.popular') } | ||||
| 
 | ||||
|   before do | ||||
|     sign_in Fabricate(:user, admin: true), scope: :user | ||||
|     sign_in current_user, scope: :user | ||||
|   end | ||||
| 
 | ||||
|   describe 'GET #index' do | ||||
| @ -16,10 +22,6 @@ RSpec.describe Admin::InstancesController, type: :controller do | ||||
|     end | ||||
| 
 | ||||
|     it 'renders instances' do | ||||
|       Fabricate(:account, domain: 'popular') | ||||
|       Fabricate(:account, domain: 'popular') | ||||
|       Fabricate(:account, domain: 'less.popular') | ||||
| 
 | ||||
|       get :index, params: { page: 2 } | ||||
| 
 | ||||
|       instances = assigns(:instances).to_a | ||||
| @ -29,4 +31,27 @@ RSpec.describe Admin::InstancesController, type: :controller do | ||||
|       expect(response).to have_http_status(200) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'DELETE #destroy' do | ||||
|     subject { delete :destroy, params: { id: Instance.first.id } } | ||||
| 
 | ||||
|     let(:current_user) { Fabricate(:user, admin: admin) } | ||||
|     let(:account) { Fabricate(:account) } | ||||
| 
 | ||||
|     context 'when user is admin' do | ||||
|       let(:admin) { true } | ||||
| 
 | ||||
|       it 'succeeds in purging instance' do | ||||
|         is_expected.to redirect_to admin_instances_path | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'when user is not admin' do | ||||
|       let(:admin) { false } | ||||
| 
 | ||||
|       it 'fails to purge instance' do | ||||
|         is_expected.to have_http_status :forbidden | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -37,7 +37,7 @@ RSpec.describe AccountPolicy do | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   permissions :unsuspend? do | ||||
|   permissions :unsuspend?, :unblock_email? do | ||||
|     before do | ||||
|       alice.suspend! | ||||
|     end | ||||
|  | ||||
| @ -8,7 +8,7 @@ RSpec.describe InstancePolicy do | ||||
|   let(:admin)   { Fabricate(:user, admin: true).account } | ||||
|   let(:john)    { Fabricate(:user).account } | ||||
| 
 | ||||
|   permissions :index? do | ||||
|   permissions :index?, :show?, :destroy? do | ||||
|     context 'admin' do | ||||
|       it 'permits' do | ||||
|         expect(subject).to permit(admin, Instance) | ||||
|  | ||||
							
								
								
									
										27
									
								
								spec/services/purge_domain_service_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								spec/services/purge_domain_service_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| require 'rails_helper' | ||||
| 
 | ||||
| RSpec.describe PurgeDomainService, type: :service do | ||||
|   let!(:old_account) { Fabricate(:account, domain: 'obsolete.org') } | ||||
|   let!(:old_status1) { Fabricate(:status, account: old_account) } | ||||
|   let!(:old_status2) { Fabricate(:status, account: old_account) } | ||||
|   let!(:old_attachment) { Fabricate(:media_attachment, account: old_account, status: old_status2, file: attachment_fixture('attachment.jpg')) } | ||||
| 
 | ||||
|   subject { PurgeDomainService.new } | ||||
| 
 | ||||
|   describe 'for a suspension' do | ||||
|     before do | ||||
|       subject.call('obsolete.org') | ||||
|     end | ||||
| 
 | ||||
|     it 'removes the remote accounts\'s statuses and media attachments' do | ||||
|       expect { old_account.reload }.to raise_exception ActiveRecord::RecordNotFound | ||||
|       expect { old_status1.reload }.to raise_exception ActiveRecord::RecordNotFound | ||||
|       expect { old_status2.reload }.to raise_exception ActiveRecord::RecordNotFound | ||||
|       expect { old_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound | ||||
|     end | ||||
| 
 | ||||
|     it 'refreshes instances view' do | ||||
|       expect(Instance.where(domain: 'obsolete.org').exists?).to be false | ||||
|     end | ||||
|   end | ||||
| end | ||||
							
								
								
									
										18
									
								
								spec/workers/admin/domain_purge_worker_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								spec/workers/admin/domain_purge_worker_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| # frozen_string_literal: true | ||||
| 
 | ||||
| require 'rails_helper' | ||||
| 
 | ||||
| describe Admin::DomainPurgeWorker do | ||||
|   subject { described_class.new } | ||||
| 
 | ||||
|   describe 'perform' do | ||||
|     it 'calls domain purge service for relevant domain block' do | ||||
|       service = double(call: nil) | ||||
|       allow(PurgeDomainService).to receive(:new).and_return(service) | ||||
|       result = subject.perform('example.com') | ||||
| 
 | ||||
|       expect(result).to be_nil | ||||
|       expect(service).to have_received(:call).with('example.com') | ||||
|     end | ||||
|   end | ||||
| end | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user