Remove roles when block or delete users

After a user assigned as a budget admin deletes their account or gets blocked by
a moderator, the application throws an exception while loading the admin
investment index page.

As an erased user is not really deleted and neither its associated roles, the
application was failing when trying to sort and administration without a
username. In this case, the application was throwing an `ArgumentError:
comparison of NilClass with String failed` exception.

As a blocked user is not deleted or its roles, the application failed when trying
to access the user name through the delegation in the Administrator. In this
case, the application was throwing a `NoMethodError: undefined method `name' for
nil:NilClass` exception.
This commit is contained in:
Senén Rodero Rodríguez
2022-05-04 12:53:30 +02:00
parent d797ec3ca0
commit c6190d0199
4 changed files with 80 additions and 0 deletions

View File

@@ -230,6 +230,7 @@ class User < ApplicationRecord
Proposal.hide_all proposal_ids Proposal.hide_all proposal_ids
Budget::Investment.hide_all budget_investment_ids Budget::Investment.hide_all budget_investment_ids
ProposalNotification.hide_all ProposalNotification.where(author_id: id).ids ProposalNotification.hide_all ProposalNotification.where(author_id: id).ids
remove_roles
end end
def full_restore def full_restore
@@ -263,12 +264,21 @@ class User < ApplicationRecord
unconfirmed_phone: nil unconfirmed_phone: nil
) )
identities.destroy_all identities.destroy_all
remove_roles
end end
def erased? def erased?
erased_at.present? erased_at.present?
end end
def remove_roles
administrator&.destroy!
valuator&.destroy!
moderator&.destroy!
manager&.destroy!
sdg_manager&.destroy!
end
def take_votes_if_erased_document(document_number, document_type) def take_votes_if_erased_document(document_number, document_type)
erased_user = User.erased.find_by(document_number: document_number, erased_user = User.erased.find_by(document_number: document_number,
document_type: document_type) document_type: document_type)

View File

@@ -538,6 +538,19 @@ describe User do
expect(Identity.exists?(identity.id)).not_to be expect(Identity.exists?(identity.id)).not_to be
end end
it "removes all user roles" do
user = create(:user)
[:administrator, :moderator, :manager, :sdg_manager, :valuator].each do |role|
create(role, user: user)
end
expect { user.erase }.to change { Administrator.count }.by(-1)
.and change { Moderator.count }.by(-1)
.and change { Manager.count }.by(-1)
.and change { SDG::Manager.count }.by(-1)
.and change { Valuator.count }.by(-1)
end
end end
describe "#take_votes_from" do describe "#take_votes_from" do
@@ -749,6 +762,19 @@ describe User do
expect(Legislation::Proposal.all).to eq [other_proposal] expect(Legislation::Proposal.all).to eq [other_proposal]
expect(Legislation::Proposal.with_hidden).to match_array [proposal, other_proposal] expect(Legislation::Proposal.with_hidden).to match_array [proposal, other_proposal]
end end
it "removes all user roles" do
user = create(:user)
[:administrator, :moderator, :manager, :sdg_manager, :valuator].each do |role|
create(role, user: user)
end
expect { user.block }.to change { Administrator.count }.by(-1)
.and change { Moderator.count }.by(-1)
.and change { Manager.count }.by(-1)
.and change { SDG::Manager.count }.by(-1)
.and change { Valuator.count }.by(-1)
end
end end
describe "#full_restore" do describe "#full_restore" do

View File

@@ -173,6 +173,28 @@ describe "Account" do
expect(page).to have_content "Invalid Email or username or password" expect(page).to have_content "Invalid Email or username or password"
end end
scenario "Erasing an account removes all related roles" do
user.update!(username: "Admin")
administrators = [create(:administrator, user: user),
create(:administrator, user: create(:user, username: "Other admin"))]
budget = create(:budget, administrators: administrators)
visit admin_budget_budget_investments_path(budget)
expect(page).to have_select options: ["All administrators", "Admin", "Other admin"]
visit account_path
click_link "Erase my account"
fill_in "user_erase_reason", with: "I don't want my roles anymore!"
click_button "Erase my account"
expect(page).to have_content "Goodbye! Your account has been cancelled. We hope to see you again soon."
login_as(administrators.last.user)
visit admin_budget_budget_investments_path(budget)
expect(page).to have_select options: ["All administrators", "Other admin"]
end
context "Recommendations" do context "Recommendations" do
scenario "are enabled by default" do scenario "are enabled by default" do
visit account_path visit account_path

View File

@@ -94,4 +94,26 @@ describe "Moderate users" do
expect(page).to have_content "Hidden" expect(page).to have_content "Hidden"
end end
end end
scenario "Block a user removes all their roles" do
admin = create(:administrator).user
user = create(:user, username: "Budget administrator")
budget = create(:budget, administrators: [create(:administrator, user: user)])
debate = create(:debate, author: user)
login_as(admin)
visit admin_budget_budget_investments_path(budget)
expect(page).to have_select options: ["All administrators", "Budget administrator"]
visit debate_path(debate)
within("#debate_#{debate.id}") do
accept_confirm { click_button "Block author" }
end
expect(page).to have_current_path(debates_path)
visit admin_budget_budget_investments_path(budget)
expect(page).to have_select options: ["All administrators"]
end
end end