Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/Usuário pode excluir sua conta e dados relacionados #172

Merged
merged 6 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions app/controllers/profiles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :set_profile_and_posts, only: %i[show edit remove_photo update]
before_action :private_profile?, only: %i[show]
before_action :redirect_unauthorized_access, only: %i[edit update remove_photo settings]
before_action :redirect_unauthorized_access, only: %i[edit update remove_photo]

def edit; end

Expand Down Expand Up @@ -59,22 +59,13 @@ def private_profile?
redirect_to root_path, alert: t('.private')
end

def settings; end

def deactivate_profile
current_user.profile.inactive!
sign_out current_user
redirect_to root_path, alert: t('.success')
end

private

def profile_params
params.require(:profile).permit(:photo)
end

def redirect_unauthorized_access
@profile = Profile.find(params[:profile_id]) if params[:profile_id]
return if current_user == @profile.user

redirect_to root_path, alert: t('alerts.unauthorized')
Expand Down
26 changes: 26 additions & 0 deletions app/controllers/settings_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class SettingsController < ApplicationController
before_action :authenticate_user!
before_action :redirect_unauthorized_access, only: %i[index]

def index; end

def deactivate_profile
current_user.profile.inactive!
sign_out current_user
redirect_to root_path, alert: t('deactivate_profile')
end

def delete_account
current_user.delete_user_data
redirect_to root_path, notice: t('delete_account')
end

private

def redirect_unauthorized_access
@profile = Profile.find(params[:profile_id])
return if current_user == @profile.user

redirect_to root_path, alert: t('alerts.unauthorized')
end
end
39 changes: 33 additions & 6 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one :profile, dependent: :destroy
has_many :posts, dependent: :nullify
has_many :likes, dependent: :destroy
has_many :comments, dependent: :nullify
has_one :personal_info, through: :profile
has_many :professional_infos, through: :profile
has_many :education_infos, through: :profile
has_many :invitation_requests, through: :profile
has_many :posts, dependent: :destroy
has_many :likes, dependent: :destroy
has_many :comments, dependent: :destroy

enum role: { user: 0, admin: 10 }

validates :full_name, :citizen_id_number, presence: true
validates :citizen_id_number, uniqueness: true
validate :validate_citizen_id_number
validates :full_name, presence: true
validates :citizen_id_number, presence: true, unless: -> { deleted_at.present? }
validates :citizen_id_number, uniqueness: true, unless: -> { deleted_at.present? }
validate :validate_citizen_id_number, unless: -> { deleted_at.present? }

after_create :'create_profile!'
after_create :subscribe_likes_mailer_job
Expand Down Expand Up @@ -69,6 +70,11 @@ def received_zero_likes?(number_of_days)
received_post_likes_since(number_of_days).empty? && received_comment_likes_since(number_of_days).empty?
end

def delete_user_data
transfer_posts_and_comments_to(cloned_user)
destroy
end

private

def subscribe_likes_mailer_job
Expand All @@ -78,4 +84,25 @@ def subscribe_likes_mailer_job
def validate_citizen_id_number
errors.add(:citizen_id_number, 'inválido') unless CPF.valid?(citizen_id_number)
end

def transfer_posts_and_comments_to(clone)
posts.each do |post|
post.update(user: clone, status: 'archived')
end

comments.each do |comment|
comment.update(user: clone, old_message: comment.message, message: 'Comentário Removido')
end
end

def cloned_user
clone = dup
clone.full_name = 'Conta Excluída'
clone.email = "deleted@account-#{id}.com"
clone.password = SecureRandom.alphanumeric(8)
clone.citizen_id_number = "deleted-#{SecureRandom.uuid}"
clone.deleted_at = Time.current
clone.save!
clone
end
end
34 changes: 18 additions & 16 deletions app/views/posts/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -73,25 +73,27 @@
</footer>
</blockquote>

<div class="btn-group">
<div class="me-2">
<%= comment.likes.count %> <%= Like.model_name.human(count: comment.likes.count) %>
</div>
<% if comment.user.deleted_at.nil? %>
<div class="btn-group">
<div class="me-2">
<%= comment.likes.count %> <%= Like.model_name.human(count: comment.likes.count) %>
</div>

