Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
commit4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch)
tree5423a1c7516cffe36384133ade12572cf709398d /spec/features/admin
parente570267f2f6b326480d284e0164a6464ba4081bc (diff)
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.rb5
-rw-r--r--spec/features/admin/admin_dev_ops_report_spec.rb6
-rw-r--r--spec/features/admin/admin_groups_spec.rb10
-rw-r--r--spec/features/admin/admin_labels_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb70
-rw-r--r--spec/features/admin/admin_mode_spec.rb235
-rw-r--r--spec/features/admin/admin_projects_spec.rb36
-rw-r--r--spec/features/admin/admin_settings_spec.rb73
-rw-r--r--spec/features/admin/admin_users_spec.rb44
-rw-r--r--spec/features/admin/services/admin_visits_service_templates_spec.rb2
-rw-r--r--spec/features/admin/users/user_spec.rb177
-rw-r--r--spec/features/admin/users/users_spec.rb586
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