diff options
Diffstat (limited to 'spec/controllers')
42 files changed, 1009 insertions, 195 deletions
diff --git a/spec/controllers/admin/account_moderation_notes_controller_spec.rb b/spec/controllers/admin/account_moderation_notes_controller_spec.rb index 410ce6543..d3f3263f8 100644 --- a/spec/controllers/admin/account_moderation_notes_controller_spec.rb +++ b/spec/controllers/admin/account_moderation_notes_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Admin::AccountModerationNotesController, type: :controller do render_views - let(:user) { Fabricate(:user, admin: true) } + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } let(:target_account) { Fabricate(:account) } before do diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb index 1779fb7c0..1bd51a0c8 100644 --- a/spec/controllers/admin/accounts_controller_spec.rb +++ b/spec/controllers/admin/accounts_controller_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Admin::AccountsController, type: :controller do before { sign_in current_user, scope: :user } describe 'GET #index' do - let(:current_user) { Fabricate(:user, admin: true) } + let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } around do |example| default_per_page = Account.default_per_page @@ -60,7 +60,7 @@ RSpec.describe Admin::AccountsController, type: :controller do end describe 'GET #show' do - let(:current_user) { Fabricate(:user, admin: true) } + let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } let(:account) { Fabricate(:account) } it 'returns http success' do @@ -72,15 +72,15 @@ RSpec.describe Admin::AccountsController, type: :controller do describe 'POST #memorialize' do subject { post :memorialize, params: { id: account.id } } - let(:current_user) { Fabricate(:user, admin: current_user_admin) } + let(:current_user) { Fabricate(:user, role: current_role) } let(:account) { user.account } - let(:user) { Fabricate(:user, admin: target_user_admin) } + let(:user) { Fabricate(:user, role: target_role) } context 'when user is admin' do - let(:current_user_admin) { true } + let(:current_role) { UserRole.find_by(name: 'Admin') } context 'when target user is admin' do - let(:target_user_admin) { true } + let(:target_role) { UserRole.find_by(name: 'Admin') } it 'fails to memorialize account' do is_expected.to have_http_status :forbidden @@ -89,7 +89,7 @@ RSpec.describe Admin::AccountsController, type: :controller do end context 'when target user is not admin' do - let(:target_user_admin) { false } + let(:target_role) { UserRole.find_by(name: 'Moderator') } it 'succeeds in memorializing account' do is_expected.to redirect_to admin_account_path(account.id) @@ -99,10 +99,10 @@ RSpec.describe Admin::AccountsController, type: :controller do end context 'when user is not admin' do - let(:current_user_admin) { false } + let(:current_role) { UserRole.find_by(name: 'Moderator') } context 'when target user is admin' do - let(:target_user_admin) { true } + let(:target_role) { UserRole.find_by(name: 'Admin') } it 'fails to memorialize account' do is_expected.to have_http_status :forbidden @@ -111,7 +111,7 @@ RSpec.describe Admin::AccountsController, type: :controller do end context 'when target user is not admin' do - let(:target_user_admin) { false } + let(:target_role) { UserRole.find_by(name: 'Moderator') } it 'fails to memorialize account' do is_expected.to have_http_status :forbidden @@ -124,12 +124,12 @@ RSpec.describe Admin::AccountsController, type: :controller do describe 'POST #enable' do subject { post :enable, params: { id: account.id } } - let(:current_user) { Fabricate(:user, admin: admin) } + let(:current_user) { Fabricate(:user, role: role) } let(:account) { user.account } let(:user) { Fabricate(:user, disabled: true) } context 'when user is admin' do - let(:admin) { true } + let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in enabling account' do is_expected.to redirect_to admin_account_path(account.id) @@ -138,7 +138,7 @@ RSpec.describe Admin::AccountsController, type: :controller do end context 'when user is not admin' do - let(:admin) { false } + let(:role) { UserRole.everyone } it 'fails to enable account' do is_expected.to have_http_status :forbidden @@ -150,19 +150,23 @@ RSpec.describe Admin::AccountsController, type: :controller do describe 'POST #redownload' do subject { post :redownload, params: { id: account.id } } - let(:current_user) { Fabricate(:user, admin: admin) } - let(:account) { Fabricate(:account) } + let(:current_user) { Fabricate(:user, role: role) } + let(:account) { Fabricate(:account, domain: 'example.com') } + + before do + allow_any_instance_of(ResolveAccountService).to receive(:call) + end context 'when user is admin' do - let(:admin) { true } + let(:role) { UserRole.find_by(name: 'Admin') } - it 'succeeds in redownloadin' do + it 'succeeds in redownloading' do is_expected.to redirect_to admin_account_path(account.id) end end context 'when user is not admin' do - let(:admin) { false } + let(:role) { UserRole.everyone } it 'fails to redownload' do is_expected.to have_http_status :forbidden @@ -173,11 +177,11 @@ RSpec.describe Admin::AccountsController, type: :controller do describe 'POST #remove_avatar' do subject { post :remove_avatar, params: { id: account.id } } - let(:current_user) { Fabricate(:user, admin: admin) } + let(:current_user) { Fabricate(:user, role: role) } let(:account) { Fabricate(:account) } context 'when user is admin' do - let(:admin) { true } + let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in removing avatar' do is_expected.to redirect_to admin_account_path(account.id) @@ -185,7 +189,7 @@ RSpec.describe Admin::AccountsController, type: :controller do end context 'when user is not admin' do - let(:admin) { false } + let(:role) { UserRole.everyone } it 'fails to remove avatar' do is_expected.to have_http_status :forbidden @@ -196,12 +200,12 @@ RSpec.describe Admin::AccountsController, type: :controller do describe 'POST #unblock_email' do subject { post :unblock_email, params: { id: account.id } } - let(:current_user) { Fabricate(:user, admin: admin) } + let(:current_user) { Fabricate(:user, role: role) } 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 } + let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in removing email blocks' do expect { subject }.to change { CanonicalEmailBlock.where(reference_account: account).count }.from(1).to(0) @@ -214,7 +218,7 @@ RSpec.describe Admin::AccountsController, type: :controller do end context 'when user is not admin' do - let(:admin) { false } + let(:role) { UserRole.everyone } it 'fails to remove avatar' do subject diff --git a/spec/controllers/admin/action_logs_controller_spec.rb b/spec/controllers/admin/action_logs_controller_spec.rb index 4720ed2e2..c1957258f 100644 --- a/spec/controllers/admin/action_logs_controller_spec.rb +++ b/spec/controllers/admin/action_logs_controller_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' describe Admin::ActionLogsController, type: :controller do describe 'GET #index' do it 'returns 200' do - sign_in Fabricate(:user, admin: true) + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')) get :index, params: { page: 1 } expect(response).to have_http_status(200) diff --git a/spec/controllers/admin/base_controller_spec.rb b/spec/controllers/admin/base_controller_spec.rb index 9ac833623..44be91951 100644 --- a/spec/controllers/admin/base_controller_spec.rb +++ b/spec/controllers/admin/base_controller_spec.rb @@ -5,13 +5,14 @@ require 'rails_helper' describe Admin::BaseController, type: :controller do controller do def success + authorize :dashboard, :index? render 'admin/reports/show' end end it 'requires administrator or moderator' do routes.draw { get 'success' => 'admin/base#success' } - sign_in(Fabricate(:user, admin: false, moderator: false)) + sign_in(Fabricate(:user)) get :success expect(response).to have_http_status(:forbidden) @@ -19,14 +20,14 @@ describe Admin::BaseController, type: :controller do it 'renders admin layout as a moderator' do routes.draw { get 'success' => 'admin/base#success' } - sign_in(Fabricate(:user, moderator: true)) + sign_in(Fabricate(:user, role: UserRole.find_by(name: 'Moderator'))) get :success expect(response).to render_template layout: 'admin' end it 'renders admin layout as an admin' do routes.draw { get 'success' => 'admin/base#success' } - sign_in(Fabricate(:user, admin: true)) + sign_in(Fabricate(:user, role: UserRole.find_by(name: 'Admin'))) get :success expect(response).to render_template layout: 'admin' end diff --git a/spec/controllers/admin/change_email_controller_spec.rb b/spec/controllers/admin/change_email_controller_spec.rb index e7f3f7c97..cf8a27d39 100644 --- a/spec/controllers/admin/change_email_controller_spec.rb +++ b/spec/controllers/admin/change_email_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Admin::ChangeEmailsController, type: :controller do render_views - let(:admin) { Fabricate(:user, admin: true) } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do sign_in admin diff --git a/spec/controllers/admin/confirmations_controller_spec.rb b/spec/controllers/admin/confirmations_controller_spec.rb index 5b4f7e925..6268903c4 100644 --- a/spec/controllers/admin/confirmations_controller_spec.rb +++ b/spec/controllers/admin/confirmations_controller_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Admin::ConfirmationsController, type: :controller do render_views before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'POST #create' do diff --git a/spec/controllers/admin/custom_emojis_controller_spec.rb b/spec/controllers/admin/custom_emojis_controller_spec.rb index a8d96948c..06cd0c22d 100644 --- a/spec/controllers/admin/custom_emojis_controller_spec.rb +++ b/spec/controllers/admin/custom_emojis_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Admin::CustomEmojisController do render_views - let(:user) { Fabricate(:user, admin: true) } + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do sign_in user, scope: :user diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb index 7824854f9..6231a09a2 100644 --- a/spec/controllers/admin/dashboard_controller_spec.rb +++ b/spec/controllers/admin/dashboard_controller_spec.rb @@ -12,7 +12,7 @@ describe Admin::DashboardController, type: :controller do Admin::SystemCheck::Message.new(:rules_check, nil, admin_rules_path), Admin::SystemCheck::Message.new(:sidekiq_process_check, 'foo, bar'), ]) - sign_in Fabricate(:user, admin: true) + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')) end it 'returns 200' do diff --git a/spec/controllers/admin/disputes/appeals_controller_spec.rb b/spec/controllers/admin/disputes/appeals_controller_spec.rb index 6a06f9406..712657791 100644 --- a/spec/controllers/admin/disputes/appeals_controller_spec.rb +++ b/spec/controllers/admin/disputes/appeals_controller_spec.rb @@ -14,7 +14,7 @@ RSpec.describe Admin::Disputes::AppealsController, type: :controller do end describe 'POST #approve' do - let(:current_user) { Fabricate(:user, admin: true) } + let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do allow(UserMailer).to receive(:appeal_approved).and_return(double('email', deliver_later: nil)) @@ -35,7 +35,7 @@ RSpec.describe Admin::Disputes::AppealsController, type: :controller do end describe 'POST #reject' do - let(:current_user) { Fabricate(:user, admin: true) } + let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do allow(UserMailer).to receive(:appeal_rejected).and_return(double('email', deliver_later: nil)) diff --git a/spec/controllers/admin/domain_allows_controller_spec.rb b/spec/controllers/admin/domain_allows_controller_spec.rb index 8bacdd3e4..6c4e67787 100644 --- a/spec/controllers/admin/domain_allows_controller_spec.rb +++ b/spec/controllers/admin/domain_allows_controller_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Admin::DomainAllowsController, type: :controller do render_views before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'GET #new' do diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb index a35b2fb3b..98cda5004 100644 --- a/spec/controllers/admin/domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/domain_blocks_controller_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do render_views before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'GET #new' do diff --git a/spec/controllers/admin/email_domain_blocks_controller_spec.rb b/spec/controllers/admin/email_domain_blocks_controller_spec.rb index cf194579d..e9cef4a94 100644 --- a/spec/controllers/admin/email_domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/email_domain_blocks_controller_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Admin::EmailDomainBlocksController, type: :controller do render_views before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'GET #index' do diff --git a/spec/controllers/admin/export_domain_allows_controller_spec.rb b/spec/controllers/admin/export_domain_allows_controller_spec.rb index f6275c2d6..1e1a5ae7d 100644 --- a/spec/controllers/admin/export_domain_allows_controller_spec.rb +++ b/spec/controllers/admin/export_domain_allows_controller_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Admin::ExportDomainAllowsController, type: :controller do render_views before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'GET #export' do diff --git a/spec/controllers/admin/export_domain_blocks_controller_spec.rb b/spec/controllers/admin/export_domain_blocks_controller_spec.rb index 0493df859..8697e0c21 100644 --- a/spec/controllers/admin/export_domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/export_domain_blocks_controller_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Admin::ExportDomainBlocksController, type: :controller do render_views before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'GET #export' do diff --git a/spec/controllers/admin/instances_controller_spec.rb b/spec/controllers/admin/instances_controller_spec.rb index 53427b874..337f7a80c 100644 --- a/spec/controllers/admin/instances_controller_spec.rb +++ b/spec/controllers/admin/instances_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Admin::InstancesController, type: :controller do render_views - let(:current_user) { Fabricate(:user, admin: true) } + let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } let!(:account) { Fabricate(:account, domain: 'popular') } let!(:account2) { Fabricate(:account, domain: 'popular') } @@ -35,11 +35,11 @@ RSpec.describe Admin::InstancesController, type: :controller do describe 'DELETE #destroy' do subject { delete :destroy, params: { id: Instance.first.id } } - let(:current_user) { Fabricate(:user, admin: admin) } + let(:current_user) { Fabricate(:user, role: role) } let(:account) { Fabricate(:account) } context 'when user is admin' do - let(:admin) { true } + let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in purging instance' do is_expected.to redirect_to admin_instances_path @@ -47,7 +47,7 @@ RSpec.describe Admin::InstancesController, type: :controller do end context 'when user is not admin' do - let(:admin) { false } + let(:role) { nil } it 'fails to purge instance' do is_expected.to have_http_status :forbidden diff --git a/spec/controllers/admin/invites_controller_spec.rb b/spec/controllers/admin/invites_controller_spec.rb index 449a699e4..1fb488742 100644 --- a/spec/controllers/admin/invites_controller_spec.rb +++ b/spec/controllers/admin/invites_controller_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' describe Admin::InvitesController do render_views - let(:user) { Fabricate(:user, admin: true) } + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do sign_in user, scope: :user diff --git a/spec/controllers/admin/report_notes_controller_spec.rb b/spec/controllers/admin/report_notes_controller_spec.rb index c0013f41a..fa7572d18 100644 --- a/spec/controllers/admin/report_notes_controller_spec.rb +++ b/spec/controllers/admin/report_notes_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Admin::ReportNotesController do render_views - let(:user) { Fabricate(:user, admin: true) } + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do sign_in user, scope: :user diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb index d421f0739..4cd1524bf 100644 --- a/spec/controllers/admin/reports_controller_spec.rb +++ b/spec/controllers/admin/reports_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Admin::ReportsController do render_views - let(:user) { Fabricate(:user, admin: true) } + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do sign_in user, scope: :user end diff --git a/spec/controllers/admin/resets_controller_spec.rb b/spec/controllers/admin/resets_controller_spec.rb index 28510b5af..aeb172318 100644 --- a/spec/controllers/admin/resets_controller_spec.rb +++ b/spec/controllers/admin/resets_controller_spec.rb @@ -5,7 +5,7 @@ describe Admin::ResetsController do let(:account) { Fabricate(:account) } before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'POST #create' do diff --git a/spec/controllers/admin/roles_controller_spec.rb b/spec/controllers/admin/roles_controller_spec.rb index 8e0de73cb..8ff891205 100644 --- a/spec/controllers/admin/roles_controller_spec.rb +++ b/spec/controllers/admin/roles_controller_spec.rb @@ -3,31 +3,247 @@ require 'rails_helper' describe Admin::RolesController do render_views - let(:admin) { Fabricate(:user, admin: true) } + let(:permissions) { UserRole::Flags::NONE } + let(:current_role) { UserRole.create(name: 'Foo', permissions: permissions, position: 10) } + let(:current_user) { Fabricate(:user, role: current_role) } before do - sign_in admin, scope: :user + sign_in current_user, scope: :user end - describe 'POST #promote' do - subject { post :promote, params: { account_id: user.account_id } } + describe 'GET #index' do + before do + get :index + end + + context 'when user does not have permission to manage roles' do + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + end - let(:user) { Fabricate(:user, moderator: false, admin: false) } + context 'when user has permission to manage roles' do + let(:permissions) { UserRole::FLAGS[:manage_roles] } - it 'promotes user' do - expect(subject).to redirect_to admin_account_path(user.account_id) - expect(user.reload).to be_moderator + it 'returns http success' do + expect(response).to have_http_status(:success) + end end end - describe 'POST #demote' do - subject { post :demote, params: { account_id: user.account_id } } + describe 'GET #new' do + before do + get :new + end + + context 'when user does not have permission to manage roles' do + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + end + + context 'when user has permission to manage roles' do + let(:permissions) { UserRole::FLAGS[:manage_roles] } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + end + end + + describe 'POST #create' do + let(:selected_position) { 1 } + let(:selected_permissions_as_keys) { %w(manage_roles) } + + before do + post :create, params: { user_role: { name: 'Bar', position: selected_position, permissions_as_keys: selected_permissions_as_keys } } + end + + context 'when user has permission to manage roles' do + let(:permissions) { UserRole::FLAGS[:manage_roles] } + + context 'when new role\'s does not elevate above the user\'s role' do + let(:selected_position) { 1 } + let(:selected_permissions_as_keys) { %w(manage_roles) } + + it 'redirects to roles page' do + expect(response).to redirect_to(admin_roles_path) + end + + it 'creates new role' do + expect(UserRole.find_by(name: 'Bar')).to_not be_nil + end + end + + context 'when new role\'s position is higher than user\'s role' do + let(:selected_position) { 100 } + let(:selected_permissions_as_keys) { %w(manage_roles) } + + it 'renders new template' do + expect(response).to render_template(:new) + end + + it 'does not create new role' do + expect(UserRole.find_by(name: 'Bar')).to be_nil + end + end + + context 'when new role has permissions the user does not have' do + let(:selected_position) { 1 } + let(:selected_permissions_as_keys) { %w(manage_roles manage_users manage_reports) } + + it 'renders new template' do + expect(response).to render_template(:new) + end + + it 'does not create new role' do + expect(UserRole.find_by(name: 'Bar')).to be_nil + end + end + + context 'when user has administrator permission' do + let(:permissions) { UserRole::FLAGS[:administrator] } + + let(:selected_position) { 1 } + let(:selected_permissions_as_keys) { %w(manage_roles manage_users manage_reports) } + + it 'redirects to roles page' do + expect(response).to redirect_to(admin_roles_path) + end + + it 'creates new role' do + expect(UserRole.find_by(name: 'Bar')).to_not be_nil + end + end + end + end + + describe 'GET #edit' do + let(:role_position) { 8 } + let(:role) { UserRole.create(name: 'Bar', permissions: UserRole::FLAGS[:manage_users], position: role_position) } + + before do + get :edit, params: { id: role.id } + end + + context 'when user does not have permission to manage roles' do + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + end + + context 'when user has permission to manage roles' do + let(:permissions) { UserRole::FLAGS[:manage_roles] } + + context 'when user outranks the role' do + it 'returns http success' do + expect(response).to have_http_status(:success) + end + end + + context 'when role outranks user' do + let(:role_position) { current_role.position + 1 } + + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + end + end + end + + describe 'PUT #update' do + let(:role_position) { 8 } + let(:role_permissions) { UserRole::FLAGS[:manage_users] } + let(:role) { UserRole.create(name: 'Bar', permissions: role_permissions, position: role_position) } + + let(:selected_position) { 8 } + let(:selected_permissions_as_keys) { %w(manage_users) } + + before do + put :update, params: { id: role.id, user_role: { name: 'Baz', position: selected_position, permissions_as_keys: selected_permissions_as_keys } } + end + + context 'when user does not have permission to manage roles' do + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + + it 'does not update the role' do + expect(role.reload.name).to eq 'Bar' + end + end + + context 'when user has permission to manage roles' do + let(:permissions) { UserRole::FLAGS[:manage_roles] } + + context 'when role has permissions the user doesn\'t' do + it 'renders edit template' do + expect(response).to render_template(:edit) + end + + it 'does not update the role' do + expect(role.reload.name).to eq 'Bar' + end + end + + context 'when user has all permissions of the role' do + let(:permissions) { UserRole::FLAGS[:manage_roles] | UserRole::FLAGS[:manage_users] } + + context 'when user outranks the role' do + it 'redirects to roles page' do + expect(response).to redirect_to(admin_roles_path) + end + + it 'updates the role' do + expect(role.reload.name).to eq 'Baz' + end + end + + context 'when role outranks user' do + let(:role_position) { current_role.position + 1 } + + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + + it 'does not update the role' do + expect(role.reload.name).to eq 'Bar' + end + end + end + end + end + + describe 'DELETE #destroy' do + let(:role_position) { 8 } + let(:role) { UserRole.create(name: 'Bar', permissions: UserRole::FLAGS[:manage_users], position: role_position) } + + before do + delete :destroy, params: { id: role.id } + end + + context 'when user does not have permission to manage roles' do + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + end + + context 'when user has permission to manage roles' do + let(:permissions) { UserRole::FLAGS[:manage_roles] } + + context 'when user outranks the role' do + it 'redirects to roles page' do + expect(response).to redirect_to(admin_roles_path) + end + end - let(:user) { Fabricate(:user, moderator: true, admin: false) } + context 'when role outranks user' do + let(:role_position) { current_role.position + 1 } - it 'demotes user' do - expect(subject).to redirect_to admin_account_path(user.account_id) - expect(user.reload).not_to be_moderator + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + end end end end diff --git a/spec/controllers/admin/settings_controller_spec.rb b/spec/controllers/admin/settings_controller_spec.rb index 6cf0ee20a..46749f76c 100644 --- a/spec/controllers/admin/settings_controller_spec.rb +++ b/spec/controllers/admin/settings_controller_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Admin::SettingsController, type: :controller do describe 'When signed in as an admin' do before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'GET #edit' do diff --git a/spec/controllers/admin/statuses_controller_spec.rb b/spec/controllers/admin/statuses_controller_spec.rb index de32fd18e..227688e23 100644 --- a/spec/controllers/admin/statuses_controller_spec.rb +++ b/spec/controllers/admin/statuses_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Admin::StatusesController do render_views - let(:user) { Fabricate(:user, admin: true) } + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } let(:account) { Fabricate(:account) } let!(:status) { Fabricate(:status, account: account) } let(:media_attached_status) { Fabricate(:status, account: account, sensitive: !sensitive) } diff --git a/spec/controllers/admin/tags_controller_spec.rb b/spec/controllers/admin/tags_controller_spec.rb index 85c801a9c..52fd09eb1 100644 --- a/spec/controllers/admin/tags_controller_spec.rb +++ b/spec/controllers/admin/tags_controller_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Admin::TagsController, type: :controller do render_views before do - sign_in Fabricate(:user, admin: true) + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')) end describe 'GET #show' do diff --git a/spec/controllers/admin/users/roles_controller.rb b/spec/controllers/admin/users/roles_controller.rb new file mode 100644 index 000000000..bd6a3fa67 --- /dev/null +++ b/spec/controllers/admin/users/roles_controller.rb @@ -0,0 +1,81 @@ +require 'rails_helper' + +describe Admin::Users::RolesController do + render_views + + let(:current_role) { UserRole.create(name: 'Foo', permissions: UserRole::FLAGS[:manage_roles], position: 10) } + let(:current_user) { Fabricate(:user, role: current_role) } + + let(:previous_role) { nil } + let(:user) { Fabricate(:user, role: previous_role) } + + before do + sign_in current_user, scope: :user + end + + describe 'GET #show' do + before do + get :show, params: { user_id: user.id } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + context 'when target user is higher ranked than current user' do + let(:previous_role) { UserRole.create(name: 'Baz', permissions: UserRole::FLAGS[:administrator], position: 100) } + + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + end + end + + describe 'PUT #update' do + let(:selected_role) { UserRole.create(name: 'Bar', permissions: permissions, position: position) } + + before do + put :update, params: { user_id: user.id, user: { role_id: selected_role.id } } + end + + context do + let(:permissions) { UserRole::FLAGS[:manage_roles] } + let(:position) { 1 } + + it 'updates user role' do + expect(user.reload.role_id).to eq selected_role&.id + end + + it 'redirects back to account page' do + expect(response).to redirect_to(admin_account_path(user.account_id)) + end + end + + context 'when selected role has higher position than current user\'s role' do + let(:permissions) { UserRole::FLAGS[:administrator] } + let(:position) { 100 } + + it 'does not update user role' do + expect(user.reload.role_id).to eq previous_role&.id + end + + it 'renders edit form' do + expect(response).to render_template(:show) + end + end + + context 'when target user is higher ranked than current user' do + let(:previous_role) { UserRole.create(name: 'Baz', permissions: UserRole::FLAGS[:administrator], position: 100) } + let(:permissions) { UserRole::FLAGS[:manage_roles] } + let(:position) { 1 } + + it 'does not update user role' do + expect(user.reload.role_id).to eq previous_role&.id + end + + it 'returns http forbidden' do + expect(response).to have_http_status(:forbidden) + end + end + end +end diff --git a/spec/controllers/admin/two_factor_authentications_controller_spec.rb b/spec/controllers/admin/users/two_factor_authentications_controller_spec.rb index c65095729..e56264ef6 100644 --- a/spec/controllers/admin/two_factor_authentications_controller_spec.rb +++ b/spec/controllers/admin/users/two_factor_authentications_controller_spec.rb @@ -1,12 +1,13 @@ require 'rails_helper' require 'webauthn/fake_client' -describe Admin::TwoFactorAuthenticationsController do +describe Admin::Users::TwoFactorAuthenticationsController do render_views let(:user) { Fabricate(:user) } + before do - sign_in Fabricate(:user, admin: true), scope: :user + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end describe 'DELETE #destroy' do diff --git a/spec/controllers/api/v1/admin/account_actions_controller_spec.rb b/spec/controllers/api/v1/admin/account_actions_controller_spec.rb index 601290b82..199395f55 100644 --- a/spec/controllers/api/v1/admin/account_actions_controller_spec.rb +++ b/spec/controllers/api/v1/admin/account_actions_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Api::V1::Admin::AccountActionsController, type: :controller do render_views - let(:role) { 'moderator' } + let(:role) { UserRole.find_by(name: 'Moderator') } let(:user) { Fabricate(:user, role: role) } let(:scopes) { 'admin:read admin:write' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } @@ -22,7 +22,7 @@ RSpec.describe Api::V1::Admin::AccountActionsController, type: :controller do end shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { wrong_role } + let(:role) { UserRole.find_by(name: wrong_role) } it 'returns http forbidden' do expect(response).to have_http_status(403) @@ -35,7 +35,7 @@ RSpec.describe Api::V1::Admin::AccountActionsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) diff --git a/spec/controllers/api/v1/admin/accounts_controller_spec.rb b/spec/controllers/api/v1/admin/accounts_controller_spec.rb index b69595f7e..cd38030e0 100644 --- a/spec/controllers/api/v1/admin/accounts_controller_spec.rb +++ b/spec/controllers/api/v1/admin/accounts_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Api::V1::Admin::AccountsController, type: :controller do render_views - let(:role) { 'moderator' } + let(:role) { UserRole.find_by(name: 'Moderator') } let(:user) { Fabricate(:user, role: role) } let(:scopes) { 'admin:read admin:write' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } @@ -22,7 +22,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { wrong_role } + let(:role) { UserRole.find_by(name: wrong_role) } it 'returns http forbidden' do expect(response).to have_http_status(403) @@ -46,7 +46,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' [ [{ active: 'true', local: 'true', staff: 'true' }, [:admin_account]], @@ -77,7 +77,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -91,7 +91,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -109,7 +109,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -127,7 +127,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -145,7 +145,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -163,7 +163,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -181,7 +181,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) diff --git a/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb b/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb new file mode 100644 index 000000000..26a391a60 --- /dev/null +++ b/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb @@ -0,0 +1,118 @@ +require 'rails_helper' + +RSpec.describe Api::V1::Admin::DomainAllowsController, type: :controller do + render_views + + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read admin:write' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + shared_examples 'forbidden for wrong scope' do |wrong_scope| + let(:scopes) { wrong_scope } + + it 'returns http forbidden' do + expect(response).to have_http_status(403) + end + end + + shared_examples 'forbidden for wrong role' do |wrong_role| + let(:role) { UserRole.find_by(name: wrong_role) } + + it 'returns http forbidden' do + expect(response).to have_http_status(403) + end + end + + describe 'GET #index' do + let!(:domain_allow) { Fabricate(:domain_allow) } + + before do + get :index + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns the expected domain allows' do + json = body_as_json + expect(json.length).to eq 1 + expect(json[0][:id].to_i).to eq domain_allow.id + end + end + + describe 'GET #show' do + let!(:domain_allow) { Fabricate(:domain_allow) } + + before do + get :show, params: { id: domain_allow.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns expected domain name' do + json = body_as_json + expect(json[:domain]).to eq domain_allow.domain + end + end + + describe 'DELETE #destroy' do + let!(:domain_allow) { Fabricate(:domain_allow) } + + before do + delete :destroy, params: { id: domain_allow.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'deletes the block' do + expect(DomainAllow.find_by(id: domain_allow.id)).to be_nil + end + end + + describe 'POST #create' do + let!(:domain_allow) { Fabricate(:domain_allow, domain: 'example.com') } + + before do + post :create, params: { domain: 'foo.bar.com' } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns expected domain name' do + json = body_as_json + expect(json[:domain]).to eq 'foo.bar.com' + end + + it 'creates a domain block' do + expect(DomainAllow.find_by(domain: 'foo.bar.com')).to_not be_nil + end + end +end diff --git a/spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb b/spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb index 196f6dc28..f12285b2a 100644 --- a/spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb +++ b/spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Api::V1::Admin::DomainBlocksController, type: :controller do render_views - let(:role) { 'admin' } + let(:role) { UserRole.find_by(name: 'Admin') } let(:user) { Fabricate(:user, role: role) } let(:scopes) { 'admin:read admin:write' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } @@ -21,7 +21,7 @@ RSpec.describe Api::V1::Admin::DomainBlocksController, type: :controller do end shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { wrong_role } + let(:role) { UserRole.find_by(name: wrong_role) } it 'returns http forbidden' do expect(response).to have_http_status(403) @@ -36,8 +36,8 @@ RSpec.describe Api::V1::Admin::DomainBlocksController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' - it_behaves_like 'forbidden for wrong role', 'moderator' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' it 'returns http success' do expect(response).to have_http_status(200) @@ -58,8 +58,8 @@ RSpec.describe Api::V1::Admin::DomainBlocksController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' - it_behaves_like 'forbidden for wrong role', 'moderator' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' it 'returns http success' do expect(response).to have_http_status(200) @@ -79,8 +79,8 @@ RSpec.describe Api::V1::Admin::DomainBlocksController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' - it_behaves_like 'forbidden for wrong role', 'moderator' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' it 'returns http success' do expect(response).to have_http_status(200) @@ -100,8 +100,8 @@ RSpec.describe Api::V1::Admin::DomainBlocksController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' - it_behaves_like 'forbidden for wrong role', 'moderator' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' it 'returns http success' do expect(response).to have_http_status(200) diff --git a/spec/controllers/api/v1/admin/reports_controller_spec.rb b/spec/controllers/api/v1/admin/reports_controller_spec.rb index b6df53048..880e72030 100644 --- a/spec/controllers/api/v1/admin/reports_controller_spec.rb +++ b/spec/controllers/api/v1/admin/reports_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Api::V1::Admin::ReportsController, type: :controller do render_views - let(:role) { 'moderator' } + let(:role) { UserRole.find_by(name: 'Moderator') } let(:user) { Fabricate(:user, role: role) } let(:scopes) { 'admin:read admin:write' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } @@ -22,7 +22,7 @@ RSpec.describe Api::V1::Admin::ReportsController, type: :controller do end shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { wrong_role } + let(:role) { UserRole.find_by(name: wrong_role) } it 'returns http forbidden' do expect(response).to have_http_status(403) @@ -35,7 +35,7 @@ RSpec.describe Api::V1::Admin::ReportsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -48,7 +48,7 @@ RSpec.describe Api::V1::Admin::ReportsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -61,7 +61,7 @@ RSpec.describe Api::V1::Admin::ReportsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -74,7 +74,7 @@ RSpec.describe Api::V1::Admin::ReportsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -87,7 +87,7 @@ RSpec.describe Api::V1::Admin::ReportsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) @@ -100,7 +100,7 @@ RSpec.describe Api::V1::Admin::ReportsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do expect(response).to have_http_status(200) diff --git a/spec/controllers/api/v1/filters/keywords_controller_spec.rb b/spec/controllers/api/v1/filters/keywords_controller_spec.rb new file mode 100644 index 000000000..aecb4e41c --- /dev/null +++ b/spec/controllers/api/v1/filters/keywords_controller_spec.rb @@ -0,0 +1,142 @@ +require 'rails_helper' + +RSpec.describe Api::V1::Filters::KeywordsController, type: :controller do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:filter) { Fabricate(:custom_filter, account: user.account) } + let(:other_user) { Fabricate(:user) } + let(:other_filter) { Fabricate(:custom_filter, account: other_user.account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + let(:scopes) { 'read:filters' } + let!(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } + + it 'returns http success' do + get :index, params: { filter_id: filter.id } + expect(response).to have_http_status(200) + end + + context "when trying to access another's user filters" do + it 'returns http not found' do + get :index, params: { filter_id: other_filter.id } + expect(response).to have_http_status(404) + end + end + end + + describe 'POST #create' do + let(:scopes) { 'write:filters' } + let(:filter_id) { filter.id } + + before do + post :create, params: { filter_id: filter_id, keyword: 'magic', whole_word: false } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns a keyword' do + json = body_as_json + expect(json[:keyword]).to eq 'magic' + expect(json[:whole_word]).to eq false + end + + it 'creates a keyword' do + filter = user.account.custom_filters.first + expect(filter).to_not be_nil + expect(filter.keywords.pluck(:keyword)).to eq ['magic'] + end + + context "when trying to add to another another's user filters" do + let(:filter_id) { other_filter.id } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + end + + describe 'GET #show' do + let(:scopes) { 'read:filters' } + let(:keyword) { Fabricate(:custom_filter_keyword, keyword: 'foo', whole_word: false, custom_filter: filter) } + + before do + get :show, params: { id: keyword.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns expected data' do + json = body_as_json + expect(json[:keyword]).to eq 'foo' + expect(json[:whole_word]).to eq false + end + + context "when trying to access another user's filter keyword" do + let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: other_filter) } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + end + + describe 'PUT #update' do + let(:scopes) { 'write:filters' } + let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } + + before do + get :update, params: { id: keyword.id, keyword: 'updated' } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'updates the keyword' do + expect(keyword.reload.keyword).to eq 'updated' + end + + context "when trying to update another user's filter keyword" do + let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: other_filter) } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + end + + describe 'DELETE #destroy' do + let(:scopes) { 'write:filters' } + let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } + + before do + delete :destroy, params: { id: keyword.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'removes the filter' do + expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound + end + + context "when trying to update another user's filter keyword" do + let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: other_filter) } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/controllers/api/v1/filters_controller_spec.rb b/spec/controllers/api/v1/filters_controller_spec.rb index 5948809e3..af1951f0b 100644 --- a/spec/controllers/api/v1/filters_controller_spec.rb +++ b/spec/controllers/api/v1/filters_controller_spec.rb @@ -34,7 +34,7 @@ RSpec.describe Api::V1::FiltersController, type: :controller do it 'creates a filter' do filter = user.account.custom_filters.first expect(filter).to_not be_nil - expect(filter.phrase).to eq 'magic' + expect(filter.keywords.pluck(:keyword)).to eq ['magic'] expect(filter.context).to eq %w(home) expect(filter.irreversible?).to be true expect(filter.expires_at).to be_nil @@ -42,21 +42,23 @@ RSpec.describe Api::V1::FiltersController, type: :controller do end describe 'GET #show' do - let(:scopes) { 'read:filters' } - let(:filter) { Fabricate(:custom_filter, account: user.account) } + let(:scopes) { 'read:filters' } + let(:filter) { Fabricate(:custom_filter, account: user.account) } + let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } it 'returns http success' do - get :show, params: { id: filter.id } + get :show, params: { id: keyword.id } expect(response).to have_http_status(200) end end describe 'PUT #update' do - let(:scopes) { 'write:filters' } - let(:filter) { Fabricate(:custom_filter, account: user.account) } + let(:scopes) { 'write:filters' } + let(:filter) { Fabricate(:custom_filter, account: user.account) } + let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } before do - put :update, params: { id: filter.id, phrase: 'updated' } + put :update, params: { id: keyword.id, phrase: 'updated' } end it 'returns http success' do @@ -64,16 +66,17 @@ RSpec.describe Api::V1::FiltersController, type: :controller do end it 'updates the filter' do - expect(filter.reload.phrase).to eq 'updated' + expect(keyword.reload.phrase).to eq 'updated' end end describe 'DELETE #destroy' do - let(:scopes) { 'write:filters' } - let(:filter) { Fabricate(:custom_filter, account: user.account) } + let(:scopes) { 'write:filters' } + let(:filter) { Fabricate(:custom_filter, account: user.account) } + let(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } before do - delete :destroy, params: { id: filter.id } + delete :destroy, params: { id: keyword.id } end it 'returns http success' do @@ -81,7 +84,7 @@ RSpec.describe Api::V1::FiltersController, type: :controller do end it 'removes the filter' do - expect { filter.reload }.to raise_error ActiveRecord::RecordNotFound + expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound end end end diff --git a/spec/controllers/api/v1/followed_tags_controller_spec.rb b/spec/controllers/api/v1/followed_tags_controller_spec.rb new file mode 100644 index 000000000..2191350ef --- /dev/null +++ b/spec/controllers/api/v1/followed_tags_controller_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +RSpec.describe Api::V1::FollowedTagsController, type: :controller do + render_views + + let(:user) { Fabricate(:user) } + let(:scopes) { 'read:follows' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + + before { allow(controller).to receive(:doorkeeper_token) { token } } + + describe 'GET #index' do + let!(:tag_follows) { Fabricate.times(5, :tag_follow, account: user.account) } + + before do + get :index, params: { limit: 1 } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/api/v1/reports_controller_spec.rb b/spec/controllers/api/v1/reports_controller_spec.rb index b5baf60e1..dbc64e704 100644 --- a/spec/controllers/api/v1/reports_controller_spec.rb +++ b/spec/controllers/api/v1/reports_controller_spec.rb @@ -13,7 +13,7 @@ RSpec.describe Api::V1::ReportsController, type: :controller do end describe 'POST #create' do - let!(:admin) { Fabricate(:user, admin: true) } + let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } let(:scopes) { 'write:reports' } let(:status) { Fabricate(:status) } diff --git a/spec/controllers/api/v1/statuses_controller_spec.rb b/spec/controllers/api/v1/statuses_controller_spec.rb index 2eb30af74..4d104a198 100644 --- a/spec/controllers/api/v1/statuses_controller_spec.rb +++ b/spec/controllers/api/v1/statuses_controller_spec.rb @@ -20,6 +20,58 @@ RSpec.describe Api::V1::StatusesController, type: :controller do get :show, params: { id: status.id } expect(response).to have_http_status(200) end + + context 'when post includes filtered terms' do + let(:status) { Fabricate(:status, text: 'this toot is about that banned word') } + + before do + user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide, keywords_attributes: [{ keyword: 'banned' }, { keyword: 'irrelevant' }]) + end + + it 'returns http success' do + get :show, params: { id: status.id } + expect(response).to have_http_status(200) + end + + it 'returns filter information' do + get :show, params: { id: status.id } + json = body_as_json + expect(json[:filtered][0]).to include({ + filter: a_hash_including({ + id: user.account.custom_filters.first.id.to_s, + title: 'filter1', + filter_action: 'hide', + }), + keyword_matches: ['banned'], + }) + end + end + + context 'when reblog includes filtered terms' do + let(:status) { Fabricate(:status, reblog: Fabricate(:status, text: 'this toot is about that banned word')) } + + before do + user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide, keywords_attributes: [{ keyword: 'banned' }, { keyword: 'irrelevant' }]) + end + + it 'returns http success' do + get :show, params: { id: status.id } + expect(response).to have_http_status(200) + end + + it 'returns filter information' do + get :show, params: { id: status.id } + json = body_as_json + expect(json[:reblog][:filtered][0]).to include({ + filter: a_hash_including({ + id: user.account.custom_filters.first.id.to_s, + title: 'filter1', + filter_action: 'hide', + }), + keyword_matches: ['banned'], + }) + end + end end describe 'GET #context' do diff --git a/spec/controllers/api/v1/tags_controller_spec.rb b/spec/controllers/api/v1/tags_controller_spec.rb new file mode 100644 index 000000000..ac42660df --- /dev/null +++ b/spec/controllers/api/v1/tags_controller_spec.rb @@ -0,0 +1,82 @@ +require 'rails_helper' + +RSpec.describe Api::V1::TagsController, type: :controller do + render_views + + let(:user) { Fabricate(:user) } + let(:scopes) { 'write:follows' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + + before { allow(controller).to receive(:doorkeeper_token) { token } } + + describe 'GET #show' do + before do + get :show, params: { id: name } + end + + context 'with existing tag' do + let!(:tag) { Fabricate(:tag) } + let(:name) { tag.name } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + end + + context 'with non-existing tag' do + let(:name) { 'hoge' } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + end + end + + describe 'POST #follow' do + before do + post :follow, params: { id: name } + end + + context 'with existing tag' do + let!(:tag) { Fabricate(:tag) } + let(:name) { tag.name } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'creates follow' do + expect(TagFollow.where(tag: tag, account: user.account).exists?).to be true + end + end + + context 'with non-existing tag' do + let(:name) { 'hoge' } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'creates follow' do + expect(TagFollow.where(tag: Tag.find_by!(name: name), account: user.account).exists?).to be true + end + end + end + + describe 'POST #unfollow' do + let!(:tag) { Fabricate(:tag, name: 'foo') } + let!(:tag_follow) { Fabricate(:tag_follow, account: user.account, tag: tag) } + + before do + post :unfollow, params: { id: tag.name } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'removes the follow' do + expect(TagFollow.where(tag: tag, account: user.account).exists?).to be false + end + end +end diff --git a/spec/controllers/api/v2/admin/accounts_controller_spec.rb b/spec/controllers/api/v2/admin/accounts_controller_spec.rb index 3212ddb84..2508a9e05 100644 --- a/spec/controllers/api/v2/admin/accounts_controller_spec.rb +++ b/spec/controllers/api/v2/admin/accounts_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Api::V2::Admin::AccountsController, type: :controller do render_views - let(:role) { 'moderator' } + let(:role) { UserRole.find_by(name: 'Moderator') } let(:user) { Fabricate(:user, role: role) } let(:scopes) { 'admin:read admin:write' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } @@ -22,7 +22,7 @@ RSpec.describe Api::V2::Admin::AccountsController, type: :controller do end shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { wrong_role } + let(:role) { UserRole.find_by(name: wrong_role) } it 'returns http forbidden' do expect(response).to have_http_status(403) @@ -46,7 +46,7 @@ RSpec.describe Api::V2::Admin::AccountsController, type: :controller do end it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', 'user' + it_behaves_like 'forbidden for wrong role', '' [ [{ status: 'active', origin: 'local', permissions: 'staff' }, [:admin_account]], diff --git a/spec/controllers/api/v2/filters_controller_spec.rb b/spec/controllers/api/v2/filters_controller_spec.rb new file mode 100644 index 000000000..cc0070d57 --- /dev/null +++ b/spec/controllers/api/v2/filters_controller_spec.rb @@ -0,0 +1,121 @@ +require 'rails_helper' + +RSpec.describe Api::V2::FiltersController, type: :controller do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + let(:scopes) { 'read:filters' } + let!(:filter) { Fabricate(:custom_filter, account: user.account) } + + it 'returns http success' do + get :index + expect(response).to have_http_status(200) + end + end + + describe 'POST #create' do + let(:scopes) { 'write:filters' } + + before do + post :create, params: { title: 'magic', context: %w(home), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns a filter with keywords' do + json = body_as_json + expect(json[:title]).to eq 'magic' + expect(json[:filter_action]).to eq 'hide' + expect(json[:context]).to eq ['home'] + expect(json[:keywords].map { |keyword| keyword.slice(:keyword, :whole_word) }).to eq [{ keyword: 'magic', whole_word: true }] + end + + it 'creates a filter' do + filter = user.account.custom_filters.first + expect(filter).to_not be_nil + expect(filter.keywords.pluck(:keyword)).to eq ['magic'] + expect(filter.context).to eq %w(home) + expect(filter.irreversible?).to be true + expect(filter.expires_at).to be_nil + end + end + + describe 'GET #show' do + let(:scopes) { 'read:filters' } + let(:filter) { Fabricate(:custom_filter, account: user.account) } + + it 'returns http success' do + get :show, params: { id: filter.id } + expect(response).to have_http_status(200) + end + end + + describe 'PUT #update' do + let(:scopes) { 'write:filters' } + let!(:filter) { Fabricate(:custom_filter, account: user.account) } + let!(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } + + context 'updating filter parameters' do + before do + put :update, params: { id: filter.id, title: 'updated', context: %w(home public) } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'updates the filter title' do + expect(filter.reload.title).to eq 'updated' + end + + it 'updates the filter context' do + expect(filter.reload.context).to eq %w(home public) + end + end + + context 'updating keywords in bulk' do + before do + allow(redis).to receive_messages(publish: nil) + put :update, params: { id: filter.id, keywords_attributes: [{ id: keyword.id, keyword: 'updated' }] } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'updates the keyword' do + expect(keyword.reload.keyword).to eq 'updated' + end + + it 'sends exactly one filters_changed event' do + expect(redis).to have_received(:publish).with("timeline:#{user.account.id}", Oj.dump(event: :filters_changed)).once + end + end + end + + describe 'DELETE #destroy' do + let(:scopes) { 'write:filters' } + let(:filter) { Fabricate(:custom_filter, account: user.account) } + + before do + delete :destroy, params: { id: filter.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'removes the filter' do + expect { filter.reload }.to raise_error ActiveRecord::RecordNotFound + end + end +end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 851e58d60..2af12376d 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -187,70 +187,6 @@ describe ApplicationController, type: :controller do end end - describe 'require_admin!' do - controller do - before_action :require_admin! - - def success - head 200 - end - end - - before do - routes.draw { get 'success' => 'anonymous#success' } - end - - it 'returns a 403 if current user is not admin' do - sign_in(Fabricate(:user, admin: false)) - get 'success' - expect(response).to have_http_status(403) - end - - it 'returns a 403 if current user is only a moderator' do - sign_in(Fabricate(:user, moderator: true)) - get 'success' - expect(response).to have_http_status(403) - end - - it 'does nothing if current user is admin' do - sign_in(Fabricate(:user, admin: true)) - get 'success' - expect(response).to have_http_status(200) - end - end - - describe 'require_staff!' do - controller do - before_action :require_staff! - - def success - head 200 - end - end - - before do - routes.draw { get 'success' => 'anonymous#success' } - end - - it 'returns a 403 if current user is not admin or moderator' do - sign_in(Fabricate(:user, admin: false, moderator: false)) - get 'success' - expect(response).to have_http_status(403) - end - - it 'does nothing if current user is moderator' do - sign_in(Fabricate(:user, moderator: true)) - get 'success' - expect(response).to have_http_status(200) - end - - it 'does nothing if current user is admin' do - sign_in(Fabricate(:user, admin: true)) - get 'success' - expect(response).to have_http_status(200) - end - end - describe 'forbidden' do controller do def route_forbidden diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index 1b8fd0b7b..d3db7aa1a 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -119,6 +119,32 @@ RSpec.describe Auth::SessionsController, type: :controller do end end + context 'using a valid password on a previously-used account with a new IP address' do + let(:previous_ip) { '1.2.3.4' } + let(:current_ip) { '4.3.2.1' } + + let!(:previous_login) { Fabricate(:login_activity, user: user, ip: previous_ip) } + + before do + allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return(current_ip) + allow(UserMailer).to receive(:suspicious_sign_in).and_return(double('email', 'deliver_later!': nil)) + user.update(current_sign_in_at: 1.month.ago) + post :create, params: { user: { email: user.email, password: user.password } } + end + + it 'redirects to home' do + expect(response).to redirect_to(root_path) + end + + it 'logs the user in' do + expect(controller.current_user).to eq user + end + + it 'sends a suspicious sign-in mail' do + expect(UserMailer).to have_received(:suspicious_sign_in).with(user, current_ip, anything, anything) + end + end + context 'using email with uppercase letters' do before do post :create, params: { user: { email: user.email.upcase, password: user.password } } diff --git a/spec/controllers/disputes/appeals_controller_spec.rb b/spec/controllers/disputes/appeals_controller_spec.rb index faa571fc9..90f222f49 100644 --- a/spec/controllers/disputes/appeals_controller_spec.rb +++ b/spec/controllers/disputes/appeals_controller_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Disputes::AppealsController, type: :controller do before { sign_in current_user, scope: :user } - let!(:admin) { Fabricate(:user, admin: true) } + let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } describe '#create' do let(:current_user) { Fabricate(:user) } diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index 76e617e6b..23b98fb12 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -7,30 +7,30 @@ describe InvitesController do sign_in user end - around do |example| - min_invite_role = Setting.min_invite_role - example.run - Setting.min_invite_role = min_invite_role - end - describe 'GET #index' do subject { get :index } - let(:user) { Fabricate(:user, moderator: false, admin: false) } + let(:user) { Fabricate(:user) } let!(:invite) { Fabricate(:invite, user: user) } - context 'when user is a staff' do + context 'when everyone can invite' do + before do + UserRole.everyone.update(permissions: UserRole.everyone.permissions | UserRole::FLAGS[:invite_users]) + end + it 'renders index page' do - Setting.min_invite_role = 'user' expect(subject).to render_template :index expect(assigns(:invites)).to include invite expect(assigns(:invites).count).to eq 1 end end - context 'when user is not a staff' do + context 'when not everyone can invite' do + before do + UserRole.everyone.update(permissions: UserRole.everyone.permissions & ~UserRole::FLAGS[:invite_users]) + end + it 'returns 403' do - Setting.min_invite_role = 'modelator' expect(subject).to have_http_status 403 end end @@ -39,8 +39,12 @@ describe InvitesController do describe 'POST #create' do subject { post :create, params: { invite: { max_uses: '10', expires_in: 1800 } } } - context 'when user is an admin' do - let(:user) { Fabricate(:user, moderator: false, admin: true) } + context 'when everyone can invite' do + let(:user) { Fabricate(:user) } + + before do + UserRole.everyone.update(permissions: UserRole.everyone.permissions | UserRole::FLAGS[:invite_users]) + end it 'succeeds to create a invite' do expect { subject }.to change { Invite.count }.by(1) @@ -49,8 +53,12 @@ describe InvitesController do end end - context 'when user is not an admin' do - let(:user) { Fabricate(:user, moderator: true, admin: false) } + context 'when not everyone can invite' do + let(:user) { Fabricate(:user) } + + before do + UserRole.everyone.update(permissions: UserRole.everyone.permissions & ~UserRole::FLAGS[:invite_users]) + end it 'returns 403' do expect(subject).to have_http_status 403 @@ -61,8 +69,8 @@ describe InvitesController do describe 'DELETE #create' do subject { delete :destroy, params: { id: invite.id } } + let(:user) { Fabricate(:user) } let!(:invite) { Fabricate(:invite, user: user, expires_at: nil) } - let(:user) { Fabricate(:user, moderator: false, admin: true) } it 'expires invite' do expect(subject).to redirect_to invites_path |