<div class="me-2">
<% if user_signed_in? && comment.likes.where(user_id: current_user.id).any? %>
<% like = comment.likes.find_by(user_id: current_user.id) %>
<%= button_to 'Descurtir', like_path(comment_like_id: like.id), method: :delete, class: 'btn btn-danger btn-sm' %>
<% else %>
<%= button_to 'Curtir', likes_path(comment_id: comment.id), method: :post, class: 'btn btn-primary btn-sm' %>
<% end %>
</div>
<div class="me-2">
<% if user_signed_in? && comment.likes.where(user_id: current_user.id).any? %>
<% like = comment.likes.find_by(user_id: current_user.id) %>
<%= button_to 'Descurtir', like_path(comment_like_id: like.id), method: :delete, class: 'btn btn-danger btn-sm' %>
<% else %>
<%= button_to 'Curtir', likes_path(comment_id: comment.id), method: :post, class: 'btn btn-primary btn-sm' %>
gmkoeb marked this conversation as resolved.
Show resolved Hide resolved
<% end %>
</div>

<div>
<%= link_to t('reports.report_btn'), new_report_path(reportable: comment, reportable_type: comment.class),
class: 'btn btn-dark btn-sm' unless comment.user == current_user %>
<div>
<%= link_to t('reports.report_btn'), new_report_path(reportable: comment, reportable_type: comment.class),
class: 'btn btn-dark btn-sm' unless comment.user == current_user %>
</div>
</div>
</div>
<% end %>
</div>
<% end %>
</div>
15 changes: 13 additions & 2 deletions app/views/profiles/settings.html.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
<h1>Configurações do Perfil</h1>

<div>
<%= form_with(url: deactivate_profile_path, method: :patch) do |form| %>
<p><strong class="text-danger">Atenção:</strong> Todos os dados relacionados ao seu perfil serão ARQUIVADOS. Você pode reativar sua conta fazendo log-in novamente.</p>
<%= form.submit 'Desativar Perfil',
class: "btn btn-danger",
data: { turbo_confirm: 'Tem certeza que deseja desativar a conta?' }
data: { turbo_confirm: 'Seu perfil será DESATIVADO, deseja prosseguir?' }
%>
<% end %>
</div>

<div>
<%= form_with(url: delete_account_path, method: :delete) do |form| %>
<p><strong class="text-danger">Atenção:</strong> Todos os dados relacionados a conta serão EXCLUÍDOS e não poderão ser recuperados.</p>
<%= form.submit 'Excluir Conta',
class: "btn btn-danger",
data: { turbo_confirm: 'Sua conta será EXCLUÍDA, deseja prosseguir?' }
%>
<% end %>
</div>
20 changes: 20 additions & 0 deletions app/views/settings/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<h2>Configurações</h2>
<div>
<%= form_with(url: deactivate_profile_path, method: :patch) do |form| %>
<p><strong class="text-danger">Atenção:</strong> Todos os dados relacionados ao seu perfil serão ARQUIVADOS. Você pode reativar sua conta fazendo log-in novamente.</p>
<%= form.submit 'Desativar Perfil',
class: "btn btn-danger",
data: { turbo_confirm: 'Seu perfil será DESATIVADO, deseja prosseguir?' }
%>
<% end %>
</div>

<div>
<%= form_with(url: delete_account_path, method: :delete) do |form| %>
<p><strong class="text-danger">Atenção:</strong> Todos os dados relacionados a conta serão EXCLUÍDOS e não poderão ser recuperados.</p>
<%= form.submit 'Excluir Conta',
class: "btn btn-danger",
data: { turbo_confirm: 'Sua conta será EXCLUÍDA, deseja prosseguir?' }
%>
<% end %>
</div>
2 changes: 1 addition & 1 deletion app/views/shared/_navbar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<%= link_to 'Criar Nova Publicação', new_post_path, class: 'nav-link', data: { turbo: false } %>
</li>
<li class="dropdown-item" href="#">
<%= link_to 'Configurações', profile_settings_path(current_user), class: 'nav-link' %>
<%= link_to 'Configurações', profile_settings_path(current_user.profile), class: 'nav-link' %>
</li>
<li class="dropdown-item" href="#">
<%= button_to 'Sair', destroy_user_session_path, method: :delete, class: 'btn btn-danger w-100' %>
Expand Down
2 changes: 0 additions & 2 deletions config/locales/profile.pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ pt-BR:
success: Privacidade alterada com sucesso
show:
private: O perfil que você acessou é privado
deactivate_profile:
success: Perfil desativado com sucesso
profile:
update:
success: 'Informações pessoais atualizadas com sucesso'
3 changes: 3 additions & 0 deletions config/locales/settings.pt-BR.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pt-BR:
deactivate_profile: Perfil desativado com sucesso
delete_account: Conta excluída com sucesso
9 changes: 5 additions & 4 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Rails.application.routes.draw do
devise_for :users, :controllers => {:registrations => "registrations"}
devise_for :users, controllers: { registrations: 'registrations' }

root to: "home#index"
root to: 'home#index'

resources :searches, only: %i[index]
resources :invitations, only: %i[index show] do
Expand All @@ -24,7 +24,7 @@
resources :users, only: [] do
resources :posts, shallow: true, only: %i[show edit update]
resources :profiles, shallow: true, only: %i[edit show update] do
get 'settings'
resources 'settings', only: %i[index]
patch :remove_photo, on: :member
resources :connections, only: %i[create index] do
patch 'unfollow', 'follow_again'
Expand All @@ -33,7 +33,8 @@
end
end

patch 'deactivate_profile', controller: :profiles
delete 'delete_account', controller: :settings
patch 'deactivate_profile', controller: :settings
patch 'work_unavailable', controller: :profiles
patch 'open_to_work', controller: :profiles
patch 'change_privacy', controller: :profiles
Expand Down
6 changes: 6 additions & 0 deletions db/migrate/20240210143501_add_deleted_at_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddDeletedAtToUsers < ActiveRecord::Migration[7.1]
def change
add_column :users, :deleted_at, :datetime
add_index :users, :deleted_at
end
end
5 changes: 5 additions & 0 deletions db/migrate/20240210163321_add_old_message_to_comments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddOldMessageToComments < ActiveRecord::Migration[7.1]
def change
add_column :comments, :old_message, :text
end
end
7 changes: 5 additions & 2 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions spec/models/profile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,28 @@
end
end

describe '#inactive' do
it 'arquiva dados do usuário' do
user = create(:user, full_name: 'James')
profile = create(:profile, user:)
post1 = create(:post, user:, status: 'published')
post2 = create(:post, user:, status: 'draft')
post3 = create(:post, user:, status: 'archived')
other_user = create(:user)
Connection.create(follower: profile, followed_profile: other_user.profile)
Connection.create(follower: other_user.profile, followed_profile: profile)

profile.inactive!

expect(user.reload.full_name).to eq 'Perfil Desativado'
expect(profile.reload).to be_inactive
expect(post1.reload).to be_archived
expect(post2.reload).to be_archived
expect(post3.reload).to be_archived
expect(Connection.inactive.count).to eq 2
end
end

describe '#active' do
it 'restaura dados do usuário' do
user = create(:user, full_name: 'James')
Expand Down
18 changes: 18 additions & 0 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,22 @@
expect(user.description).to eq 'João (Admin)'
end
end

describe '#delete_user_data' do
it 'deleta dados relaciondos ao usuário mantendo posts e comentarios em usuário coringa' do
user = create(:user, full_name: 'João Almeida')
user.posts.create(title: 'Post do usuário excluído', content: 'Conteúdo')
post = create(:post)
post.comments.create(message: 'Novo comentário', user:)

user.delete_user_data

expect(User.find_by(id: user.id)).to be_nil
deleted_user = User.find_by(full_name: 'Conta Excluída')
expect(deleted_user.deleted_at).not_to be_nil
expect(deleted_user.comments.first.message).to eq 'Comentário Removido'
expect(deleted_user.comments.first.old_message).to eq 'Novo comentário'
expect(deleted_user.posts.count).to eq 1
end
end
end
25 changes: 0 additions & 25 deletions spec/requests/profiles/user_deactivate_profile_spec.rb

This file was deleted.

Loading
Loading