diff --git a/app/controllers/super_admin/users_controller.rb b/app/controllers/super_admin/users_controller.rb index a27f528adb..93be8fcec7 100644 --- a/app/controllers/super_admin/users_controller.rb +++ b/app/controllers/super_admin/users_controller.rb @@ -38,6 +38,7 @@ def update # Remove the extraneous Org Selector hidden fields attrs = remove_org_selection_params(params_in: attrs) + attrs = handle_confirmed_at_param(attrs) if @user.update(attrs) # If its a new Org create it @@ -125,7 +126,8 @@ def user_params :org_id, :org_name, :org_crosswalk, :department_id, :language_id, - :other_organisation) + :other_organisation, + :confirmed_at) end def merge_accounts @@ -136,5 +138,20 @@ def merge_accounts flash.now[:alert] = failure_message(@user, _('merge')) end end + + def handle_confirmed_at_param(attrs) + # if an unconfirmed email is now being confirmed + if !@user.confirmed? && attrs[:confirmed_at] == '1' + attrs[:confirmed_at] = Time.current + # elsif a confirmed email is now being unconfirmed and the user is not a super admin + elsif @user.confirmed? && attrs[:confirmed_at] == '0' && !@user.can_super_admin? + attrs[:confirmed_at] = nil + else + # else delete the param + # (keeps value nil for unconfirmed user and maintains previous Time value for confirmed user) + attrs.delete(:confirmed_at) + end + attrs + end end end diff --git a/app/views/super_admin/users/_email_confirmation_status.html.erb b/app/views/super_admin/users/_email_confirmation_status.html.erb new file mode 100644 index 0000000000..7528238d91 --- /dev/null +++ b/app/views/super_admin/users/_email_confirmation_status.html.erb @@ -0,0 +1,11 @@ +
+ <%= f.label(:confirmed_at, _('Email Confirmation Status'), class: 'control-label') %> +
+ <% is_checkbox_disabled = @user.can_super_admin? && @user.confirmed_at.present? %> + <%= f.check_box(:confirmed_at, { checked: @user.confirmed?, + disabled: is_checkbox_disabled, + style: 'vertical-align: middle; + margin-top: -2px;' }) %> + <%= @user.confirmed? ? _("Confirmed.") : _("Unconfirmed.") %> + <%= content_tag(:small, _("(Use checkbox to change status.)")) unless is_checkbox_disabled %> +
diff --git a/app/views/super_admin/users/edit.html.erb b/app/views/super_admin/users/edit.html.erb index 8d1a3ab7ee..d9f1da15f6 100644 --- a/app/views/super_admin/users/edit.html.erb +++ b/app/views/super_admin/users/edit.html.erb @@ -57,6 +57,8 @@ <% end %> + <%= render 'email_confirmation_status', f: f %> +
<%= f.button(_('Save'), class: 'btn btn-secondary', type: "submit", id: "personal_details_registration_form_submit") %> diff --git a/spec/controllers/super_admin/users_controller_spec.rb b/spec/controllers/super_admin/users_controller_spec.rb new file mode 100644 index 0000000000..5d3232eb76 --- /dev/null +++ b/spec/controllers/super_admin/users_controller_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe SuperAdmin::UsersController, type: :controller do + let(:super_admin) { create(:user, :super_admin) } + let(:user) { create(:user, confirmed_at: nil) } + + before do + sign_in super_admin + end + + describe 'PUT #update' do + context 'when confirming an unconfirmed user' do + it 'sets confirmed_at to the current time' do + put :update, params: { id: user.id, user: { confirmed_at: '1' } } + user.reload + expect(user.confirmed_at).to be_a(Time) + end + end + + context 'when unconfirming a confirmed user' do + before do + user.update(confirmed_at: Time.current) + end + + it 'sets confirmed_at to nil' do + put :update, params: { id: user.id, user: { confirmed_at: '0' } } + user.reload + expect(user.confirmed_at).to be_nil + end + end + + context 'when update will not affect confirmation status' do + it 'does not update confirmed_at value for an already confirmed user' do + # (usec: 0) removes mircoseconds to better enable comparison + user.update(confirmed_at: Time.current.change(usec: 0)) + original_confirmed_at = user.confirmed_at + put :update, params: { id: user.id, user: { firstname: 'NewName', confirmed_at: '1' } } + user.reload + expect(user.confirmed_at).to eq(original_confirmed_at) + end + end + + context 'when attempting to set a super_admin to unconfirmed' do + it 'does not update confirmed_at value to nil' do + put :update, params: { id: super_admin.id, user: { confirmed_at: '0' } } + super_admin.reload + expect(super_admin.confirmed_at).not_to be_nil + end + end + end +end