Commit a3ef8367 authored by Doug Stull's avatar Doug Stull Committed by Bob Van Landuyt

Migrates block user to shared confirm modal

- ease of upkeep to use shared component.
parent d1eae71c
......@@ -5,12 +5,12 @@ import ModalManager from './components/user_modal_manager.vue';
import DeleteUserModal from './components/delete_user_modal.vue';
import UserOperationConfirmationModal from './components/user_operation_confirmation_modal.vue';
import csrf from '~/lib/utils/csrf';
import initConfirmModal from '~/confirm_modal';
const MODAL_TEXTS_CONTAINER_SELECTOR = '#modal-texts';
const MODAL_MANAGER_SELECTOR = '#user-modal';
const ACTION_MODALS = {
deactivate: UserOperationConfirmationModal,
block: UserOperationConfirmationModal,
delete: DeleteUserModal,
'delete-with-contributions': DeleteUserModal,
};
......@@ -62,4 +62,6 @@ document.addEventListener('DOMContentLoaded', () => {
});
},
});
initConfirmModal();
});
<script>
import { GlModal } from '@gitlab/ui';
import { GlModal, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
import { uniqueId } from 'lodash';
import csrf from '~/lib/utils/csrf';
......@@ -7,6 +7,9 @@ export default {
components: {
GlModal,
},
directives: {
SafeHtml,
},
props: {
selector: {
type: String,
......@@ -71,7 +74,8 @@ export default {
-->
<input type="hidden" name="_method" :value="method" />
<input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
<div>{{ modalAttributes.message }}</div>
<div v-if="modalAttributes.messageHtml" v-safe-html="modalAttributes.messageHtml"></div>
<div v-else>{{ modalAttributes.message }}</div>
</form>
</gl-modal>
</template>
......@@ -110,6 +110,32 @@ module UsersHelper
!user.confirmed?
end
def user_block_data(user, message)
{
path: block_admin_user_path(user),
method: 'put',
modal_attributes: {
title: s_('AdminUsers|Block user %{username}?') % { username: sanitize_name(user.name) },
messageHtml: message,
okVariant: 'warning',
okTitle: s_('AdminUsers|Block')
}.to_json
}
end
def user_block_effects
header = tag.p s_('AdminUsers|Blocking user has the following effects:')
list = tag.ul do
concat tag.li s_('AdminUsers|User will not be able to login')
concat tag.li s_('AdminUsers|User will not be able to access git repositories')
concat tag.li s_('AdminUsers|Personal projects will be left')
concat tag.li s_('AdminUsers|Owned groups will be left')
end
header + list
end
private
def blocked_user_badge(user)
......
......@@ -2,10 +2,7 @@
.card-header.bg-warning.text-white
= s_('AdminUsers|Block this user')
.card-body
= render partial: 'admin/users/user_block_effects'
= user_block_effects
%br
%button.btn.gl-button.btn-warning{ data: { 'gl-modal-action': 'block',
content: s_('AdminUsers|You can always unblock their account, their data will remain intact.'),
url: block_admin_user_path(user),
username: sanitize_name(user.name) } }
%button.btn.gl-button.btn-warning.js-confirm-modal-button{ data: user_block_data(user, s_('AdminUsers|You can always unblock their account, their data will remain intact.')) }
= s_('AdminUsers|Block user')
......@@ -5,11 +5,6 @@
action: s_("AdminUsers|Deactivate") } }
= render partial: 'admin/users/user_deactivation_effects'
%div{ data: { modal: "block",
title: s_("AdminUsers|Block user %{username}?"),
action: s_("AdminUsers|Block") } }
= render partial: 'admin/users/user_block_effects'
%div{ data: { modal: "delete",
title: s_("AdminUsers|Delete User %{username}?"),
action: s_('AdminUsers|Delete user'),
......
......@@ -24,10 +24,10 @@
.table-action-buttons
= link_to _('Edit'), edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn gl-button btn-default'
- unless user == current_user
%button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { toggle: 'dropdown' } }
%button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { testid: "user-action-button-#{user.id}", toggle: 'dropdown' } }
= sprite_icon('settings')
= sprite_icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-right
%ul.dropdown-menu.dropdown-menu-right{ data: { testid: "user-action-dropdown-#{user.id}" } }
%li.dropdown-header
= _('Settings')
%li
......@@ -37,16 +37,12 @@
- elsif user.blocked?
- if user.blocked_pending_approval?
= link_to s_('AdminUsers|Approve'), approve_admin_user_path(user), method: :put
%button.btn.btn-default-tertiary{ data: { 'gl-modal-action': 'block',
url: block_admin_user_path(user),
username: sanitize_name(user.name) } }
%button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_block_data(user, user_block_effects) }
= s_('AdminUsers|Block')
- else
= link_to _('Unblock'), unblock_admin_user_path(user), method: :put
- else
%button.btn.btn-default-tertiary{ data: { 'gl-modal-action': 'block',
url: block_admin_user_path(user),
username: sanitize_name(user.name) } }
%button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_block_data(user, user_block_effects) }
= s_('AdminUsers|Block')
- if user.can_be_deactivated?
%li
......
%p
= s_('AdminUsers|Blocking user has the following effects:')
%ul
%li
= s_('AdminUsers|User will not be able to login')
%li
= s_('AdminUsers|User will not be able to access git repositories')
%li
= s_('AdminUsers|Personal projects will be left')
%li
= s_('AdminUsers|Owned groups will be left')
......@@ -204,6 +204,32 @@ RSpec.describe "Admin::Users" do
expect(page).to have_content(user.email)
end
end
context 'when blocking a user' do
it 'shows confirmation and allows blocking', :js do
expect(page).to have_content(user.email)
find("[data-testid='user-action-button-#{user.id}']").click
within find("[data-testid='user-action-dropdown-#{user.id}']") do
find('li button', text: 'Block').click
end
wait_for_requests
expect(page).to have_content('Block user')
expect(page).to have_content('Blocking user has the following effects')
expect(page).to have_content('User will not be able to login')
expect(page).to have_content('Owned groups will be left')
find('.modal-footer button', text: 'Block').click
wait_for_requests
expect(page).to have_content('Successfully blocked')
expect(page).not_to have_content(user.email)
end
end
end
describe "GET /admin/users/new" do
......@@ -362,6 +388,26 @@ RSpec.describe "Admin::Users" do
end
end
context 'when blocking the user' do
it 'shows confirmation and allows blocking', :js do
visit admin_user_path(user)
find('button', text: 'Block user').click
wait_for_requests
expect(page).to have_content('Block user')
expect(page).to have_content('You can always unblock their account, their data will remain intact.')
find('.modal-footer button', text: 'Block').click
wait_for_requests
expect(page).to have_content('Successfully blocked')
expect(page).to have_content('This user is blocked')
end
end
describe 'Impersonation' do
let(:another_user) { create(:user) }
......
......@@ -62,7 +62,7 @@ describe('vue_shared/components/confirm_modal', () => {
wrapper.vm.modalAttributes = MOCK_MODAL_DATA.modalAttributes;
});
it('renders GlModal wtih data', () => {
it('renders GlModal with data', () => {
expect(findModal().exists()).toBeTruthy();
expect(findModal().attributes()).toEqual(
expect.objectContaining({
......@@ -72,6 +72,24 @@ describe('vue_shared/components/confirm_modal', () => {
);
});
});
describe.each`
desc | attrs | expectation
${'when message is simple text'} | ${{}} | ${`<div>${MOCK_MODAL_DATA.modalAttributes.message}</div>`}
${'when message has html'} | ${{ messageHtml: '<p>Header</p><ul onhover="alert(1)"><li>First</li></ul>' }} | ${'<p>Header</p><ul><li>First</li></ul>'}
`('$desc', ({ attrs, expectation }) => {
beforeEach(() => {
createComponent();
wrapper.vm.modalAttributes = {
...MOCK_MODAL_DATA.modalAttributes,
...attrs,
};
});
it('renders message', () => {
expect(findForm().element.innerHTML).toContain(expectation);
});
});
});
describe('methods', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment