Skip to content

Commit

Permalink
fix: Refactor 'destroy_user_account!' method in Decidim::DestroyAccou…
Browse files Browse the repository at this point in the history
…nt command
  • Loading branch information
Quentinchampenois committed Nov 16, 2023
1 parent 7a2b381 commit 79622e3
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/decidim/cleaner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require "decidim/cleaner/admin"
require "decidim/cleaner/engine"
require "decidim/cleaner/admin_engine"
require "decidim/cleaner/extends/commands/decidim/destroy_account"

module Decidim
# This namespace holds the logic of the `Cleaner` module.
Expand Down
4 changes: 4 additions & 0 deletions lib/decidim/cleaner/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ module Cleaner
# This is the engine that runs on the public interface of cleaner.
class Engine < ::Rails::Engine
isolate_namespace Decidim::Cleaner

config.to_prepare do
Decidim::DestroyAccount.include(Decidim::Cleaner::Extends::DestroyAccount)
end
end
end
end
31 changes: 31 additions & 0 deletions lib/decidim/cleaner/extends/commands/decidim/destroy_account.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

module Decidim
module Cleaner
module Extends
# This command destroys the user's account.
module DestroyAccount
extend ActiveSupport::Concern

included do
private

# Invalidate all sessions after cleaning Decidim::User record to prevent Active Record error
def destroy_user_account!
@user.name = ""
@user.nickname = ""
@user.email = ""
@user.delete_reason = @form.delete_reason
@user.admin = false if @user.admin?
@user.deleted_at = Time.current
@user.skip_reconfirmation!
@user.avatar.purge
@user.save!

@user.invalidate_all_sessions!
end
end
end
end
end
end
108 changes: 108 additions & 0 deletions spec/commands/decidim/destroy_account_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim
describe DestroyAccount do
let(:command) { described_class.new(user, form) }
let(:user) { create(:user, :confirmed) }
let!(:identity) { create(:identity, user:) }
let(:valid) { true }
let(:data) do
{
delete_reason: "I want to delete my account"
}
end

let(:form) do
form = double(
delete_reason: data[:delete_reason],
valid?: valid
)

form
end

context "when invalid" do
let(:valid) { false }

it "broadcasts invalid" do
expect { command.call }.to broadcast(:invalid)
end
end

context "when valid" do
let(:valid) { true }

it "broadcasts ok" do
expect { command.call }.to broadcast(:ok)
end

it "changes the auth salt to invalidate all other sessions" do
old_salt = user.authenticatable_salt
command.call
expect(user.reload.authenticatable_salt).not_to eq(old_salt)
end

it "stores the deleted_at and delete_reason to the user" do
command.call
expect(user.reload.delete_reason).to eq(data[:delete_reason])
expect(user.reload.deleted_at).not_to be_nil
end

it "set name, nickname and email to blank string" do
command.call
expect(user.reload.name).to eq("")
expect(user.reload.nickname).to eq("")
expect(user.reload.email).to eq("")
end

it "destroys the current user avatar" do
command.call
expect(user.reload.avatar).not_to be_present
end

it "deletes user's identities" do
expect do
command.call
end.to change(Identity, :count).by(-1)
end

it "deletes user group memberships" do
user_group = create(:user_group)
create(:user_group_membership, user_group:, user:)

expect do
command.call
end.to change(UserGroupMembership, :count).by(-1)
end

it "deletes the follows" do
other_user = create(:user)
create(:follow, followable: user, user: other_user)
create(:follow, followable: other_user, user:)

expect do
command.call
end.to change(Follow, :count).by(-2)
end

it "deletes participatory space private user" do
create(:participatory_space_private_user, user:)

expect do
command.call
end.to change(ParticipatorySpacePrivateUser, :count).by(-1)
end

context "when user is admin" do
let(:user) { create(:user, :confirmed, :admin) }

it "removes admin role" do
command.call
expect(user.reload.admin).to be_falsey
end
end
end
end
end

0 comments on commit 79622e3

Please sign in to comment.