Merge remote-tracking branch 'parent/main' into upstream-20231214
This commit is contained in:
commit
08a2f557fe
61 changed files with 980 additions and 838 deletions
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Accounts::IdentityProofsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Accounts::ListsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:lists') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:list) { Fabricate(:list, account: user.account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
user.account.follow!(account)
|
||||
list.accounts << account
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Accounts::LookupController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show, params: { account_id: account.id, acct: account.acct }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,40 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::Accounts::PinsController do
|
||||
let(:john) { Fabricate(:user) }
|
||||
let(:kevin) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: john.id, scopes: 'write:accounts') }
|
||||
|
||||
before do
|
||||
kevin.account.followers << john.account
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
subject { post :create, params: { account_id: kevin.account.id } }
|
||||
|
||||
it 'creates account_pin', :aggregate_failures do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(1)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
subject { delete :destroy, params: { account_id: kevin.account.id } }
|
||||
|
||||
before do
|
||||
Fabricate(:account_pin, account: john.account, target_account: kevin.account)
|
||||
end
|
||||
|
||||
it 'destroys account_pin', :aggregate_failures do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(-1)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::Accounts::SearchController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show, params: { q: 'query' }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::FeaturedTags::SuggestionsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V2::SuggestionsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -34,23 +34,21 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:action) { :create }
|
||||
|
||||
shared_examples 'a new user with given email address and username' do
|
||||
it 'creates a new user with the specified email address' do
|
||||
subject
|
||||
|
||||
expect(User.find_by(email: options[:email])).to be_present
|
||||
end
|
||||
|
||||
it 'creates a new local account with the specified username' do
|
||||
subject
|
||||
|
||||
expect(Account.find_local('tootctl_username')).to be_present
|
||||
end
|
||||
|
||||
it 'returns "OK" and newly generated password' do
|
||||
it 'creates user and accounts from options and displays success message' do
|
||||
allow(SecureRandom).to receive(:hex).and_return('test_password')
|
||||
|
||||
expect { subject }
|
||||
.to output_results("OK\nNew password: test_password")
|
||||
.to output_results('OK', 'New password: test_password')
|
||||
expect(user_from_options).to be_present
|
||||
expect(account_from_options).to be_present
|
||||
end
|
||||
|
||||
def user_from_options
|
||||
User.find_by(email: options[:email])
|
||||
end
|
||||
|
||||
def account_from_options
|
||||
Account.find_local('tootctl_username')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -79,7 +77,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it_behaves_like 'a new user with given email address and username'
|
||||
|
||||
it 'creates a new user with confirmed status' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('New password')
|
||||
|
||||
user = User.find_by(email: options[:email])
|
||||
|
||||
|
@ -97,7 +96,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it_behaves_like 'a new user with given email address and username'
|
||||
|
||||
it 'creates a new user with approved status' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('New password')
|
||||
|
||||
user = User.find_by(email: options[:email])
|
||||
|
||||
|
@ -113,7 +113,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it_behaves_like 'a new user with given email address and username'
|
||||
|
||||
it 'creates a new user and assigns the specified role' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('New password')
|
||||
|
||||
role = User.find_by(email: options[:email])&.role
|
||||
|
||||
|
@ -150,7 +151,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { email: 'tootctl_new@example.com', reattach: true, force: true } }
|
||||
|
||||
it 'reattaches the account to the new user and deletes the previous user' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('New password')
|
||||
|
||||
user = Account.find_local('tootctl_username')&.user
|
||||
|
||||
|
@ -199,14 +201,9 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:arguments) { [user.account.username] }
|
||||
|
||||
context 'when no option is provided' do
|
||||
it 'returns a successful message' do
|
||||
it 'returns a successful message and preserves user' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
end
|
||||
|
||||
it 'does not modify the user' do
|
||||
subject
|
||||
|
||||
expect(user).to eq(user.reload)
|
||||
end
|
||||
end
|
||||
|
@ -227,7 +224,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { role: default_role.name } }
|
||||
|
||||
it "updates the user's role to the specified role" do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
role = user.reload.role
|
||||
|
||||
|
@ -242,7 +240,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:user) { Fabricate(:user, role: role) }
|
||||
|
||||
it "removes the user's role successfully" do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
role = user.reload.role
|
||||
|
||||
|
@ -255,13 +254,15 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { email: 'new_email@email.com' } }
|
||||
|
||||
it "sets the user's unconfirmed email to the provided email address" do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(user.reload.unconfirmed_email).to eq(options[:email])
|
||||
end
|
||||
|
||||
it "does not update the user's original email address" do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(user.reload.email).to eq('old_email@email.com')
|
||||
end
|
||||
|
@ -271,13 +272,15 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { email: 'new_email@email.com', confirm: true } }
|
||||
|
||||
it "updates the user's email address to the provided email" do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(user.reload.email).to eq(options[:email])
|
||||
end
|
||||
|
||||
it "sets the user's email address as confirmed" do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(user.reload.confirmed?).to be(true)
|
||||
end
|
||||
|
@ -289,7 +292,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { confirm: true } }
|
||||
|
||||
it "confirms the user's email address" do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(user.reload.confirmed?).to be(true)
|
||||
end
|
||||
|
@ -304,7 +308,9 @@ describe Mastodon::CLI::Accounts do
|
|||
end
|
||||
|
||||
it 'approves the user' do
|
||||
expect { subject }.to change { user.reload.approved }.from(false).to(true)
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
.and change { user.reload.approved }.from(false).to(true)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -313,7 +319,9 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { disable: true } }
|
||||
|
||||
it 'disables the user' do
|
||||
expect { subject }.to change { user.reload.disabled }.from(false).to(true)
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
.and change { user.reload.disabled }.from(false).to(true)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -322,7 +330,9 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { enable: true } }
|
||||
|
||||
it 'enables the user' do
|
||||
expect { subject }.to change { user.reload.disabled }.from(true).to(false)
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
.and change { user.reload.disabled }.from(true).to(false)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -342,7 +352,9 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { disable_2fa: true } }
|
||||
|
||||
it 'disables the two-factor authentication for the user' do
|
||||
expect { subject }.to change { user.reload.otp_required_for_login }.from(true).to(false)
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
.and change { user.reload.otp_required_for_login }.from(true).to(false)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -392,7 +404,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:arguments) { [account.username] }
|
||||
|
||||
it 'deletes the specified user successfully' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('Deleting')
|
||||
|
||||
expect(delete_account_service).to have_received(:call).with(account, reserve_email: false).once
|
||||
end
|
||||
|
@ -400,15 +413,10 @@ describe Mastodon::CLI::Accounts do
|
|||
context 'with --dry-run option' do
|
||||
let(:options) { { dry_run: true } }
|
||||
|
||||
it 'does not delete the specified user' do
|
||||
subject
|
||||
|
||||
expect(delete_account_service).to_not have_received(:call).with(account, reserve_email: false)
|
||||
end
|
||||
|
||||
it 'outputs a successful message in dry run mode' do
|
||||
it 'outputs a successful message in dry run mode and does not delete the user' do
|
||||
expect { subject }
|
||||
.to output_results('OK (DRY RUN)')
|
||||
expect(delete_account_service).to_not have_received(:call).with(account, reserve_email: false)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -427,7 +435,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { email: account.user.email } }
|
||||
|
||||
it 'deletes the specified user successfully' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('Deleting')
|
||||
|
||||
expect(delete_account_service).to have_received(:call).with(account, reserve_email: false).once
|
||||
end
|
||||
|
@ -435,15 +444,12 @@ describe Mastodon::CLI::Accounts do
|
|||
context 'with --dry-run option' do
|
||||
let(:options) { { email: account.user.email, dry_run: true } }
|
||||
|
||||
it 'does not delete the user' do
|
||||
subject
|
||||
|
||||
expect(delete_account_service).to_not have_received(:call).with(account, reserve_email: false)
|
||||
end
|
||||
|
||||
it 'outputs a successful message in dry run mode' do
|
||||
it 'outputs a successful message in dry run mode and does not delete the user' do
|
||||
expect { subject }
|
||||
.to output_results('OK (DRY RUN)')
|
||||
expect(delete_account_service)
|
||||
.to_not have_received(:call)
|
||||
.with(account, reserve_email: false)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -472,7 +478,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { all: true } }
|
||||
|
||||
it 'approves all pending registrations' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(User.pluck(:approved).all?(true)).to be(true)
|
||||
end
|
||||
|
@ -482,20 +489,20 @@ describe Mastodon::CLI::Accounts do
|
|||
context 'when the number is positive' do
|
||||
let(:options) { { number: 2 } }
|
||||
|
||||
it 'approves the earliest n pending registrations' do
|
||||
subject
|
||||
|
||||
n_earliest_pending_registrations = User.order(created_at: :asc).first(options[:number])
|
||||
it 'approves the earliest n pending registrations but not the remaining ones' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(n_earliest_pending_registrations.all?(&:approved?)).to be(true)
|
||||
expect(pending_registrations.all?(&:approved?)).to be(false)
|
||||
end
|
||||
|
||||
it 'does not approve the remaining pending registrations' do
|
||||
subject
|
||||
def n_earliest_pending_registrations
|
||||
User.order(created_at: :asc).first(options[:number])
|
||||
end
|
||||
|
||||
pending_registrations = User.order(created_at: :asc).last(total_users - options[:number])
|
||||
|
||||
expect(pending_registrations.all?(&:approved?)).to be(false)
|
||||
def pending_registrations
|
||||
User.order(created_at: :asc).last(total_users - options[:number])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -512,15 +519,10 @@ describe Mastodon::CLI::Accounts do
|
|||
context 'when the given number is greater than the number of users' do
|
||||
let(:options) { { number: total_users * 2 } }
|
||||
|
||||
it 'approves all users' do
|
||||
subject
|
||||
|
||||
expect(User.pluck(:approved).all?(true)).to be(true)
|
||||
end
|
||||
|
||||
it 'does not raise any error' do
|
||||
it 'approves all users and does not raise any error' do
|
||||
expect { subject }
|
||||
.to_not raise_error
|
||||
.to output_results('OK')
|
||||
expect(User.pluck(:approved).all?(true)).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -531,7 +533,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:arguments) { [user.account.username] }
|
||||
|
||||
it 'approves the specified user successfully' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(user.reload.approved?).to be(true)
|
||||
end
|
||||
|
@ -575,18 +578,13 @@ describe Mastodon::CLI::Accounts do
|
|||
stub_parallelize_with_progress!
|
||||
end
|
||||
|
||||
it 'makes all local accounts follow the target account' do
|
||||
subject
|
||||
|
||||
it 'displays a successful message and makes all local accounts follow the target account' do
|
||||
expect { subject }
|
||||
.to output_results("OK, followed target from #{Account.local.count} accounts")
|
||||
expect(follow_service).to have_received(:call).with(follower_bob, target_account, any_args).once
|
||||
expect(follow_service).to have_received(:call).with(follower_rony, target_account, any_args).once
|
||||
expect(follow_service).to have_received(:call).with(follower_charles, target_account, any_args).once
|
||||
end
|
||||
|
||||
it 'displays a successful message' do
|
||||
expect { subject }
|
||||
.to output_results("OK, followed target from #{Account.local.count} accounts")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -618,18 +616,13 @@ describe Mastodon::CLI::Accounts do
|
|||
stub_parallelize_with_progress!
|
||||
end
|
||||
|
||||
it 'makes all local accounts unfollow the target account' do
|
||||
subject
|
||||
|
||||
it 'displays a successful message and makes all local accounts unfollow the target account' do
|
||||
expect { subject }
|
||||
.to output_results('OK, unfollowed target from 3 accounts')
|
||||
expect(unfollow_service).to have_received(:call).with(follower_chris, target_account).once
|
||||
expect(unfollow_service).to have_received(:call).with(follower_rambo, target_account).once
|
||||
expect(unfollow_service).to have_received(:call).with(follower_ana, target_account).once
|
||||
end
|
||||
|
||||
it 'displays a successful message' do
|
||||
expect { subject }
|
||||
.to output_results('OK, unfollowed target from 3 accounts')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -651,22 +644,17 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:user) { account.user }
|
||||
let(:arguments) { [account.username] }
|
||||
|
||||
it 'creates a new backup for the specified user' do
|
||||
expect { subject }.to change { user.backups.count }.by(1)
|
||||
end
|
||||
|
||||
it 'creates a backup job' do
|
||||
allow(BackupWorker).to receive(:perform_async)
|
||||
|
||||
subject
|
||||
latest_backup = user.backups.last
|
||||
before { allow(BackupWorker).to receive(:perform_async) }
|
||||
|
||||
it 'creates a new backup and backup job for the specified user and outputs success message' do
|
||||
expect { subject }
|
||||
.to change { user.backups.count }.by(1)
|
||||
.and output_results('OK')
|
||||
expect(BackupWorker).to have_received(:perform_async).with(latest_backup.id).once
|
||||
end
|
||||
|
||||
it 'displays a successful message' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
def latest_backup
|
||||
user.backups.last
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -691,7 +679,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(remote_account_example_com).to receive(:reset_avatar!)
|
||||
allow(account_example_net).to receive(:reset_avatar!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(remote_account_example_com).to have_received(:reset_avatar!).once
|
||||
|
@ -701,7 +690,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it 'does not refresh avatar for local accounts' do
|
||||
allow(local_account).to receive(:reset_avatar!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(local_account).to_not have_received(:reset_avatar!)
|
||||
|
@ -711,7 +701,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(remote_account_example_com).to receive(:reset_header!)
|
||||
allow(account_example_net).to receive(:reset_header!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(remote_account_example_com).to have_received(:reset_header!).once
|
||||
|
@ -721,7 +712,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it 'does not refresh the header for local accounts' do
|
||||
allow(local_account).to receive(:reset_header!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(local_account).to_not have_received(:reset_header!)
|
||||
|
@ -742,7 +734,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(remote_account_example_com).to receive(:reset_avatar!)
|
||||
allow(account_example_net).to receive(:reset_avatar!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(local_account).to_not have_received(:reset_avatar!)
|
||||
|
@ -755,7 +748,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(remote_account_example_com).to receive(:reset_header!)
|
||||
allow(account_example_net).to receive(:reset_header!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(local_account).to_not have_received(:reset_header!)
|
||||
|
@ -788,7 +782,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(account_example_com_a).to receive(:reset_avatar!)
|
||||
allow(account_example_com_b).to receive(:reset_avatar!)
|
||||
|
||||
cli.refresh(*arguments)
|
||||
expect { cli.refresh(*arguments) }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(account_example_com_a).to have_received(:reset_avatar!).once
|
||||
expect(account_example_com_b).to have_received(:reset_avatar!).once
|
||||
|
@ -797,7 +792,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it 'does not reset the avatar for unspecified accounts' do
|
||||
allow(account_example_net).to receive(:reset_avatar!)
|
||||
|
||||
cli.refresh(*arguments)
|
||||
expect { cli.refresh(*arguments) }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(account_example_net).to_not have_received(:reset_avatar!)
|
||||
end
|
||||
|
@ -806,7 +802,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(account_example_com_a).to receive(:reset_header!)
|
||||
allow(account_example_com_b).to receive(:reset_header!)
|
||||
|
||||
cli.refresh(*arguments)
|
||||
expect { cli.refresh(*arguments) }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(account_example_com_a).to have_received(:reset_header!).once
|
||||
expect(account_example_com_b).to have_received(:reset_header!).once
|
||||
|
@ -815,7 +812,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it 'does not reset the header for unspecified accounts' do
|
||||
allow(account_example_net).to receive(:reset_header!)
|
||||
|
||||
cli.refresh(*arguments)
|
||||
expect { cli.refresh(*arguments) }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(account_example_net).to_not have_received(:reset_header!)
|
||||
end
|
||||
|
@ -848,7 +846,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(account_example_com_a).to receive(:reset_avatar!)
|
||||
allow(account_example_com_b).to receive(:reset_avatar!)
|
||||
|
||||
cli.refresh(*arguments)
|
||||
expect { cli.refresh(*arguments) }
|
||||
.to output_results('OK (DRY RUN)')
|
||||
|
||||
expect(account_example_com_a).to_not have_received(:reset_avatar!)
|
||||
expect(account_example_com_b).to_not have_received(:reset_avatar!)
|
||||
|
@ -858,7 +857,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(account_example_com_a).to receive(:reset_header!)
|
||||
allow(account_example_com_b).to receive(:reset_header!)
|
||||
|
||||
cli.refresh(*arguments)
|
||||
expect { cli.refresh(*arguments) }
|
||||
.to output_results('OK (DRY RUN)')
|
||||
|
||||
expect(account_example_com_a).to_not have_received(:reset_header!)
|
||||
expect(account_example_com_b).to_not have_received(:reset_header!)
|
||||
|
@ -884,7 +884,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(account_example_com_a).to receive(:reset_avatar!)
|
||||
allow(account_example_com_b).to receive(:reset_avatar!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(account_example_com_a).to have_received(:reset_avatar!).once
|
||||
|
@ -894,7 +895,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it 'does not refresh the avatar for accounts outside specified domain' do
|
||||
allow(account_example_net).to receive(:reset_avatar!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(account_example_net).to_not have_received(:reset_avatar!)
|
||||
|
@ -904,7 +906,8 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(account_example_com_a).to receive(:reset_header!)
|
||||
allow(account_example_com_b).to receive(:reset_header!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope)
|
||||
expect(account_example_com_a).to have_received(:reset_header!).once
|
||||
|
@ -914,7 +917,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it 'does not refresh the header for accounts outside specified domain' do
|
||||
allow(account_example_net).to receive(:reset_header!)
|
||||
|
||||
cli.refresh
|
||||
expect { cli.refresh }
|
||||
.to output_results('Refreshed 2 accounts')
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(account_example_net).to_not have_received(:reset_header!)
|
||||
|
@ -949,7 +953,8 @@ describe Mastodon::CLI::Accounts do
|
|||
old_private_key = account.private_key
|
||||
old_public_key = account.public_key
|
||||
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
account.reload
|
||||
|
||||
expect(account.private_key).to_not eq(old_private_key)
|
||||
|
@ -959,19 +964,20 @@ describe Mastodon::CLI::Accounts do
|
|||
it 'broadcasts the new keys for the specified account' do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_in)
|
||||
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_in).with(anything, account.id, anything).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given username is not found' do
|
||||
let(:arguments) { ['non_existent_username'] }
|
||||
context 'when the given username is not found' do
|
||||
let(:arguments) { ['non_existent_username'] }
|
||||
|
||||
it 'exits with an error message when the specified username is not found' do
|
||||
expect { subject }
|
||||
.to output_results('No such account')
|
||||
.and raise_error(SystemExit)
|
||||
end
|
||||
it 'exits with an error message when the specified username is not found' do
|
||||
expect { subject }
|
||||
.to output_results('No such account')
|
||||
.and raise_error(SystemExit)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -983,7 +989,8 @@ describe Mastodon::CLI::Accounts do
|
|||
old_private_keys = accounts.map(&:private_key)
|
||||
old_public_keys = accounts.map(&:public_key)
|
||||
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('rotated')
|
||||
accounts.each(&:reload)
|
||||
|
||||
expect(accounts.map(&:private_key)).to_not eq(old_private_keys)
|
||||
|
@ -993,7 +1000,8 @@ describe Mastodon::CLI::Accounts do
|
|||
it 'broadcasts the new keys for each account' do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_in)
|
||||
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('rotated')
|
||||
|
||||
accounts.each do |account|
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_in).with(anything, account.id, anything).once
|
||||
|
@ -1071,15 +1079,11 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(from_account).to receive(:destroy)
|
||||
end
|
||||
|
||||
it 'merges "from_account" into "to_account"' do
|
||||
subject
|
||||
it 'merges `from_account` into `to_account` and deletes `from_account`' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(to_account).to have_received(:merge_with!).with(from_account).once
|
||||
end
|
||||
|
||||
it 'deletes "from_account"' do
|
||||
subject
|
||||
|
||||
expect(from_account).to have_received(:destroy).once
|
||||
end
|
||||
end
|
||||
|
@ -1099,15 +1103,11 @@ describe Mastodon::CLI::Accounts do
|
|||
allow(from_account).to receive(:destroy)
|
||||
end
|
||||
|
||||
it 'merges "from_account" into "to_account"' do
|
||||
subject
|
||||
it 'merges "from_account" into "to_account" and deletes from_account' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
expect(to_account).to have_received(:merge_with!).with(from_account).once
|
||||
end
|
||||
|
||||
it 'deletes "from_account"' do
|
||||
subject
|
||||
|
||||
expect(from_account).to have_received(:destroy)
|
||||
end
|
||||
end
|
||||
|
@ -1134,28 +1134,23 @@ describe Mastodon::CLI::Accounts do
|
|||
stub_request(:head, 'https://example.net/users/tales').to_return(status: 200)
|
||||
end
|
||||
|
||||
it 'deletes all inactive remote accounts that longer exist in the origin server' do
|
||||
subject
|
||||
|
||||
def expect_delete_inactive_remote_accounts
|
||||
expect(delete_account_service).to have_received(:call).with(bob, reserve_username: false).once
|
||||
expect(delete_account_service).to have_received(:call).with(gon, reserve_username: false).once
|
||||
end
|
||||
|
||||
it 'does not delete any active remote account that still exists in the origin server' do
|
||||
subject
|
||||
|
||||
def expect_not_delete_active_accounts
|
||||
expect(delete_account_service).to_not have_received(:call).with(tom, reserve_username: false)
|
||||
expect(delete_account_service).to_not have_received(:call).with(ana, reserve_username: false)
|
||||
expect(delete_account_service).to_not have_received(:call).with(tales, reserve_username: false)
|
||||
end
|
||||
|
||||
it 'touches inactive remote accounts that have not been deleted' do
|
||||
expect { subject }.to(change { tales.reload.updated_at })
|
||||
end
|
||||
|
||||
it 'displays the summary correctly' do
|
||||
it 'touches inactive remote accounts that have not been deleted and summarizes activity' do
|
||||
expect { subject }
|
||||
.to output_results('Visited 5 accounts, removed 2')
|
||||
.to change { tales.reload.updated_at }
|
||||
.and output_results('Visited 5 accounts, removed 2')
|
||||
expect_delete_inactive_remote_accounts
|
||||
expect_not_delete_active_accounts
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1168,16 +1163,15 @@ describe Mastodon::CLI::Accounts do
|
|||
stub_request(:head, 'https://example.net/users/tales').to_return(status: 404)
|
||||
end
|
||||
|
||||
it 'deletes inactive remote accounts that longer exist in the specified domain' do
|
||||
subject
|
||||
|
||||
def expect_delete_inactive_remote_accounts
|
||||
expect(delete_account_service).to have_received(:call).with(gon, reserve_username: false).once
|
||||
expect(delete_account_service).to have_received(:call).with(tales, reserve_username: false).once
|
||||
end
|
||||
|
||||
it 'displays the summary correctly' do
|
||||
it 'displays the summary correctly and deletes inactive remote accounts' do
|
||||
expect { subject }
|
||||
.to output_results('Visited 2 accounts, removed 2')
|
||||
expect_delete_inactive_remote_accounts
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1189,15 +1183,14 @@ describe Mastodon::CLI::Accounts do
|
|||
stub_request(:head, 'https://example.net/users/gon').to_return(status: 200)
|
||||
end
|
||||
|
||||
it 'skips accounts from the unavailable domain' do
|
||||
subject
|
||||
|
||||
def expect_skip_accounts_from_unavailable_domain
|
||||
expect(delete_account_service).to_not have_received(:call).with(tales, reserve_username: false)
|
||||
end
|
||||
|
||||
it 'displays the summary correctly' do
|
||||
it 'displays the summary correctly and skip accounts from unavailable domains' do
|
||||
expect { subject }
|
||||
.to output_results("Visited 5 accounts, removed 0\nThe following domains were not available during the check:\n example.net")
|
||||
expect_skip_accounts_from_unavailable_domain
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1268,25 +1261,14 @@ describe Mastodon::CLI::Accounts do
|
|||
|
||||
before do
|
||||
accounts.each { |account| target_account.follow!(account) }
|
||||
end
|
||||
|
||||
it 'resets all "following" relationships from the target account' do
|
||||
subject
|
||||
|
||||
expect(target_account.reload.following).to be_empty
|
||||
end
|
||||
|
||||
it 'calls BootstrapTimelineWorker once to rebuild the timeline' do
|
||||
allow(BootstrapTimelineWorker).to receive(:perform_async)
|
||||
|
||||
subject
|
||||
|
||||
expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once
|
||||
end
|
||||
|
||||
it 'displays a successful message' do
|
||||
it 'resets following relationships and displays a successful message and rebuilds timeline' do
|
||||
expect { subject }
|
||||
.to output_results("Processed #{total_relationships} relationships")
|
||||
expect(target_account.reload.following).to be_empty
|
||||
expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1297,15 +1279,10 @@ describe Mastodon::CLI::Accounts do
|
|||
accounts.each { |account| account.follow!(target_account) }
|
||||
end
|
||||
|
||||
it 'resets all "followers" relationships from the target account' do
|
||||
subject
|
||||
|
||||
expect(target_account.reload.followers).to be_empty
|
||||
end
|
||||
|
||||
it 'displays a successful message' do
|
||||
it 'resets followers relationships and displays a successful message' do
|
||||
expect { subject }
|
||||
.to output_results("Processed #{total_relationships} relationships")
|
||||
expect(target_account.reload.followers).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1315,31 +1292,15 @@ describe Mastodon::CLI::Accounts do
|
|||
before do
|
||||
accounts.first(2).each { |account| account.follow!(target_account) }
|
||||
accounts.last(1).each { |account| target_account.follow!(account) }
|
||||
end
|
||||
|
||||
it 'resets all "followers" relationships from the target account' do
|
||||
subject
|
||||
|
||||
expect(target_account.reload.followers).to be_empty
|
||||
end
|
||||
|
||||
it 'resets all "following" relationships from the target account' do
|
||||
subject
|
||||
|
||||
expect(target_account.reload.following).to be_empty
|
||||
end
|
||||
|
||||
it 'calls BootstrapTimelineWorker once to rebuild the timeline' do
|
||||
allow(BootstrapTimelineWorker).to receive(:perform_async)
|
||||
|
||||
subject
|
||||
|
||||
expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once
|
||||
end
|
||||
|
||||
it 'displays a successful message' do
|
||||
it 'resets followers and following and displays a successful message and rebuilds timeline' do
|
||||
expect { subject }
|
||||
.to output_results("Processed #{total_relationships} relationships")
|
||||
expect(target_account.reload.followers).to be_empty
|
||||
expect(target_account.reload.following).to be_empty
|
||||
expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1360,57 +1321,51 @@ describe Mastodon::CLI::Accounts do
|
|||
stub_parallelize_with_progress!
|
||||
end
|
||||
|
||||
it 'prunes all remote accounts with no interactions with local users' do
|
||||
subject
|
||||
|
||||
def expect_prune_remote_accounts_without_interaction
|
||||
prunable_account_ids = prunable_accounts.pluck(:id)
|
||||
|
||||
expect(Account.where(id: prunable_account_ids).count).to eq(0)
|
||||
end
|
||||
|
||||
it 'displays a successful message' do
|
||||
it 'displays a successful message and handles accounts correctly' do
|
||||
expect { subject }
|
||||
.to output_results("OK, pruned #{prunable_accounts.size} accounts")
|
||||
expect_prune_remote_accounts_without_interaction
|
||||
expect_not_prune_local_accounts
|
||||
expect_not_prune_bot_accounts
|
||||
expect_not_prune_group_accounts
|
||||
expect_not_prune_mentioned_accounts
|
||||
end
|
||||
|
||||
it 'does not prune local accounts' do
|
||||
subject
|
||||
|
||||
def expect_not_prune_local_accounts
|
||||
expect(Account.exists?(id: local_account.id)).to be(true)
|
||||
end
|
||||
|
||||
it 'does not prune bot accounts' do
|
||||
subject
|
||||
|
||||
def expect_not_prune_bot_accounts
|
||||
expect(Account.exists?(id: bot_account.id)).to be(true)
|
||||
end
|
||||
|
||||
it 'does not prune group accounts' do
|
||||
subject
|
||||
|
||||
def expect_not_prune_group_accounts
|
||||
expect(Account.exists?(id: group_account.id)).to be(true)
|
||||
end
|
||||
|
||||
it 'does not prune accounts that have been mentioned' do
|
||||
subject
|
||||
|
||||
def expect_not_prune_mentioned_accounts
|
||||
expect(Account.exists?(id: mentioned_account.id)).to be true
|
||||
end
|
||||
|
||||
context 'with --dry-run option' do
|
||||
let(:options) { { dry_run: true } }
|
||||
|
||||
it 'does not prune any account' do
|
||||
subject
|
||||
|
||||
def expect_no_account_prunes
|
||||
prunable_account_ids = prunable_accounts.pluck(:id)
|
||||
|
||||
expect(Account.where(id: prunable_account_ids).count).to eq(prunable_accounts.size)
|
||||
end
|
||||
|
||||
it 'displays a successful message with (DRY RUN)' do
|
||||
it 'displays a successful message with (DRY RUN) and doesnt prune anything' do
|
||||
expect { subject }
|
||||
.to output_results("OK, pruned #{prunable_accounts.size} accounts (DRY RUN)")
|
||||
expect_no_account_prunes
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1430,7 +1385,8 @@ describe Mastodon::CLI::Accounts do
|
|||
|
||||
shared_examples 'a successful migration' do
|
||||
it 'calls the MoveService for the last migration' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
|
||||
last_migration = source_account.migrations.last
|
||||
|
||||
|
@ -1540,7 +1496,8 @@ describe Mastodon::CLI::Accounts do
|
|||
end
|
||||
|
||||
it 'creates a migration for the specified account with the target account' do
|
||||
subject
|
||||
expect { subject }
|
||||
.to output_results('migrated')
|
||||
|
||||
last_migration = source_account.migrations.last
|
||||
|
||||
|
|
|
@ -33,26 +33,25 @@ describe Mastodon::CLI::IpBlocks do
|
|||
let(:arguments) { ip_list }
|
||||
|
||||
shared_examples 'ip address blocking' do
|
||||
it 'blocks all specified IP addresses' do
|
||||
subject
|
||||
|
||||
blocked_ip_addresses = IpBlock.where(ip: ip_list).pluck(:ip)
|
||||
expected_ip_addresses = ip_list.map { |ip| IPAddr.new(ip) }
|
||||
|
||||
expect(blocked_ip_addresses).to match_array(expected_ip_addresses)
|
||||
def blocked_ip_addresses
|
||||
IpBlock.where(ip: ip_list).pluck(:ip)
|
||||
end
|
||||
|
||||
it 'sets the severity for all blocked IP addresses' do
|
||||
subject
|
||||
|
||||
blocked_ips_severity = IpBlock.where(ip: ip_list).pluck(:severity).all?(options[:severity])
|
||||
|
||||
expect(blocked_ips_severity).to be(true)
|
||||
def expected_ip_addresses
|
||||
ip_list.map { |ip| IPAddr.new(ip) }
|
||||
end
|
||||
|
||||
it 'displays a success message with a summary' do
|
||||
def blocked_ips_severity
|
||||
IpBlock.where(ip: ip_list).pluck(:severity).all?(options[:severity])
|
||||
end
|
||||
|
||||
it 'blocks and sets severity for ip address and displays summary' do
|
||||
expect { subject }
|
||||
.to output_results("Added #{ip_list.size}, skipped 0, failed 0")
|
||||
expect(blocked_ip_addresses)
|
||||
.to match_array(expected_ip_addresses)
|
||||
expect(blocked_ips_severity)
|
||||
.to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -64,17 +63,13 @@ describe Mastodon::CLI::IpBlocks do
|
|||
let!(:blocked_ip) { IpBlock.create(ip: ip_list.last, severity: options[:severity]) }
|
||||
let(:arguments) { ip_list }
|
||||
|
||||
it 'skips the already blocked IP address' do
|
||||
allow(IpBlock).to receive(:new).and_call_original
|
||||
before { allow(IpBlock).to receive(:new).and_call_original }
|
||||
|
||||
subject
|
||||
|
||||
expect(IpBlock).to_not have_received(:new).with(ip: ip_list.last)
|
||||
end
|
||||
|
||||
it 'displays the correct summary' do
|
||||
it 'skips already block ip and displays the correct summary' do
|
||||
expect { subject }
|
||||
.to output_results("#{ip_list.last} is already blocked\nAdded #{ip_list.size - 1}, skipped 1, failed 0")
|
||||
|
||||
expect(IpBlock).to_not have_received(:new).with(ip: ip_list.last)
|
||||
end
|
||||
|
||||
context 'with --force option' do
|
||||
|
@ -83,7 +78,8 @@ describe Mastodon::CLI::IpBlocks do
|
|||
|
||||
it 'overwrites the existing IP block record' do
|
||||
expect { subject }
|
||||
.to change { blocked_ip.reload.severity }
|
||||
.to output_results('Added 11')
|
||||
.and change { blocked_ip.reload.severity }
|
||||
.from('no_access')
|
||||
.to('sign_up_requires_approval')
|
||||
end
|
||||
|
@ -179,15 +175,10 @@ describe Mastodon::CLI::IpBlocks do
|
|||
ip_list.each { |ip| IpBlock.create(ip: ip, severity: :no_access) }
|
||||
end
|
||||
|
||||
it 'removes exact IP blocks' do
|
||||
subject
|
||||
|
||||
expect(IpBlock.where(ip: ip_list)).to_not exist
|
||||
end
|
||||
|
||||
it 'displays success message with a summary' do
|
||||
it 'removes exact ip blocks and displays success message with a summary' do
|
||||
expect { subject }
|
||||
.to output_results("Removed #{ip_list.size}, skipped 0")
|
||||
expect(IpBlock.where(ip: ip_list)).to_not exist
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -198,16 +189,20 @@ describe Mastodon::CLI::IpBlocks do
|
|||
let(:arguments) { ['192.168.0.5', '10.0.1.50'] }
|
||||
let(:options) { { force: true } }
|
||||
|
||||
it 'removes blocks for IP ranges that cover given IP(s)' do
|
||||
subject
|
||||
it 'removes blocks for IP ranges that cover given IP(s) and keeps other ranges' do
|
||||
expect { subject }
|
||||
.to output_results('Removed 2')
|
||||
|
||||
expect(IpBlock.where(id: [first_ip_range_block.id, second_ip_range_block.id])).to_not exist
|
||||
expect(covered_ranges).to_not exist
|
||||
expect(other_ranges).to exist
|
||||
end
|
||||
|
||||
it 'does not remove other IP ranges' do
|
||||
subject
|
||||
def covered_ranges
|
||||
IpBlock.where(id: [first_ip_range_block.id, second_ip_range_block.id])
|
||||
end
|
||||
|
||||
expect(IpBlock.where(id: third_ip_range_block.id)).to exist
|
||||
def other_ranges
|
||||
IpBlock.where(id: third_ip_range_block.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -215,14 +210,12 @@ describe Mastodon::CLI::IpBlocks do
|
|||
let(:unblocked_ip) { '192.0.2.1' }
|
||||
let(:arguments) { [unblocked_ip] }
|
||||
|
||||
it 'skips the IP address' do
|
||||
it 'skips the IP address and displays summary' do
|
||||
expect { subject }
|
||||
.to output_results("#{unblocked_ip} is not yet blocked")
|
||||
end
|
||||
|
||||
it 'displays the summary correctly' do
|
||||
expect { subject }
|
||||
.to output_results('Removed 0, skipped 1')
|
||||
.to output_results(
|
||||
"#{unblocked_ip} is not yet blocked",
|
||||
'Removed 0, skipped 1'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -230,14 +223,12 @@ describe Mastodon::CLI::IpBlocks do
|
|||
let(:invalid_ip) { '320.15.175.0' }
|
||||
let(:arguments) { [invalid_ip] }
|
||||
|
||||
it 'skips the invalid IP address' do
|
||||
it 'skips the invalid IP address and displays summary' do
|
||||
expect { subject }
|
||||
.to output_results("#{invalid_ip} is invalid")
|
||||
end
|
||||
|
||||
it 'displays the summary correctly' do
|
||||
expect { subject }
|
||||
.to output_results('Removed 0, skipped 1')
|
||||
.to output_results(
|
||||
"#{invalid_ip} is invalid",
|
||||
'Removed 0, skipped 1'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -265,7 +256,7 @@ describe Mastodon::CLI::IpBlocks do
|
|||
.to output_results("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
|
||||
end
|
||||
|
||||
it 'does not export bloked IPs with different severities' do
|
||||
it 'does not export blocked IPs with different severities' do
|
||||
expect { subject }
|
||||
.to_not output_results("#{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}")
|
||||
end
|
||||
|
@ -279,7 +270,7 @@ describe Mastodon::CLI::IpBlocks do
|
|||
.to output_results("deny #{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};\ndeny #{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix};")
|
||||
end
|
||||
|
||||
it 'does not export bloked IPs with different severities' do
|
||||
it 'does not export blocked IPs with different severities' do
|
||||
expect { subject }
|
||||
.to_not output_results("deny #{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};")
|
||||
end
|
||||
|
|
|
@ -20,37 +20,30 @@ describe Mastodon::CLI::Settings do
|
|||
describe '#open' do
|
||||
let(:action) { :open }
|
||||
|
||||
it 'changes "registrations_mode" to "open"' do
|
||||
expect { subject }.to change(Setting, :registrations_mode).from(nil).to('open')
|
||||
end
|
||||
|
||||
it 'displays success message' do
|
||||
it 'changes "registrations_mode" to "open" and displays success' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
.to change(Setting, :registrations_mode).from(nil).to('open')
|
||||
.and output_results('OK')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#approved' do
|
||||
let(:action) { :approved }
|
||||
|
||||
it 'changes "registrations_mode" to "approved"' do
|
||||
expect { subject }.to change(Setting, :registrations_mode).from(nil).to('approved')
|
||||
end
|
||||
|
||||
it 'displays success message' do
|
||||
it 'changes "registrations_mode" to "approved" and displays success' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
.to change(Setting, :registrations_mode).from(nil).to('approved')
|
||||
.and output_results('OK')
|
||||
end
|
||||
|
||||
context 'with --require-reason' do
|
||||
let(:options) { { require_reason: true } }
|
||||
|
||||
it 'changes "registrations_mode" to "approved"' do
|
||||
expect { subject }.to change(Setting, :registrations_mode).from(nil).to('approved')
|
||||
end
|
||||
|
||||
it 'sets "require_invite_text" to "true"' do
|
||||
expect { subject }.to change(Setting, :require_invite_text).from(false).to(true)
|
||||
it 'changes registrations_mode and require_invite_text' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
.and change(Setting, :registrations_mode).from(nil).to('approved')
|
||||
.and change(Setting, :require_invite_text).from(false).to(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -58,13 +51,10 @@ describe Mastodon::CLI::Settings do
|
|||
describe '#close' do
|
||||
let(:action) { :close }
|
||||
|
||||
it 'changes "registrations_mode" to "none"' do
|
||||
expect { subject }.to change(Setting, :registrations_mode).from(nil).to('none')
|
||||
end
|
||||
|
||||
it 'displays success message' do
|
||||
it 'changes "registrations_mode" to "none" and displays success' do
|
||||
expect { subject }
|
||||
.to output_results('OK')
|
||||
.to change(Setting, :registrations_mode).from(nil).to('none')
|
||||
.and output_results('OK')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -104,7 +104,6 @@ RSpec.configure do |config|
|
|||
end
|
||||
|
||||
config.before :each, type: :cli do
|
||||
stub_stdout
|
||||
stub_reset_connection_pools
|
||||
end
|
||||
|
||||
|
@ -163,14 +162,6 @@ def attachment_fixture(name)
|
|||
Rails.root.join('spec', 'fixtures', 'files', name).open
|
||||
end
|
||||
|
||||
def stub_stdout
|
||||
# TODO: Is there a bettery way to:
|
||||
# - Avoid CLI command output being printed out
|
||||
# - Allow rspec to assert things against STDOUT
|
||||
# - Avoid disabling stdout for other desirable output (deprecation warnings, for example)
|
||||
allow($stdout).to receive(:write)
|
||||
end
|
||||
|
||||
def stub_reset_connection_pools
|
||||
# TODO: Is there a better way to correctly run specs without stubbing this?
|
||||
# (Avoids reset_connection_pools! in test env)
|
||||
|
|
|
@ -2,20 +2,16 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Accounts::FamiliarFollowersController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:follows') }
|
||||
describe 'Accounts Familiar Followers API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read:follows' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
describe 'GET /api/v1/accounts/familiar_followers' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
get '/api/v1/accounts/familiar_followers', params: { account_id: account.id, limit: 2 }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
@ -26,7 +22,7 @@ describe Api::V1::Accounts::FamiliarFollowersController do
|
|||
|
||||
it 'removes duplicate account IDs from params' do
|
||||
account_ids = [account_a, account_b, account_b, account_a, account_a].map { |a| a.id.to_s }
|
||||
get :index, params: { id: account_ids }
|
||||
get '/api/v1/accounts/familiar_followers', params: { id: account_ids }, headers: headers
|
||||
|
||||
expect(body_as_json.pluck(:id)).to contain_exactly(account_a.id.to_s, account_b.id.to_s)
|
||||
end
|
19
spec/requests/api/v1/accounts/identity_proofs_spec.rb
Normal file
19
spec/requests/api/v1/accounts/identity_proofs_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Accounts Identity Proofs API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read:accounts' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
describe 'GET /api/v1/accounts/identity_proofs' do
|
||||
it 'returns http success' do
|
||||
get "/api/v1/accounts/#{account.id}/identity_proofs", params: { limit: 2 }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
25
spec/requests/api/v1/accounts/lists_spec.rb
Normal file
25
spec/requests/api/v1/accounts/lists_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Accounts Lists API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read:lists' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:list) { Fabricate(:list, account: user.account) }
|
||||
|
||||
before do
|
||||
user.account.follow!(account)
|
||||
list.accounts << account
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/accounts/lists' do
|
||||
it 'returns http success' do
|
||||
get "/api/v1/accounts/#{account.id}/lists", headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
19
spec/requests/api/v1/accounts/lookup_spec.rb
Normal file
19
spec/requests/api/v1/accounts/lookup_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Accounts Lookup API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read:accounts' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
describe 'GET /api/v1/accounts/lookup' do
|
||||
it 'returns http success' do
|
||||
get '/api/v1/accounts/lookup', params: { account_id: account.id, acct: account.acct }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,21 +2,17 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Accounts::NotesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:accounts') }
|
||||
describe 'Accounts Notes API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'write:accounts' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:comment) { 'foo' }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
describe 'POST /api/v1/accounts/:account_id/note' do
|
||||
subject do
|
||||
post :create, params: { account_id: account.id, comment: comment }
|
||||
post "/api/v1/accounts/#{account.id}/note", params: { comment: comment }, headers: headers
|
||||
end
|
||||
|
||||
context 'when account note has reasonable length', :aggregate_failures do
|
41
spec/requests/api/v1/accounts/pins_spec.rb
Normal file
41
spec/requests/api/v1/accounts/pins_spec.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Accounts Pins API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'write:accounts' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:kevin) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
kevin.account.followers << user.account
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/accounts/:account_id/pin' do
|
||||
subject { post "/api/v1/accounts/#{kevin.account.id}/pin", headers: headers }
|
||||
|
||||
it 'creates account_pin', :aggregate_failures do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: user.account, target_account: kevin.account).count }.by(1)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/accounts/:account_id/unpin' do
|
||||
subject { post "/api/v1/accounts/#{kevin.account.id}/unpin", headers: headers }
|
||||
|
||||
before do
|
||||
Fabricate(:account_pin, account: user.account, target_account: kevin.account)
|
||||
end
|
||||
|
||||
it 'destroys account_pin', :aggregate_failures do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: user.account, target_account: kevin.account).count }.by(-1)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,8 +31,8 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
.to have_http_status(200)
|
||||
expect(body_as_json)
|
||||
.to be_an(Enumerable)
|
||||
.and have_attributes(
|
||||
first: include(
|
||||
.and contain_exactly(
|
||||
include(
|
||||
following: true,
|
||||
followed_by: false
|
||||
)
|
||||
|
@ -53,9 +53,11 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
expect(body_as_json)
|
||||
.to be_an(Enumerable)
|
||||
.and have_attributes(
|
||||
size: 2,
|
||||
first: include(simon_item),
|
||||
second: include(lewis_item)
|
||||
size: 2
|
||||
)
|
||||
.and contain_exactly(
|
||||
include(simon_item),
|
||||
include(lewis_item)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -71,10 +73,12 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
expect(body_as_json)
|
||||
.to be_an(Enumerable)
|
||||
.and have_attributes(
|
||||
size: 3,
|
||||
first: include(simon_item),
|
||||
second: include(lewis_item),
|
||||
third: include(bob_item)
|
||||
size: 3
|
||||
)
|
||||
.and contain_exactly(
|
||||
include(simon_item),
|
||||
include(lewis_item),
|
||||
include(bob_item)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -88,9 +92,11 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
expect(body_as_json)
|
||||
.to be_an(Enumerable)
|
||||
.and have_attributes(
|
||||
size: 2,
|
||||
first: include(simon_item),
|
||||
second: include(lewis_item)
|
||||
size: 2
|
||||
)
|
||||
.and contain_exactly(
|
||||
include(simon_item),
|
||||
include(lewis_item)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -116,7 +122,6 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
muting: false,
|
||||
requested: false,
|
||||
domain_blocking: false,
|
||||
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -129,7 +134,6 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
muting: false,
|
||||
requested: false,
|
||||
domain_blocking: false,
|
||||
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -149,8 +153,10 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
expect(body_as_json)
|
||||
.to be_an(Enumerable)
|
||||
.and have_attributes(
|
||||
size: 1,
|
||||
first: include(
|
||||
size: 1
|
||||
)
|
||||
.and contain_exactly(
|
||||
include(
|
||||
following: true,
|
||||
showing_reblogs: true
|
||||
)
|
||||
|
@ -168,8 +174,8 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
|
||||
expect(body_as_json)
|
||||
.to be_an(Enumerable)
|
||||
.and have_attributes(
|
||||
first: include(
|
||||
.and contain_exactly(
|
||||
include(
|
||||
following: false,
|
||||
showing_reblogs: false
|
||||
)
|
||||
|
|
18
spec/requests/api/v1/accounts/search_spec.rb
Normal file
18
spec/requests/api/v1/accounts/search_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Accounts Search API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read:accounts' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/accounts/search' do
|
||||
it 'returns http success' do
|
||||
get '/api/v1/accounts/search', params: { q: 'query' }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
19
spec/requests/api/v1/featured_tags/suggestions_spec.rb
Normal file
19
spec/requests/api/v1/featured_tags/suggestions_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Featured Tags Suggestions API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read:accounts' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
describe 'GET /api/v1/featured_tags/suggestions' do
|
||||
it 'returns http success' do
|
||||
get '/api/v1/featured_tags/suggestions', params: { account_id: account.id, limit: 2 }, headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
18
spec/requests/api/v2/suggestions_spec.rb
Normal file
18
spec/requests/api/v2/suggestions_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Suggestions API' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v2/suggestions' do
|
||||
it 'returns http success' do
|
||||
get '/api/v2/suggestions', headers: headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,13 +11,14 @@ RSpec.describe FanOutOnWriteService, type: :service do
|
|||
let(:visibility) { 'public' }
|
||||
let(:searchability) { 'public' }
|
||||
let(:subscription_policy) { :allow }
|
||||
let(:status) { Fabricate(:status, account: alice, visibility: visibility, searchability: searchability, text: 'Hello @bob #hoge') }
|
||||
let(:status) { Fabricate(:status, account: alice, visibility: visibility, searchability: searchability, text: 'Hello @bob @eve #hoge') }
|
||||
|
||||
let!(:alice) { Fabricate(:user, current_sign_in_at: last_active_at, account_attributes: { master_settings: { subscription_policy: subscription_policy } }).account }
|
||||
let!(:bob) { Fabricate(:user, current_sign_in_at: last_active_at, account_attributes: { username: 'bob' }).account }
|
||||
let!(:tom) { Fabricate(:user, current_sign_in_at: last_active_at).account }
|
||||
let!(:ohagi) { Fabricate(:user, current_sign_in_at: last_active_at).account }
|
||||
let!(:tagf) { Fabricate(:user, current_sign_in_at: last_active_at).account }
|
||||
let!(:eve) { Fabricate(:user, current_sign_in_at: last_active_at, account_attributes: { username: 'eve' }).account }
|
||||
|
||||
let!(:list) { nil }
|
||||
let!(:empty_list) { nil }
|
||||
|
@ -256,6 +257,25 @@ RSpec.describe FanOutOnWriteService, type: :service do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when handling status updates', :sidekiq_fake do
|
||||
before do
|
||||
subject.call(status)
|
||||
|
||||
status.snapshot!(at_time: status.created_at, rate_limit: false)
|
||||
status.update!(text: 'Hello @bob @eve #hoge (edited)')
|
||||
status.snapshot!(account_id: status.account_id)
|
||||
|
||||
redis.set("subscribed:timeline:#{eve.id}:notifications", '1')
|
||||
|
||||
Sidekiq::Worker.clear_all
|
||||
end
|
||||
|
||||
it 'pushes the update to mentioned users through the notifications streaming channel' do
|
||||
subject.call(status, update: true)
|
||||
expect(PushUpdateWorker).to have_enqueued_sidekiq_job(anything, status.id, "timeline:#{eve.id}:notifications", { 'update' => true })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is limited' do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue