From d8936ea0e67b7034e84735be66976d29faa3ef6c Mon Sep 17 00:00:00 2001 From: Rasmus Kjellberg <2277443+kjellberg@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:31:14 +0100 Subject: [PATCH] feat: delete user accounts --- Rakefile | 4 +-- .../stylesheets/application.tailwind.css | 10 +++++++ .../users/cancellations_controller.rb | 4 +++ .../partials/navigations/_settings.html.erb | 9 +++++- app/views/users/cancellations/show.html.erb | 16 ++++++++++ app/views/users/registrations/edit.html.erb | 22 ++++++++++++++ config/locales/kiqr.en.yml | 29 +++++++++++++++++-- config/routes/authentication.rb | 1 + config/tailwind.config.js | 7 +++++ test/system/accounts/edit_acounts_test.rb | 26 ++++++++--------- test/system/signin_test.rb | 21 +++++++------- test/system/users/cancellation_test.rb | 21 ++++++++++++++ .../{accounts => users}/onboarding_test.rb | 0 13 files changed, 142 insertions(+), 28 deletions(-) create mode 100644 app/controllers/users/cancellations_controller.rb create mode 100644 app/views/users/cancellations/show.html.erb create mode 100644 app/views/users/registrations/edit.html.erb create mode 100644 test/system/users/cancellation_test.rb rename test/system/{accounts => users}/onboarding_test.rb (100%) diff --git a/Rakefile b/Rakefile index d0b8a4e..161f931 100644 --- a/Rakefile +++ b/Rakefile @@ -17,8 +17,8 @@ namespace :lint do end task :default do - Rake::Task["lint:standard"].invoke - Rake::Task["lint:erb"].invoke Rake::Task["test"].invoke Rake::Task["test:system"].invoke + Rake::Task["lint:standard"].invoke + Rake::Task["lint:erb"].invoke end diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index 2e0e26f..6b4b617 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -32,3 +32,13 @@ @apply border border-rose-500; } } + +@layer components { + .box { + @apply bg-surface w-full rounded-lg p-8 shadow; + } + + .kiqr-button { + @apply border-border rounded bg-rose-500 px-4 py-2 text-white; + } +} diff --git a/app/controllers/users/cancellations_controller.rb b/app/controllers/users/cancellations_controller.rb new file mode 100644 index 0000000..adc22ff --- /dev/null +++ b/app/controllers/users/cancellations_controller.rb @@ -0,0 +1,4 @@ +class Users::CancellationsController < ApplicationController + def show + end +end diff --git a/app/views/partials/navigations/_settings.html.erb b/app/views/partials/navigations/_settings.html.erb index 1f2fcd1..af3a6fa 100644 --- a/app/views/partials/navigations/_settings.html.erb +++ b/app/views/partials/navigations/_settings.html.erb @@ -6,7 +6,7 @@ <%= render(PageLayouts::Settings::NavigationItem::Component.new( label: t('.items.account.label'), description: t('.items.account.description'), - icon: "fa fa-user", + icon: Current.account.personal? ? "fa fa-user" : "fa fa-users", path: edit_account_path )) %> @@ -21,3 +21,10 @@ icon: "fa fa-lock", path: edit_user_registration_path )) %> + +<%= render(PageLayouts::Settings::NavigationItem::Component.new( + label: t('.items.delete_user.label'), + description: t('.items.delete_user.description'), + icon: "fa fa-person-circle-minus", + path: delete_user_registration_path +)) %> diff --git a/app/views/users/cancellations/show.html.erb b/app/views/users/cancellations/show.html.erb new file mode 100644 index 0000000..eeccabc --- /dev/null +++ b/app/views/users/cancellations/show.html.erb @@ -0,0 +1,16 @@ +<% title t(".title") %> + +<%= render(PageLayouts::Settings::Component.new( + title: t(".title"), + description: t(".description") +)) do %> +
+
+

<%= t(".box_title") %>

+
+
+

<%= t(".content") %>

