diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-19 15:44:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-19 15:44:42 +0000 |
commit | 4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch) | |
tree | 5423a1c7516cffe36384133ade12572cf709398d /spec/features/admin | |
parent | e570267f2f6b326480d284e0164a6464ba4081bc (diff) | |
download | gitlab-ce-4555e1b21c365ed8303ffb7a3325d773c9b8bf31.tar.gz |
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'spec/features/admin')
-rw-r--r-- | spec/features/admin/admin_appearance_spec.rb | 5 | ||||
-rw-r--r-- | spec/features/admin/admin_dev_ops_report_spec.rb | 6 | ||||
-rw-r--r-- | spec/features/admin/admin_groups_spec.rb | 10 | ||||
-rw-r--r-- | spec/features/admin/admin_labels_spec.rb | 2 | ||||
-rw-r--r-- | spec/features/admin/admin_mode/logout_spec.rb | 70 | ||||
-rw-r--r-- | spec/features/admin/admin_mode_spec.rb | 235 | ||||
-rw-r--r-- | spec/features/admin/admin_projects_spec.rb | 36 | ||||
-rw-r--r-- | spec/features/admin/admin_settings_spec.rb | 73 | ||||
-rw-r--r-- | spec/features/admin/admin_users_spec.rb | 44 | ||||
-rw-r--r-- | spec/features/admin/services/admin_visits_service_templates_spec.rb | 2 | ||||
-rw-r--r-- | spec/features/admin/users/user_spec.rb | 177 | ||||
-rw-r--r-- | spec/features/admin/users/users_spec.rb | 586 |
12 files changed, 704 insertions, 542 deletions
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb index 61e7efbc56c..603e757096f 100644 --- a/spec/features/admin/admin_appearance_spec.rb +++ b/spec/features/admin/admin_appearance_spec.rb @@ -37,7 +37,7 @@ RSpec.describe 'Admin Appearance' do expect_custom_sign_in_appearance(appearance) end - it 'preview new project page appearance' do + it 'preview new project page appearance', :js do sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) @@ -86,10 +86,11 @@ RSpec.describe 'Admin Appearance' do expect_custom_sign_in_appearance(appearance) end - it 'custom new project page' do + it 'custom new project page', :js do sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) visit new_project_path + find('[data-qa-selector="blank_project_link"]').click expect_custom_new_project_appearance(appearance) end diff --git a/spec/features/admin/admin_dev_ops_report_spec.rb b/spec/features/admin/admin_dev_ops_report_spec.rb index a05fa0640d8..33f984af807 100644 --- a/spec/features/admin/admin_dev_ops_report_spec.rb +++ b/spec/features/admin/admin_dev_ops_report_spec.rb @@ -53,15 +53,13 @@ RSpec.describe 'DevOps Report page', :js do end context 'when there is data to display' do - it 'shows numbers for each metric' do + it 'shows the DevOps Score app' do stub_application_setting(usage_ping_enabled: true) create(:dev_ops_report_metric) visit admin_dev_ops_report_path - expect(page).to have_content( - 'Issues created per active user 1.2 You 9.3 Lead 13.3%' - ) + expect(page).to have_selector('[data-testid="devops-score-app"]') end end end diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index e7634f4e020..f9673a8aa2f 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'Admin Groups' do include Select2Helper include Spec::Support::Helpers::Features::MembersHelpers + include Spec::Support::Helpers::Features::InviteMembersModalHelper let(:internal) { Gitlab::VisibilityLevel::INTERNAL } @@ -202,6 +203,7 @@ RSpec.describe 'Admin Groups' do select2(Gitlab::Access::REPORTER, from: '#access_level') end click_button "Add users to group" + page.within ".group-users-list" do expect(page).to have_content(user.name) expect(page).to have_content('Reporter') @@ -220,19 +222,13 @@ RSpec.describe 'Admin Groups' do describe 'add admin himself to a group' do before do - stub_feature_flags(invite_members_group_modal: false) group.add_user(:user, Gitlab::Access::OWNER) end it 'adds admin a to a group as developer', :js do visit group_group_members_path(group) - page.within '.invite-users-form' do - select2(current_user.id, from: '#user_ids', multiple: true) - select 'Developer', from: 'access_level' - end - - click_button 'Invite' + invite_member(current_user.name, role: 'Developer') page.within members_table do expect(page).to have_content(current_user.name) diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb index 43fb1f31a0f..08d81906d9f 100644 --- a/spec/features/admin/admin_labels_spec.rb +++ b/spec/features/admin/admin_labels_spec.rb @@ -36,7 +36,7 @@ RSpec.describe 'admin issues labels' do it 'deletes all labels', :js do page.within '.labels' do - page.all('.js-remove-row').each do |remove| + page.all('.js-remove-label').each do |remove| accept_confirm { remove.click } wait_for_requests end diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb index 8cfac5d8b99..664eb51e58f 100644 --- a/spec/features/admin/admin_mode/logout_spec.rb +++ b/spec/features/admin/admin_mode/logout_spec.rb @@ -8,37 +8,67 @@ RSpec.describe 'Admin Mode Logout', :js do let(:user) { create(:admin) } - before do - stub_feature_flags(combined_menu: false) + shared_examples 'combined_menu: feature flag examples' do + before do + gitlab_sign_in(user) + gitlab_enable_admin_mode_sign_in(user) + visit admin_root_path + end - gitlab_sign_in(user) - gitlab_enable_admin_mode_sign_in(user) - visit admin_root_path - end + it 'disable removes admin mode and redirects to root page' do + pending_on_combined_menu_flag - it 'disable removes admin mode and redirects to root page' do - gitlab_disable_admin_mode + gitlab_disable_admin_mode - expect(current_path).to eq root_path - expect(page).to have_link(href: new_admin_session_path) - end + expect(current_path).to eq root_path + expect(page).to have_link(href: new_admin_session_path) + end + + it 'disable shows flash notice' do + pending_on_combined_menu_flag + + gitlab_disable_admin_mode + + expect(page).to have_selector('.flash-notice') + end - it 'disable shows flash notice' do - gitlab_disable_admin_mode + context 'on a read-only instance' do + before do + allow(Gitlab::Database).to receive(:read_only?).and_return(true) + end - expect(page).to have_selector('.flash-notice') + it 'disable removes admin mode and redirects to root page' do + pending_on_combined_menu_flag + + gitlab_disable_admin_mode + + expect(current_path).to eq root_path + expect(page).to have_link(href: new_admin_session_path) + end + end end - context 'on a read-only instance' do + context 'with combined_menu: feature flag on' do + let(:needs_rewrite_for_combined_menu_flag_on) { true } + before do - allow(Gitlab::Database).to receive(:read_only?).and_return(true) + stub_feature_flags(combined_menu: true) end - it 'disable removes admin mode and redirects to root page' do - gitlab_disable_admin_mode + it_behaves_like 'combined_menu: feature flag examples' + end - expect(current_path).to eq root_path - expect(page).to have_link(href: new_admin_session_path) + context 'with combined_menu feature flag off' do + let(:needs_rewrite_for_combined_menu_flag_on) { false } + + before do + stub_feature_flags(combined_menu: false) end + + it_behaves_like 'combined_menu: feature flag examples' + end + + def pending_on_combined_menu_flag + pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on end end diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb index 633de20c82d..4df035b13e8 100644 --- a/spec/features/admin/admin_mode_spec.rb +++ b/spec/features/admin/admin_mode_spec.rb @@ -8,55 +8,41 @@ RSpec.describe 'Admin mode' do let(:admin) { create(:admin) } - before do - stub_feature_flags(combined_menu: false) - - stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') - end - - context 'application setting :admin_mode is enabled', :request_store do + shared_examples 'combined_menu: feature flag examples' do before do - sign_in(admin) + stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') end - context 'when not in admin mode' do - it 'has no leave admin mode button' do - visit new_admin_session_path - - page.within('.navbar-sub-nav') do - expect(page).not_to have_link(href: destroy_admin_session_path) - end + context 'application setting :admin_mode is enabled', :request_store do + before do + sign_in(admin) end - it 'can open pages not in admin scope' do - visit new_admin_session_path + context 'when not in admin mode' do + it 'has no leave admin mode button' do + visit new_admin_session_path - page.within('.navbar-sub-nav') do - find_all('a', text: 'Projects').first.click + page.within('.navbar-sub-nav') do + expect(page).not_to have_link(href: destroy_admin_session_path) + end end - expect(page).to have_current_path(dashboard_projects_path) - end - - it 'is necessary to provide credentials again before opening pages in admin scope' do - visit general_admin_application_settings_path # admin logged out because not in admin_mode - - expect(page).to have_current_path(new_admin_session_path) - end + it 'can open pages not in admin scope' do + pending_on_combined_menu_flag - it 'can enter admin mode' do - visit new_admin_session_path + visit new_admin_session_path - fill_in 'user_password', with: admin.password + page.within('.navbar-sub-nav') do + find_all('a', text: 'Projects').first.click + end - click_button 'Enter Admin Mode' + expect(page).to have_current_path(dashboard_projects_path) + end - expect(page).to have_current_path(admin_root_path) - end + it 'is necessary to provide credentials again before opening pages in admin scope' do + visit general_admin_application_settings_path # admin logged out because not in admin_mode - context 'on a read-only instance' do - before do - allow(Gitlab::Database).to receive(:read_only?).and_return(true) + expect(page).to have_current_path(new_admin_session_path) end it 'can enter admin mode' do @@ -68,108 +54,161 @@ RSpec.describe 'Admin mode' do expect(page).to have_current_path(admin_root_path) end - end - end - context 'when in admin_mode' do - before do - gitlab_enable_admin_mode_sign_in(admin) - end + context 'on a read-only instance' do + before do + allow(Gitlab::Database).to receive(:read_only?).and_return(true) + end - it 'contains link to leave admin mode' do - page.within('.navbar-sub-nav') do - expect(page).to have_link(href: destroy_admin_session_path) + it 'can enter admin mode' do + visit new_admin_session_path + + fill_in 'user_password', with: admin.password + + click_button 'Enter Admin Mode' + + expect(page).to have_current_path(admin_root_path) + end end end - it 'can leave admin mode using main dashboard link', :js do - page.within('.navbar-sub-nav') do - click_on 'Leave Admin Mode' + context 'when in admin_mode' do + before do + gitlab_enable_admin_mode_sign_in(admin) + end - expect(page).to have_link(href: new_admin_session_path) + it 'contains link to leave admin mode' do + pending_on_combined_menu_flag + + page.within('.navbar-sub-nav') do + expect(page).to have_link(href: destroy_admin_session_path) + end end - end - it 'can leave admin mode using dropdown menu on smaller screens', :js do - resize_screen_xs - visit root_dashboard_path + it 'can leave admin mode using main dashboard link', :js do + pending_on_combined_menu_flag - find('.header-more').click + page.within('.navbar-sub-nav') do + click_on 'Leave Admin Mode' - page.within '.navbar-sub-nav' do - click_on 'Leave Admin Mode' + expect(page).to have_link(href: new_admin_session_path) + end + end + + it 'can leave admin mode using dropdown menu on smaller screens', :js do + pending_on_combined_menu_flag + + resize_screen_xs + visit root_dashboard_path find('.header-more').click - expect(page).to have_link(href: new_admin_session_path) - end - end + page.within '.navbar-sub-nav' do + click_on 'Leave Admin Mode' - it 'can open pages not in admin scope' do - page.within('.navbar-sub-nav') do - find_all('a', text: 'Projects').first.click + find('.header-more').click - expect(page).to have_current_path(dashboard_projects_path) + expect(page).to have_link(href: new_admin_session_path) + end end - end - context 'nav bar' do - it 'shows admin dashboard links on bigger screen' do - visit root_dashboard_path + it 'can open pages not in admin scope' do + pending_on_combined_menu_flag - page.within '.navbar' do - expect(page).to have_link(text: 'Admin Area', href: admin_root_path, visible: true) - expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true) + page.within('.navbar-sub-nav') do + find_all('a', text: 'Projects').first.click + + expect(page).to have_current_path(dashboard_projects_path) end end - it 'relocates admin dashboard links to dropdown list on smaller screen', :js do - resize_screen_xs - visit root_dashboard_path + context 'nav bar' do + it 'shows admin dashboard links on bigger screen' do + pending_on_combined_menu_flag - page.within '.navbar' do - expect(page).not_to have_link(text: 'Admin Area', href: admin_root_path, visible: true) - expect(page).not_to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true) + visit root_dashboard_path + + page.within '.navbar' do + expect(page).to have_link(text: 'Admin Area', href: admin_root_path, visible: true) + expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true) + end end - find('.header-more').click + it 'relocates admin dashboard links to dropdown list on smaller screen', :js do + pending_on_combined_menu_flag + + resize_screen_xs + visit root_dashboard_path - page.within '.navbar' do - expect(page).to have_link(text: 'Admin Area', href: admin_root_path, visible: true) - expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true) + page.within '.navbar' do + expect(page).not_to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true) + end + + find('.header-more').click + + page.within '.navbar' do + expect(page).to have_link(text: 'Admin Area', href: admin_root_path, visible: true) + expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true) + end end end - end - context 'on a read-only instance' do - before do - allow(Gitlab::Database).to receive(:read_only?).and_return(true) - end + context 'on a read-only instance' do + before do + allow(Gitlab::Database).to receive(:read_only?).and_return(true) + end - it 'can leave admin mode', :js do - page.within('.navbar-sub-nav') do - click_on 'Leave Admin Mode' + it 'can leave admin mode', :js do + pending_on_combined_menu_flag - expect(page).to have_link(href: new_admin_session_path) + page.within('.navbar-sub-nav') do + click_on 'Leave Admin Mode' + + expect(page).to have_link(href: new_admin_session_path) + end end end end end + + context 'application setting :admin_mode is disabled' do + before do + stub_application_setting(admin_mode: false) + sign_in(admin) + end + + it 'shows no admin mode buttons in navbar' do + visit admin_root_path + + page.within('.navbar-sub-nav') do + expect(page).not_to have_link(href: new_admin_session_path) + expect(page).not_to have_link(href: destroy_admin_session_path) + end + end + end end - context 'application setting :admin_mode is disabled' do + context 'with combined_menu: feature flag on' do + let(:needs_rewrite_for_combined_menu_flag_on) { true } + before do - stub_application_setting(admin_mode: false) - sign_in(admin) + stub_feature_flags(combined_menu: true) end - it 'shows no admin mode buttons in navbar' do - visit admin_root_path + it_behaves_like 'combined_menu: feature flag examples' + end - page.within('.navbar-sub-nav') do - expect(page).not_to have_link(href: new_admin_session_path) - expect(page).not_to have_link(href: destroy_admin_session_path) - end + context 'with combined_menu feature flag off' do + let(:needs_rewrite_for_combined_menu_flag_on) { false } + + before do + stub_feature_flags(combined_menu: false) end + + it_behaves_like 'combined_menu: feature flag examples' + end + + def pending_on_combined_menu_flag + pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on end end diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index bf280595ec7..cbbe9aa3b8b 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe "Admin::Projects" do include Spec::Support::Helpers::Features::MembersHelpers + include Spec::Support::Helpers::Features::InviteMembersModalHelper include Select2Helper let(:user) { create :user } @@ -95,21 +96,27 @@ RSpec.describe "Admin::Projects" do describe 'admin adds themselves to the project', :js do before do project.add_maintainer(user) - stub_feature_flags(invite_members_group_modal: false) end it 'adds admin to the project as developer' do visit project_project_members_path(project) - page.within '.invite-users-form' do - select2(current_user.id, from: '#user_ids', multiple: true) - select 'Developer', from: 'access_level' - end - - click_button 'Invite' + invite_member(current_user.name, role: 'Developer') expect(find_member_row(current_user)).to have_content('Developer') end + + context 'with the invite_members_group_modal feature flag disabled' do + it 'adds admin to the project as developer' do + stub_feature_flags(invite_members_group_modal: false) + + visit project_project_members_path(project) + + add_member_using_form(current_user.id, role: 'Developer') + + expect(find_member_row(current_user)).to have_content('Developer') + end + end end describe 'admin removes themselves from the project', :js do @@ -134,4 +141,19 @@ RSpec.describe "Admin::Projects" do expect(current_path).to match dashboard_projects_path end end + + # temporary method for the form until the :invite_members_group_modal feature flag is + # enabled: https://gitlab.com/gitlab-org/gitlab/-/issues/247208 + def add_member_using_form(id, role: 'Developer') + page.within '.invite-users-form' do + select2(id, from: '#user_ids', multiple: true) + + fill_in 'expires_at', with: 5.days.from_now.to_date + find_field('expires_at').native.send_keys :enter + + select(role, from: "access_level") + + click_on 'Invite' + end + end end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 90ce865cc00..0a7113a5559 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -251,40 +251,62 @@ RSpec.describe 'Admin updates settings' do end end - context 'when the Slack Notifications Service template is active' do + context 'when Service Templates are enabled' do before do - create(:service, :template, type: 'SlackService', active: true) - + stub_feature_flags(disable_service_templates: false) visit general_admin_application_settings_path end - it 'change Slack Notifications Service template settings', :js do - first(:link, 'Service Templates').click - click_link 'Slack notifications' - fill_in 'Webhook', with: 'http://localhost' - fill_in 'Username', with: 'test_user' - fill_in 'service[push_channel]', with: '#test_channel' - page.check('Notify only broken pipelines') - page.select 'All branches', from: 'Branches to be notified' + it 'shows Service Templates link' do + expect(page).to have_link('Service Templates') + end - check_all_events - click_button 'Save changes' + context 'when the Slack Notifications Service template is active' do + before do + create(:service, :template, type: 'SlackService', active: true) - expect(page).to have_content 'Application settings saved successfully' + visit general_admin_application_settings_path + end - click_link 'Slack notifications' + it 'change Slack Notifications Service template settings', :js do + first(:link, 'Service Templates').click + click_link 'Slack notifications' + fill_in 'Webhook', with: 'http://localhost' + fill_in 'Username', with: 'test_user' + fill_in 'service[push_channel]', with: '#test_channel' + page.check('Notify only broken pipelines') + page.select 'All branches', from: 'Branches to be notified' + page.select 'Match any of the labels', from: 'Labels to be notified behavior' + + check_all_events + click_button 'Save changes' + + expect(page).to have_content 'Application settings saved successfully' - expect(page.all('input[type=checkbox]')).to all(be_checked) - expect(find_field('Webhook').value).to eq 'http://localhost' - expect(find_field('Username').value).to eq 'test_user' - expect(find('[name="service[push_channel]"]').value).to eq '#test_channel' + click_link 'Slack notifications' + + expect(page.all('input[type=checkbox]')).to all(be_checked) + expect(find_field('Webhook').value).to eq 'http://localhost' + expect(find_field('Username').value).to eq 'test_user' + expect(find('[name="service[push_channel]"]').value).to eq '#test_channel' + end + + it 'defaults Deployment events to false for chat notification template settings', :js do + first(:link, 'Service Templates').click + click_link 'Slack notifications' + + expect(find_field('Deployment')).not_to be_checked + end end + end - it 'defaults Deployment events to false for chat notification template settings', :js do - first(:link, 'Service Templates').click - click_link 'Slack notifications' + context 'When Service templates are disabled' do + before do + stub_feature_flags(disable_service_templates: true) + end - expect(find_field('Deployment')).not_to be_checked + it 'does not show Service Templates link' do + expect(page).not_to have_link('Service Templates') end end @@ -424,7 +446,8 @@ RSpec.describe 'Admin updates settings' do check 'Enable reCAPTCHA for login' fill_in 'IPs per user', with: 15 check 'Enable Spam Check via external API endpoint' - fill_in 'URL of the external Spam Check endpoint', with: 'https://www.example.com/spamcheck' + fill_in 'URL of the external Spam Check endpoint', with: 'grpc://www.example.com/spamcheck' + fill_in 'Spam Check API Key', with: 'SPAM_CHECK_API_KEY' click_button 'Save changes' end @@ -433,7 +456,7 @@ RSpec.describe 'Admin updates settings' do expect(current_settings.login_recaptcha_protection_enabled).to be true expect(current_settings.unique_ips_limit_per_user).to eq(15) expect(current_settings.spam_check_endpoint_enabled).to be true - expect(current_settings.spam_check_endpoint_url).to eq 'https://www.example.com/spamcheck' + expect(current_settings.spam_check_endpoint_url).to eq 'grpc://www.example.com/spamcheck' end end diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index 4fc60d17886..6d5944002a1 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -10,61 +10,51 @@ RSpec.describe "Admin::Users" do gitlab_enable_admin_mode_sign_in(current_user) end - describe 'Tabs', :js do + describe 'Tabs' do let(:tabs_selector) { '.js-users-tabs' } let(:active_tab_selector) { '.nav-link.active' } - it 'does not add the tab param when the Users tab is selected' do - visit admin_users_path + it 'links to the Users tab' do + visit cohorts_admin_users_path within tabs_selector do click_link 'Users' + + expect(page).to have_selector active_tab_selector, text: 'Users' end expect(page).to have_current_path(admin_users_path) end - it 'adds the ?tab=cohorts param when the Cohorts tab is selected' do + it 'links to the Cohorts tab' do visit admin_users_path within tabs_selector do click_link 'Cohorts' + + expect(page).to have_selector active_tab_selector, text: 'Cohorts' end - expect(page).to have_current_path(admin_users_path(tab: 'cohorts')) + expect(page).to have_current_path(cohorts_admin_users_path) + expect(page).to have_selector active_tab_selector, text: 'Cohorts' end - it 'shows the cohorts tab when the tab param is set' do + it 'redirects legacy route' do visit admin_users_path(tab: 'cohorts') - within tabs_selector do - expect(page).to have_selector active_tab_selector, text: 'Cohorts' - end + expect(page).to have_current_path(cohorts_admin_users_path) end end describe 'Cohorts tab content' do - context 'with usage ping enabled' do - it 'shows users count per month' do - stub_application_setting(usage_ping_enabled: true) + it 'shows users count per month' do + stub_application_setting(usage_ping_enabled: false) - create_list(:user, 2) + create_list(:user, 2) - visit admin_users_path(tab: 'cohorts') - - expect(page).to have_content("#{Time.now.strftime('%b %Y')} 3 0") - end - end - - context 'with usage ping disabled' do - it 'shows empty state', :js do - stub_application_setting(usage_ping_enabled: false) - - visit admin_users_path(tab: 'cohorts') + visit admin_users_path(tab: 'cohorts') - expect(page).to have_selector(".js-empty-state") - expect(page).to have_content("Activate user activity analysis") - end + expect(page).to have_content("#{Time.now.strftime('%b %Y')} 3 0") end end end diff --git a/spec/features/admin/services/admin_visits_service_templates_spec.rb b/spec/features/admin/services/admin_visits_service_templates_spec.rb index 1fd8c8316e3..9d011b97f63 100644 --- a/spec/features/admin/services/admin_visits_service_templates_spec.rb +++ b/spec/features/admin/services/admin_visits_service_templates_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Admin visits service templates' do let(:admin) { create(:user, :admin) } - let(:slack_service) { Service.for_template.find { |s| s.type == 'SlackService' } } + let(:slack_service) { Integration.for_template.find { |s| s.type == 'SlackService' } } before do sign_in(admin) diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb index befa7bd338b..01341398135 100644 --- a/spec/features/admin/users/user_spec.rb +++ b/spec/features/admin/users/user_spec.rb @@ -4,18 +4,16 @@ require 'spec_helper' RSpec.describe 'Admin::Users::User' do let_it_be(:user) { 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) - stub_feature_flags(vue_admin_users: false) end describe 'GET /admin/users/:id' do it 'has user info', :aggregate_failures do - visit admin_users_path - click_link user.name + visit admin_user_path(user) expect(page).to have_content(user.email) expect(page).to have_content(user.name) @@ -27,21 +25,6 @@ RSpec.describe 'Admin::Users::User' do expect(page).to have_button('Delete user and contributions') end - context 'user pending approval' do - it 'shows user info', :aggregate_failures do - user = create(:user, :blocked_pending_approval) - - visit admin_users_path - click_link 'Pending approval' - click_link user.name - - expect(page).to have_content(user.name) - expect(page).to have_content('Pending approval') - expect(page).to have_link('Approve user') - expect(page).to have_link('Reject request') - end - end - context 'when blocking/unblocking the user' do it 'shows confirmation and allows blocking and unblocking', :js do visit admin_user_path(user) @@ -171,6 +154,8 @@ RSpec.describe 'Admin::Users::User' do it 'logs in as the user when impersonate is clicked' do subject + find('[data-qa-selector="user_menu"]').click + expect(page.find(:css, '[data-testid="user-profile-link"]')['data-user']).to eql(another_user.username) end @@ -205,6 +190,8 @@ RSpec.describe 'Admin::Users::User' do it 'logs out of impersonated user back to original user' do subject + find('[data-qa-selector="user_menu"]').click + expect(page.find(:css, '[data-testid="user-profile-link"]')['data-user']).to eq(current_user.username) end @@ -238,6 +225,8 @@ RSpec.describe 'Admin::Users::User' do end it 'shows when disabled' do + user.update!(otp_required_for_login: false) + visit admin_user_path(user) expect_two_factor_status('Disabled') @@ -251,7 +240,7 @@ RSpec.describe 'Admin::Users::User' do end describe 'Email verification status' do - let!(:secondary_email) do + let_it_be(:secondary_email) do create :email, email: 'secondary@example.com', user: user end @@ -274,99 +263,121 @@ RSpec.describe 'Admin::Users::User' do expect(page).to have_content("#{secondary_email.email} Verified") end end - end - - describe 'show user attributes' do - it 'has expected attributes', :aggregate_failures do - visit admin_users_path - click_link user.name + describe 'show user identities' do + it 'shows user identities', :aggregate_failures do + visit admin_user_identities_path(user) - expect(page).to have_content 'Account' - expect(page).to have_content 'Personal projects limit' + expect(page).to have_content(user.name) + expect(page).to have_content('twitter') + end end - end - describe 'remove users secondary email', :js do - let!(:secondary_email) do - create :email, email: 'secondary@example.com', user: user + describe 'update user identities' do + before do + allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:twitter, :twitter_updated]) + end + + it 'modifies twitter identity', :aggregate_failures do + visit admin_user_identities_path(user) + + find('.table').find(:link, 'Edit').click + fill_in 'identity_extern_uid', with: '654321' + select 'twitter_updated', from: 'identity_provider' + click_button 'Save changes' + + expect(page).to have_content(user.name) + expect(page).to have_content('twitter_updated') + expect(page).to have_content('654321') + end end - it do - visit admin_user_path(user.username) + describe 'remove users secondary email', :js do + let_it_be(:secondary_email) do + create :email, email: 'secondary@example.com', user: user + end + + it do + visit admin_user_path(user.username) - expect(page).to have_content("Secondary email: #{secondary_email.email}") + expect(page).to have_content("Secondary email: #{secondary_email.email}") - accept_confirm { find("#remove_email_#{secondary_email.id}").click } + accept_confirm { find("#remove_email_#{secondary_email.id}").click } - expect(page).not_to have_content(secondary_email.email) + expect(page).not_to have_content(secondary_email.email) + end end - end - describe 'show user keys', :js do - it do - key1 = create(:key, user: user, title: 'ssh-rsa Key1', key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4FIEBXGi4bPU8kzxMefudPIJ08/gNprdNTaO9BR/ndy3+58s2HCTw2xCHcsuBmq+TsAqgEidVq4skpqoTMB+Uot5Uzp9z4764rc48dZiI661izoREoKnuRQSsRqUTHg5wrLzwxlQbl1MVfRWQpqiz/5KjBC7yLEb9AbusjnWBk8wvC1bQPQ1uLAauEA7d836tgaIsym9BrLsMVnR4P1boWD3Xp1B1T/ImJwAGHvRmP/ycIqmKdSpMdJXwxcb40efWVj0Ibbe7ii9eeoLdHACqevUZi6fwfbymdow+FeqlkPoHyGg3Cu4vD/D8+8cRc7mE/zGCWcQ15Var83Tczour Key1') - key2 = create(:key, user: user, title: 'ssh-rsa Key2', key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQSTWXhJAX/He+nG78MiRRRn7m0Pb0XbcgTxE0etArgoFoh9WtvDf36HG6tOSg/0UUNcp0dICsNAmhBKdncp6cIyPaXJTURPRAGvhI0/VDk4bi27bRnccGbJ/hDaUxZMLhhrzY0r22mjVf8PF6dvv5QUIQVm1/LeaWYsHHvLgiIjwrXirUZPnFrZw6VLREoBKG8uWvfSXw1L5eapmstqfsME8099oi+vWLR8MgEysZQmD28M73fgW4zek6LDQzKQyJx9nB+hJkKUDvcuziZjGmRFlNgSA2mguERwL1OXonD8WYUrBDGKroIvBT39zS5d9tQDnidEJZ9Y8gv5ViYP7x Key2') + describe 'remove user with identities' do + it 'removes user with twitter identity', :aggregate_failures do + visit admin_user_identities_path(user) - visit admin_users_path + click_link 'Delete' - click_link user.name - click_link 'SSH keys' + expect(page).to have_content(user.name) + expect(page).not_to have_content('twitter') + end + end - expect(page).to have_content(key1.title) - expect(page).to have_content(key2.title) + describe 'show user keys', :js do + it do + key1 = create(:key, user: user, title: 'ssh-rsa Key1', key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4FIEBXGi4bPU8kzxMefudPIJ08/gNprdNTaO9BR/ndy3+58s2HCTw2xCHcsuBmq+TsAqgEidVq4skpqoTMB+Uot5Uzp9z4764rc48dZiI661izoREoKnuRQSsRqUTHg5wrLzwxlQbl1MVfRWQpqiz/5KjBC7yLEb9AbusjnWBk8wvC1bQPQ1uLAauEA7d836tgaIsym9BrLsMVnR4P1boWD3Xp1B1T/ImJwAGHvRmP/ycIqmKdSpMdJXwxcb40efWVj0Ibbe7ii9eeoLdHACqevUZi6fwfbymdow+FeqlkPoHyGg3Cu4vD/D8+8cRc7mE/zGCWcQ15Var83Tczour Key1') + key2 = create(:key, user: user, title: 'ssh-rsa Key2', key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQSTWXhJAX/He+nG78MiRRRn7m0Pb0XbcgTxE0etArgoFoh9WtvDf36HG6tOSg/0UUNcp0dICsNAmhBKdncp6cIyPaXJTURPRAGvhI0/VDk4bi27bRnccGbJ/hDaUxZMLhhrzY0r22mjVf8PF6dvv5QUIQVm1/LeaWYsHHvLgiIjwrXirUZPnFrZw6VLREoBKG8uWvfSXw1L5eapmstqfsME8099oi+vWLR8MgEysZQmD28M73fgW4zek6LDQzKQyJx9nB+hJkKUDvcuziZjGmRFlNgSA2mguERwL1OXonD8WYUrBDGKroIvBT39zS5d9tQDnidEJZ9Y8gv5ViYP7x Key2') - click_link key2.title + visit admin_user_path(user) - expect(page).to have_content(key2.title) - expect(page).to have_content(key2.key) + click_link 'SSH keys' - click_button 'Delete' + expect(page).to have_content(key1.title) + expect(page).to have_content(key2.title) - page.within('.modal') do - page.click_button('Delete') - end + click_link key2.title - expect(page).not_to have_content(key2.title) - end - end + expect(page).to have_content(key2.title) + expect(page).to have_content(key2.key) - describe 'show user identities' do - it 'shows user identities', :aggregate_failures do - visit admin_user_identities_path(user) + click_button 'Delete' - expect(page).to have_content(user.name) - expect(page).to have_content('twitter') - end - end + page.within('.modal') do + page.click_button('Delete') + end - describe 'update user identities' do - before do - allow(Gitlab::Auth::OAuth::Provider).to receive(:providers).and_return([:twitter, :twitter_updated]) + expect(page).not_to have_content(key2.title) + end end - it 'modifies twitter identity', :aggregate_failures do - visit admin_user_identities_path(user) - - find('.table').find(:link, 'Edit').click - fill_in 'identity_extern_uid', with: '654321' - select 'twitter_updated', from: 'identity_provider' - click_button 'Save changes' + describe 'show user attributes' do + it 'has expected attributes', :aggregate_failures do + visit admin_user_path(user) - expect(page).to have_content(user.name) - expect(page).to have_content('twitter_updated') - expect(page).to have_content('654321') + expect(page).to have_content 'Account' + expect(page).to have_content 'Personal projects limit' + end end end - describe 'remove user with identities' do - it 'removes user with twitter identity', :aggregate_failures do - visit admin_user_identities_path(user) + [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 - click_link 'Delete' + describe 'GET /admin/users' do + context 'user pending approval' do + it 'shows user info', :aggregate_failures do + user = create(:user, :blocked_pending_approval) - expect(page).to have_content(user.name) - expect(page).not_to have_content('twitter') + visit admin_users_path + click_link 'Pending approval' + click_link user.name + + expect(page).to have_content(user.name) + expect(page).to have_content('Pending approval') + expect(page).to have_link('Approve user') + expect(page).to have_link('Reject request') + end + end + end end end end 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 |