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/<id>/<username> 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.
This commit is contained in:
Grayden 2021-08-18 21:57:16 -04:00 committed by GitHub
parent 617ca563f6
commit 64ead3c3a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 6 deletions

View File

@ -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);

View File

@ -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

View File

@ -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