From 64ead3c3a1333028c03429aa4273df79d6225c5c Mon Sep 17 00:00:00 2001 From: Grayden <38144548+graydenshand@users.noreply.github.com> Date: Wed, 18 Aug 2021 21:57:16 -0400 Subject: [PATCH] FIX: Revoking admin or moderator status doesn't require refresh to delete/anonymize/merge user (#14073) * FIX: Revoking admin or moderator status doesn't require refresh to delete/anonymize/merge user On the /admin/users// page, there are action buttons that are either visible or hidden depending on a few fields from the AdminDetailsSerializer: `can_be_deleted`, `can_be_anonymized`, `can_be_merged`, `can_delete_all_posts`. These fields are updated when granting/revoking admin or moderator status. However, those updates were not being reflected on the page. E.g. if a user is granted moderation privileges, the 'anonymize user' and 'merge' buttons still appear on the page, which is inconsistent with the backend state of the user. It requires refreshing the page to update the state. This commit fixes that issue, by syncing the client model state with the server state when handling a successful response from the server. Now, when revoking privileges, the buttons automatically appear without refreshing the page. Similarly, when granting moderator privileges, the buttons automatically disappear without refreshing the page. * Add detailed user response to spec for changed routes. Add tests to verify that the revoke_moderation, grant_moderation, and revoke_admin routes return a response formatted according to the AdminDetailedUserSerializer. --- .../admin/addon/models/admin-user.js | 14 ++++++++++--- app/controllers/admin/users_controller.rb | 6 +++--- spec/requests/admin/users_controller_spec.rb | 20 +++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/admin/addon/models/admin-user.js b/app/assets/javascripts/admin/addon/models/admin-user.js index cbcdcc2e24e..cfd34b87e37 100644 --- a/app/assets/javascripts/admin/addon/models/admin-user.js +++ b/app/assets/javascripts/admin/addon/models/admin-user.js @@ -86,11 +86,15 @@ const AdminUser = User.extend({ revokeAdmin() { return ajax(`/admin/users/${this.id}/revoke_admin`, { type: "PUT", - }).then(() => { + }).then((resp) => { this.setProperties({ admin: false, can_grant_admin: true, can_revoke_admin: false, + can_be_merged: resp.can_be_merged, + can_be_anonymized: resp.can_be_anonymized, + can_be_deleted: resp.can_be_deleted, + can_delete_all_posts: resp.can_delete_all_posts, }); }); }, @@ -105,11 +109,13 @@ const AdminUser = User.extend({ return ajax(`/admin/users/${this.id}/revoke_moderation`, { type: "PUT", }) - .then(() => { + .then((resp) => { this.setProperties({ moderator: false, can_grant_moderation: true, can_revoke_moderation: false, + can_be_merged: resp.can_be_merged, + can_be_anonymized: resp.can_be_anonymized, }); }) .catch(popupAjaxError); @@ -119,11 +125,13 @@ const AdminUser = User.extend({ return ajax(`/admin/users/${this.id}/grant_moderation`, { type: "PUT", }) - .then(() => { + .then((resp) => { this.setProperties({ moderator: true, can_grant_moderation: false, can_revoke_moderation: true, + can_be_merged: resp.can_be_merged, + can_be_anonymized: resp.can_be_anonymized, }); }) .catch(popupAjaxError); diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 2fb44695b40..cd8b2f7f3ae 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -187,7 +187,7 @@ class Admin::UsersController < Admin::AdminController guardian.ensure_can_revoke_admin!(@user) @user.revoke_admin! StaffActionLogger.new(current_user).log_revoke_admin(@user) - render body: nil + render_serialized(@user, AdminDetailedUserSerializer, root: false) end def grant_admin @@ -199,14 +199,14 @@ class Admin::UsersController < Admin::AdminController guardian.ensure_can_revoke_moderation!(@user) @user.revoke_moderation! StaffActionLogger.new(current_user).log_revoke_moderation(@user) - render body: nil + render_serialized(@user, AdminDetailedUserSerializer, root: false) end def grant_moderation guardian.ensure_can_grant_moderation!(@user) @user.grant_moderation! StaffActionLogger.new(current_user).log_grant_moderation(@user) - render_serialized(@user, AdminUserSerializer) + render_serialized(@user, AdminDetailedUserSerializer, root: false) end def add_group diff --git a/spec/requests/admin/users_controller_spec.rb b/spec/requests/admin/users_controller_spec.rb index 6d7a7b97201..d32b6bea607 100644 --- a/spec/requests/admin/users_controller_spec.rb +++ b/spec/requests/admin/users_controller_spec.rb @@ -327,6 +327,14 @@ RSpec.describe Admin::UsersController do another_admin.reload expect(another_admin.admin).to eq(false) end + + it 'returns detailed user schema' do + put "/admin/users/#{another_admin.id}/revoke_admin.json" + expect(response.parsed_body['can_be_merged']).to eq(true) + expect(response.parsed_body['can_be_deleted']).to eq(true) + expect(response.parsed_body['can_be_anonymized']).to eq(true) + expect(response.parsed_body['can_delete_all_posts']).to eq(true) + end end describe '#grant_admin' do @@ -505,6 +513,12 @@ RSpec.describe Admin::UsersController do another_user.reload expect(another_user.moderator).to eq(true) end + + it 'returns detailed user schema' do + put "/admin/users/#{another_user.id}/grant_moderation.json" + expect(response.parsed_body['can_be_merged']).to eq(false) + expect(response.parsed_body['can_be_anonymized']).to eq(false) + end end describe '#revoke_moderation' do @@ -524,6 +538,12 @@ RSpec.describe Admin::UsersController do moderator.reload expect(moderator.moderator).to eq(false) end + + it 'returns detailed user schema' do + put "/admin/users/#{moderator.id}/revoke_moderation.json" + expect(response.parsed_body['can_be_merged']).to eq(true) + expect(response.parsed_body['can_be_anonymized']).to eq(true) + end end describe '#primary_group' do