diff options
Diffstat (limited to 'spec/features/admin/users/users_spec.rb')
-rw-r--r-- | spec/features/admin/users/users_spec.rb | 586 |
1 files changed, 319 insertions, 267 deletions
diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 9482b4f8603..d3931373ee3 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -3,298 +3,306 @@ require 'spec_helper' RSpec.describe 'Admin::Users' do - include Spec::Support::Helpers::Features::ResponsiveTableHelpers - let_it_be(:user, reload: true) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') } - let_it_be(:current_user) { create(:admin, last_activity_on: 5.days.ago) } + let_it_be(:current_user) { create(:admin) } before do sign_in(current_user) gitlab_enable_admin_mode_sign_in(current_user) end - describe 'GET /admin/users' do - before do - stub_feature_flags(vue_admin_users: false) - visit admin_users_path - end + [true, false].each do |vue_admin_users| + context "with vue_admin_users feature flag set to #{vue_admin_users}", js: vue_admin_users do + before do + stub_feature_flags(vue_admin_users: vue_admin_users) + end - it "is ok" do - expect(current_path).to eq(admin_users_path) - end + describe 'GET /admin/users' do + before do + visit admin_users_path + end - it "has users list" do - expect(page).to have_content(current_user.email) - expect(page).to have_content(current_user.name) - expect(page).to have_content(current_user.created_at.strftime('%e %b, %Y')) - expect(page).to have_content(current_user.last_activity_on.strftime('%e %b, %Y')) - expect(page).to have_content(user.email) - expect(page).to have_content(user.name) - expect(page).to have_content('Projects') - expect(page).to have_button('Block') - expect(page).to have_button('Deactivate') - expect(page).to have_button('Delete user') - expect(page).to have_button('Delete user and contributions') - end + it "is ok" do + expect(current_path).to eq(admin_users_path) + end - describe 'view extra user information' do - it 'shows the user popover on hover', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/11290' do - expect(page).not_to have_selector('#__BV_popover_1__') + it "has users list" do + current_user.reload - first_user_link = page.first('.js-user-link') - first_user_link.hover + expect(page).to have_content(current_user.email) + expect(page).to have_content(current_user.name) + expect(page).to have_content(current_user.created_at.strftime('%e %b, %Y')) + expect(page).to have_content(user.email) + expect(page).to have_content(user.name) + expect(page).to have_content('Projects') - expect(page).to have_selector('#__BV_popover_1__') - end - end + click_user_dropdown_toggle(user.id) - context 'user project count' do - before do - project = create(:project) - project.add_maintainer(current_user) - end + expect(page).to have_button('Block') + expect(page).to have_button('Deactivate') + expect(page).to have_button('Delete user') + expect(page).to have_button('Delete user and contributions') + end - it 'displays count of users projects' do - visit admin_users_path + it 'clicking edit user takes us to edit page', :aggregate_failures do + page.within("[data-testid='user-actions-#{user.id}']") do + click_link 'Edit' + end - expect(page.find("[data-testid='user-project-count-#{current_user.id}']").text).to eq("1") - end - end + expect(page).to have_content('Name') + expect(page).to have_content('Password') + end - describe 'tabs' do - it 'has multiple tabs to filter users' do - expect(page).to have_link('Active', href: admin_users_path) - expect(page).to have_link('Admins', href: admin_users_path(filter: 'admins')) - expect(page).to have_link('2FA Enabled', href: admin_users_path(filter: 'two_factor_enabled')) - expect(page).to have_link('2FA Disabled', href: admin_users_path(filter: 'two_factor_disabled')) - expect(page).to have_link('External', href: admin_users_path(filter: 'external')) - expect(page).to have_link('Blocked', href: admin_users_path(filter: 'blocked')) - expect(page).to have_link('Deactivated', href: admin_users_path(filter: 'deactivated')) - expect(page).to have_link('Without projects', href: admin_users_path(filter: 'wop')) - end + describe 'view extra user information' do + it 'shows the user popover on hover', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/11290' do + expect(page).not_to have_selector('#__BV_popover_1__') - context '`Pending approval` tab' do - before do - visit admin_users_path - end + first_user_link = page.first('.js-user-link') + first_user_link.hover - it 'shows the `Pending approval` tab' do - expect(page).to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval')) + expect(page).to have_selector('#__BV_popover_1__') + end end - end - end - describe 'search and sort' do - before_all do - create(:user, name: 'Foo Bar', last_activity_on: 3.days.ago) - create(:user, name: 'Foo Baz', last_activity_on: 2.days.ago) - create(:user, name: 'Dmitriy') - end + context 'user project count' do + before do + project = create(:project) + project.add_maintainer(current_user) + end - it 'searches users by name' do - visit admin_users_path(search_query: 'Foo') + it 'displays count of users projects' do + visit admin_users_path - expect(page).to have_content('Foo Bar') - expect(page).to have_content('Foo Baz') - expect(page).not_to have_content('Dmitriy') - end + expect(page.find("[data-testid='user-project-count-#{current_user.id}']").text).to eq("1") + end + end - it 'sorts users by name' do - visit admin_users_path + describe 'tabs' do + it 'has multiple tabs to filter users' do + expect(page).to have_link('Active', href: admin_users_path) + expect(page).to have_link('Admins', href: admin_users_path(filter: 'admins')) + expect(page).to have_link('2FA Enabled', href: admin_users_path(filter: 'two_factor_enabled')) + expect(page).to have_link('2FA Disabled', href: admin_users_path(filter: 'two_factor_disabled')) + expect(page).to have_link('External', href: admin_users_path(filter: 'external')) + expect(page).to have_link('Blocked', href: admin_users_path(filter: 'blocked')) + expect(page).to have_link('Banned', href: admin_users_path(filter: 'banned')) + expect(page).to have_link('Deactivated', href: admin_users_path(filter: 'deactivated')) + expect(page).to have_link('Without projects', href: admin_users_path(filter: 'wop')) + end + + context '`Pending approval` tab' do + before do + visit admin_users_path + end + + it 'shows the `Pending approval` tab' do + expect(page).to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval')) + end + end + end - sort_by('Name') + describe 'search and sort' do + before_all do + create(:user, name: 'Foo Bar', last_activity_on: 3.days.ago) + create(:user, name: 'Foo Baz', last_activity_on: 2.days.ago) + create(:user, name: 'Dmitriy') + end - expect(first_row.text).to include('Dmitriy') - expect(second_row.text).to include('Foo Bar') - end + it 'searches users by name' do + visit admin_users_path(search_query: 'Foo') - it 'sorts search results only' do - visit admin_users_path(search_query: 'Foo') + expect(page).to have_content('Foo Bar') + expect(page).to have_content('Foo Baz') + expect(page).not_to have_content('Dmitriy') + end - sort_by('Name') + it 'sorts users by name' do + visit admin_users_path - expect(page).not_to have_content('Dmitriy') - expect(first_row.text).to include('Foo Bar') - expect(second_row.text).to include('Foo Baz') - end + sort_by('Name') - it 'searches with respect of sorting' do - visit admin_users_path(sort: 'Name') + expect(first_row.text).to include('Dmitriy') + expect(second_row.text).to include('Foo Bar') + end - fill_in :search_query, with: 'Foo' - click_button('Search users') + it 'sorts search results only' do + visit admin_users_path(search_query: 'Foo') - expect(first_row.text).to include('Foo Bar') - expect(second_row.text).to include('Foo Baz') - end + sort_by('Name') + expect(page).not_to have_content('Dmitriy') + expect(first_row.text).to include('Foo Bar') + expect(second_row.text).to include('Foo Baz') + end - it 'sorts users by recent last activity' do - visit admin_users_path(search_query: 'Foo') + it 'searches with respect of sorting' do + visit admin_users_path(sort: 'Name') - sort_by('Recent last activity') + fill_in :search_query, with: 'Foo' + click_button('Search users') - expect(first_row.text).to include('Foo Baz') - expect(second_row.text).to include('Foo Bar') - end + expect(first_row.text).to include('Foo Bar') + expect(second_row.text).to include('Foo Baz') + end - it 'sorts users by oldest last activity' do - visit admin_users_path(search_query: 'Foo') + it 'sorts users by recent last activity' do + visit admin_users_path(search_query: 'Foo') - sort_by('Oldest last activity') + sort_by('Recent last activity') - expect(first_row.text).to include('Foo Bar') - expect(second_row.text).to include('Foo Baz') - end - end + expect(first_row.text).to include('Foo Baz') + expect(second_row.text).to include('Foo Bar') + end - describe 'Two-factor Authentication filters' do - it 'counts users who have enabled 2FA' do - create(:user, :two_factor) + it 'sorts users by oldest last activity' do + visit admin_users_path(search_query: 'Foo') - visit admin_users_path + sort_by('Oldest last activity') - page.within('.filter-two-factor-enabled small') do - expect(page).to have_content('1') + expect(first_row.text).to include('Foo Bar') + expect(second_row.text).to include('Foo Baz') + end end - end - it 'filters by users who have enabled 2FA' do - user = create(:user, :two_factor) + describe 'Two-factor Authentication filters' do + it 'counts users who have enabled 2FA' do + create(:user, :two_factor) - visit admin_users_path - click_link '2FA Enabled' + visit admin_users_path - expect(page).to have_content(user.email) - end + page.within('.filter-two-factor-enabled small') do + expect(page).to have_content('1') + end + end - it 'counts users who have not enabled 2FA' do - visit admin_users_path + it 'filters by users who have enabled 2FA' do + user = create(:user, :two_factor) - page.within('.filter-two-factor-disabled small') do - expect(page).to have_content('2') # Including admin - end - end + visit admin_users_path + click_link '2FA Enabled' - it 'filters by users who have not enabled 2FA' do - visit admin_users_path - click_link '2FA Disabled' + expect(page).to have_content(user.email) + end - expect(page).to have_content(user.email) - end - end + it 'counts users who have not enabled 2FA' do + visit admin_users_path - describe 'Pending approval filter' do - it 'counts users who are pending approval' do - create_list(:user, 2, :blocked_pending_approval) + page.within('.filter-two-factor-disabled small') do + expect(page).to have_content('2') # Including admin + end + end - visit admin_users_path + it 'filters by users who have not enabled 2FA' do + visit admin_users_path + click_link '2FA Disabled' - page.within('.filter-blocked-pending-approval small') do - expect(page).to have_content('2') + expect(page).to have_content(user.email) + end end - end - it 'filters by users who are pending approval' do - user = create(:user, :blocked_pending_approval) + describe 'Pending approval filter' do + it 'counts users who are pending approval' do + create_list(:user, 2, :blocked_pending_approval) - visit admin_users_path - click_link 'Pending approval' + visit admin_users_path - expect(page).to have_content(user.email) - end - end + page.within('.filter-blocked-pending-approval small') do + expect(page).to have_content('2') + end + end - context 'when blocking/unblocking a user' do - it 'shows confirmation and allows blocking and unblocking', :js do - expect(page).to have_content(user.email) + it 'filters by users who are pending approval' do + user = create(:user, :blocked_pending_approval) - click_action_in_user_dropdown(user.id, 'Block') + visit admin_users_path + click_link 'Pending approval' - wait_for_requests + expect(page).to have_content(user.email) + end + end - 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') + context 'when blocking/unblocking a user' do + it 'shows confirmation and allows blocking and unblocking', :js do + expect(page).to have_content(user.email) - find('.modal-footer button', text: 'Block').click + click_action_in_user_dropdown(user.id, 'Block') - wait_for_requests + wait_for_requests - expect(page).to have_content('Successfully blocked') - expect(page).not_to have_content(user.email) + 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') - click_link 'Blocked' + find('.modal-footer button', text: 'Block').click - wait_for_requests + wait_for_requests - expect(page).to have_content(user.email) + expect(page).to have_content('Successfully blocked') + expect(page).not_to have_content(user.email) - click_action_in_user_dropdown(user.id, 'Unblock') + click_link 'Blocked' - expect(page).to have_content('Unblock user') - expect(page).to have_content('You can always block their account again if needed.') + wait_for_requests - find('.modal-footer button', text: 'Unblock').click + expect(page).to have_content(user.email) - wait_for_requests + click_action_in_user_dropdown(user.id, 'Unblock') - expect(page).to have_content('Successfully unblocked') - expect(page).not_to have_content(user.email) - end - end + expect(page).to have_content('Unblock user') + expect(page).to have_content('You can always block their account again if needed.') - context 'when deactivating/re-activating a user' do - it 'shows confirmation and allows deactivating and re-activating', :js do - expect(page).to have_content(user.email) + find('.modal-footer button', text: 'Unblock').click - click_action_in_user_dropdown(user.id, 'Deactivate') + wait_for_requests - expect(page).to have_content('Deactivate user') - expect(page).to have_content('Deactivating a user has the following effects') - expect(page).to have_content('The user will be logged out') - expect(page).to have_content('Personal projects, group and user history will be left intact') + expect(page).to have_content('Successfully unblocked') + expect(page).not_to have_content(user.email) + end + end - find('.modal-footer button', text: 'Deactivate').click + context 'when deactivating/re-activating a user' do + it 'shows confirmation and allows deactivating and re-activating', :js do + expect(page).to have_content(user.email) - wait_for_requests + click_action_in_user_dropdown(user.id, 'Deactivate') - expect(page).to have_content('Successfully deactivated') - expect(page).not_to have_content(user.email) + expect(page).to have_content('Deactivate user') + expect(page).to have_content('Deactivating a user has the following effects') + expect(page).to have_content('The user will be logged out') + expect(page).to have_content('Personal projects, group and user history will be left intact') - click_link 'Deactivated' + find('.modal-footer button', text: 'Deactivate').click - wait_for_requests + wait_for_requests - expect(page).to have_content(user.email) + expect(page).to have_content('Successfully deactivated') + expect(page).not_to have_content(user.email) - click_action_in_user_dropdown(user.id, 'Activate') + click_link 'Deactivated' - expect(page).to have_content('Activate user') - expect(page).to have_content('You can always deactivate their account again if needed.') + wait_for_requests - find('.modal-footer button', text: 'Activate').click + expect(page).to have_content(user.email) - wait_for_requests + click_action_in_user_dropdown(user.id, 'Activate') - expect(page).to have_content('Successfully activated') - expect(page).not_to have_content(user.email) - end - end + expect(page).to have_content('Activate user') + expect(page).to have_content('You can always deactivate their account again if needed.') - def click_action_in_user_dropdown(user_id, action) - find("[data-testid='user-action-button-#{user_id}']").click + find('.modal-footer button', text: 'Activate').click - within find("[data-testid='user-action-dropdown-#{user_id}']") do - find('li button', text: action).click - end + wait_for_requests - wait_for_requests + expect(page).to have_content('Successfully activated') + expect(page).not_to have_content(user.email) + end + end + end end end describe 'GET /admin/users/new' do - let(:user_username) { 'bang' } + let_it_be(:user_username) { 'bang' } before do visit new_admin_user_path @@ -344,7 +352,7 @@ RSpec.describe 'Admin::Users' do end context 'username contains spaces' do - let(:user_username) { 'Bing bang' } + let_it_be(:user_username) { 'Bing bang' } it "doesn't create the user and shows an error message" do expect { click_button 'Create user' }.to change {User.count}.by(0) @@ -363,22 +371,6 @@ RSpec.describe 'Admin::Users' do visit new_admin_user_path end - def expects_external_to_be_checked - expect(find('#user_external')).to be_checked - end - - def expects_external_to_be_unchecked - expect(find('#user_external')).not_to be_checked - end - - def expects_warning_to_be_hidden - expect(find('#warning_external_automatically_set', visible: :all)[:class]).to include 'hidden' - end - - def expects_warning_to_be_shown - expect(find('#warning_external_automatically_set')[:class]).not_to include 'hidden' - end - it 'automatically unchecks external for matching email' do expects_external_to_be_checked expects_warning_to_be_hidden @@ -413,55 +405,22 @@ RSpec.describe 'Admin::Users' do expect(new_user.external).to be_falsy end - end - end - end - - describe 'GET /admin/users/:id/edit' do - before do - stub_feature_flags(vue_admin_users: false) - visit admin_users_path - click_link "edit_user_#{user.id}" - end - - it 'has user edit page' do - expect(page).to have_content('Name') - expect(page).to have_content('Password') - end - - describe 'Update user' do - before do - fill_in 'user_name', with: 'Big Bang' - fill_in 'user_email', with: 'bigbang@mail.com' - fill_in 'user_password', with: 'AValidPassword1' - fill_in 'user_password_confirmation', with: 'AValidPassword1' - choose 'user_access_level_admin' - click_button 'Save changes' - end - - it 'shows page with new data' do - expect(page).to have_content('bigbang@mail.com') - expect(page).to have_content('Big Bang') - end - it 'changes user entry' do - user.reload - expect(user.name).to eq('Big Bang') - expect(user.admin?).to be_truthy - expect(user.password_expires_at).to be <= Time.now - end - end + def expects_external_to_be_checked + expect(find('#user_external')).to be_checked + end - describe 'update username to non ascii char' do - it do - fill_in 'user_username', with: '\u3042\u3044' - click_button('Save') + def expects_external_to_be_unchecked + expect(find('#user_external')).not_to be_checked + end - page.within '#error_explanation' do - expect(page).to have_content('Username') + def expects_warning_to_be_hidden + expect(find('#warning_external_automatically_set', visible: :all)[:class]).to include 'hidden' end - expect(page).to have_selector(%(form[action="/admin/users/#{user.username}"])) + def expects_warning_to_be_shown + expect(find('#warning_external_automatically_set')[:class]).not_to include 'hidden' + end end end end @@ -541,15 +500,108 @@ RSpec.describe 'Admin::Users' do check_breadcrumb('Edit Identity') end + + def check_breadcrumb(content) + expect(find('.breadcrumbs-sub-title')).to have_content(content) + end end - def check_breadcrumb(content) - expect(find('.breadcrumbs-sub-title')).to have_content(content) + describe 'GET /admin/users/:id/edit' do + before do + visit edit_admin_user_path(user) + end + + describe 'Update user' do + before do + fill_in 'user_name', with: 'Big Bang' + fill_in 'user_email', with: 'bigbang@mail.com' + fill_in 'user_password', with: 'AValidPassword1' + fill_in 'user_password_confirmation', with: 'AValidPassword1' + choose 'user_access_level_admin' + click_button 'Save changes' + end + + it 'shows page with new data' do + expect(page).to have_content('bigbang@mail.com') + expect(page).to have_content('Big Bang') + end + + it 'changes user entry' do + user.reload + expect(user.name).to eq('Big Bang') + expect(user.admin?).to be_truthy + expect(user.password_expires_at).to be <= Time.now + end + end + + describe 'update username to non ascii char' do + it do + fill_in 'user_username', with: '\u3042\u3044' + click_button('Save') + + page.within '#error_explanation' do + expect(page).to have_content('Username') + end + + expect(page).to have_selector(%(form[action="/admin/users/#{user.username}"])) + end + end + end + + # TODO: Move to main GET /admin/users block once feature flag is removed. Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/290737 + context 'with vue_admin_users feature flag enabled', :js do + before do + stub_feature_flags(vue_admin_users: true) + end + + describe 'GET /admin/users' do + context 'user group count', :js do + before do + group = create(:group) + group.add_developer(current_user) + project = create(:project, group: create(:group)) + project.add_reporter(current_user) + end + + it 'displays count of the users authorized groups' do + visit admin_users_path + + wait_for_requests + + expect(page.find("[data-testid='user-group-count-#{current_user.id}']").text).to eq("2") + end + end + end end - def sort_by(text) - page.within('.user-sort-dropdown') do - click_link text + def click_user_dropdown_toggle(user_id) + page.within("[data-testid='user-actions-#{user_id}']") do + find("[data-testid='dropdown-toggle']").click end end + + def first_row + page.all('[role="row"]')[1] + end + + def second_row + page.all('[role="row"]')[2] + end + + def sort_by(option) + page.within('.filtered-search-block') do + find('.dropdown-menu-toggle').click + click_link option + end + end + + def click_action_in_user_dropdown(user_id, action) + click_user_dropdown_toggle(user_id) + + within find("[data-testid='user-actions-#{user_id}']") do + find('li button', text: action).click + end + + wait_for_requests + end end |