+ <%= button_to t(".submit"), user_registration_path, name: "commit", class:"kiqr-button", data: { confirm: t(".confirmation_message"), turbo_confirm: t(".confirmation_message") }, method: :delete %> +
+
+<% end %> diff --git a/app/views/users/registrations/edit.html.erb b/app/views/users/registrations/edit.html.erb new file mode 100644 index 0000000..a879562 --- /dev/null +++ b/app/views/users/registrations/edit.html.erb @@ -0,0 +1,22 @@ +<% title t(".title") %> + +<%= render(PageLayouts::Settings::Component.new( + title: t(".title"), + description: t(".description") +)) do %> + + <%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> + <%= f.input :email, placeholder: t(".form.email.placeholder"), required: true, autofocus: true %> + +
+ <%= f.input :password, placeholder: t(".form.password.placeholder"), required: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length), input_html: { autocomplete: "new-password" } %> + <%= f.input :password_confirmation, placeholder: t(".form.password_confirmation.placeholder"), required: true, input_html: { autocomplete: "new-password" } %> +
+ + <%= f.input :current_password, placeholder: t(".form.current_password.placeholder"), hint: t(".form.current_password.hint"), required: true, input_html: { autocomplete: "current-password" } %> + +
+ <%= f.button :submit, t(".form.submit_button") %> +
+ <% end %> +<% end %> diff --git a/config/locales/kiqr.en.yml b/config/locales/kiqr.en.yml index 7328173..2718d03 100644 --- a/config/locales/kiqr.en.yml +++ b/config/locales/kiqr.en.yml @@ -9,7 +9,7 @@ en: register: "Create account" settings: account_settings: "Account settings" - user_settings: "Login & security" + user_settings: "Your personal settings" items: account: label: "Profile settings" @@ -17,10 +17,13 @@ en: user: label: "Login credentials" description: "Change user email or password." + delete_user: + label: "Delete user account" + description: "Remove all user related data" accounts: edit: title: "Profile settings" - description: "Edit your account profile" + description: "Edit your account profile." update: success: "Your account profile has been updated successfully." form: @@ -59,3 +62,25 @@ en: submit_button: "Create your account" already_have_account: Already have an account? sign_in: Sign in! + edit: + title: "Login credentials" + description: "Change user email or password." + form: + email: + placeholder: "Enter a valid email address" + password: + placeholder: "Create a secure password" + password_confirmation: + placeholder: "Confirm your password" + current_password: + placeholder: "Enter your current password" + hint: "we need your current password to confirm your changes" + submit_button: "Save changes" + cancellations: + show: + title: "Delete account" + description: "Delete your user account and all of your data." + box_title: "Delete your user account" + content: "Need to cancel your account? No worries. We're sad to see you go but understand that sometimes things change. If you have any feedback or if there's anything we can do to improve your experience, please let us know. Your input is invaluable to us. Remember, you're always welcome back!" + submit: "Delete my account" + confirmation_message: "Are you sure? This will DELETE all of your data." diff --git a/config/routes/authentication.rb b/config/routes/authentication.rb index 11fb460..e7faf76 100644 --- a/config/routes/authentication.rb +++ b/config/routes/authentication.rb @@ -8,6 +8,7 @@ scope module: :users, path: :users do get "onboarding" => "onboarding#new" post "onboarding" => "onboarding#create" + get "delete" => "cancellations#show", :as => :delete_user_registration end scope "(/team/:account_id)", account_id: %r{[^/]+} do diff --git a/config/tailwind.config.js b/config/tailwind.config.js index 2ddd492..8c40a79 100644 --- a/config/tailwind.config.js +++ b/config/tailwind.config.js @@ -36,6 +36,13 @@ module.exports = { DEFAULT: "1.5em", }, }, + typography: { + DEFAULT: { + css: { + maxWidth: '100%', + } + } + } }, }, plugins: [ diff --git a/test/system/accounts/edit_acounts_test.rb b/test/system/accounts/edit_acounts_test.rb index 6b2fe90..ae6ac7b 100644 --- a/test/system/accounts/edit_acounts_test.rb +++ b/test/system/accounts/edit_acounts_test.rb @@ -1,14 +1,10 @@ require "application_system_test_case" class EditAccountsTest < ApplicationSystemTestCase - setup do - @user = create(:user) - @team_account = create(:account, name: "Team account") - @team_account.account_users << AccountUser.create(user: @user, role: "owner") - end - test "can edit personal account" do - sign_in(@user) + user = create(:user) + + sign_in(user) visit edit_account_path # Fill the personal account setup form @@ -17,13 +13,17 @@ class EditAccountsTest < ApplicationSystemTestCase click_on "commit" assert_text I18n.t("accounts.update.success") - @user.personal_account.reload - assert_equal "New name", @user.personal_account.name + user.personal_account.reload + assert_equal "New name", user.personal_account.name end test "can edit team account" do - sign_in(@user) - visit edit_account_path(account_id: @team_account) + user = create(:user) + team_account = create(:account, name: "Team account") + team_account.account_users << AccountUser.create(user: user, role: "owner") + + sign_in(user) + visit edit_account_path(account_id: team_account) # Fill the personal account setup form fill_in "account[name]", with: "New team name" @@ -31,7 +31,7 @@ class EditAccountsTest < ApplicationSystemTestCase click_on "commit" assert_text I18n.t("accounts.update.success") - @team_account.reload - assert_equal "New team name", @team_account.name + team_account.reload + assert_equal "New team name", team_account.name end end diff --git a/test/system/signin_test.rb b/test/system/signin_test.rb index 4b0e997..b7c0627 100644 --- a/test/system/signin_test.rb +++ b/test/system/signin_test.rb @@ -1,32 +1,33 @@ require "application_system_test_case" class SigninTest < ApplicationSystemTestCase - setup do - @user = create(:user) - @unconfirmed_user = create(:user, :unconfirmed) - end - test "signs in with a verified user" do + user = create(:user) + visit new_user_session_path - fill_in "user[email]", with: @user.email - fill_in "user[password]", with: @user.password + fill_in "user[email]", with: user.email + fill_in "user[password]", with: user.password click_on "commit" assert_current_path dashboard_path end test "displays unconfirmed email message" do + unconfirmed_user = create(:user, :unconfirmed) + visit new_user_session_path - fill_in "user[email]", with: @unconfirmed_user.email - fill_in "user[password]", with: @unconfirmed_user.password + fill_in "user[email]", with: unconfirmed_user.email + fill_in "user[password]", with: unconfirmed_user.password click_on "commit" assert_text I18n.t("devise.failure.unconfirmed") end test "displays invalid password message" do + user = create(:user) + visit new_user_session_path - fill_in "user[email]", with: @user.email + fill_in "user[email]", with: user.email fill_in "user[password]", with: "invalid" click_on "commit" diff --git a/test/system/users/cancellation_test.rb b/test/system/users/cancellation_test.rb new file mode 100644 index 0000000..c920bc6 --- /dev/null +++ b/test/system/users/cancellation_test.rb @@ -0,0 +1,21 @@ +require "application_system_test_case" + +class EditAccountsTest < ApplicationSystemTestCase + test "can delete a fresh user" do + user = create(:user) + sign_in(user) + visit delete_user_registration_path + accept_confirm { click_on "commit" } + + assert_text I18n.t("devise.registrations.destroyed") + assert_nil User.find_by_id(user.id) + end + + test "can't delete a user if they're an owner of a team" do + skip("https://github.com/kiqr/kiqr/issues/1") + end + + test "can't delete a user if theres an active subscription on their personal account" do + skip("https://github.com/kiqr/kiqr/issues/1") + end +end diff --git a/test/system/accounts/onboarding_test.rb b/test/system/users/onboarding_test.rb similarity index 100% rename from test/system/accounts/onboarding_test.rb rename to test/system/users/onboarding_test.rb