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:
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/abuse_report_spec.rb2
-rw-r--r--spec/features/admin/admin_abuse_reports_spec.rb4
-rw-r--r--spec/features/admin/admin_appearance_spec.rb40
-rw-r--r--spec/features/admin/admin_broadcast_messages_spec.rb10
-rw-r--r--spec/features/admin/admin_browse_spam_logs_spec.rb6
-rw-r--r--spec/features/admin/admin_builds_spec.rb4
-rw-r--r--spec/features/admin/admin_cohorts_spec.rb4
-rw-r--r--spec/features/admin/admin_deploy_keys_spec.rb4
-rw-r--r--spec/features/admin/admin_dev_ops_report_spec.rb4
-rw-r--r--spec/features/admin/admin_disables_git_access_protocol_spec.rb1
-rw-r--r--spec/features/admin/admin_disables_two_factor_spec.rb8
-rw-r--r--spec/features/admin/admin_groups_spec.rb19
-rw-r--r--spec/features/admin/admin_health_check_spec.rb1
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb4
-rw-r--r--spec/features/admin/admin_hooks_spec.rb1
-rw-r--r--spec/features/admin/admin_labels_spec.rb4
-rw-r--r--spec/features/admin/admin_manage_applications_spec.rb4
-rw-r--r--spec/features/admin/admin_mode/login_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/workers_spec.rb2
-rw-r--r--spec/features/admin/admin_mode_spec.rb2
-rw-r--r--spec/features/admin/admin_projects_spec.rb1
-rw-r--r--spec/features/admin/admin_requests_profiles_spec.rb4
-rw-r--r--spec/features/admin/admin_runners_spec.rb10
-rw-r--r--spec/features/admin/admin_sees_project_statistics_spec.rb3
-rw-r--r--spec/features/admin/admin_sees_projects_statistics_spec.rb1
-rw-r--r--spec/features/admin/admin_serverless_domains_spec.rb12
-rw-r--r--spec/features/admin/admin_settings_spec.rb58
-rw-r--r--spec/features/admin/admin_system_info_spec.rb4
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb1
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb2
-rw-r--r--spec/features/admin/clusters/applications_spec.rb1
-rw-r--r--spec/features/admin/clusters/eks_spec.rb1
-rw-r--r--spec/features/admin/dashboard_spec.rb4
-rw-r--r--spec/features/admin/services/admin_activates_prometheus_spec.rb1
-rw-r--r--spec/features/admin/services/admin_visits_service_templates_spec.rb1
-rw-r--r--spec/features/admin/users/user_spec.rb372
-rw-r--r--spec/features/admin/users/users_spec.rb (renamed from spec/features/admin/admin_users_spec.rb)480
-rw-r--r--spec/features/alert_management/alert_management_list_spec.rb54
-rw-r--r--spec/features/alerts_settings/user_views_alerts_settings_spec.rb15
-rw-r--r--spec/features/boards/add_issues_modal_spec.rb5
-rw-r--r--spec/features/boards/boards_spec.rb4
-rw-r--r--spec/features/boards/keyboard_shortcut_spec.rb8
-rw-r--r--spec/features/boards/sidebar_spec.rb2
-rw-r--r--spec/features/breadcrumbs_schema_markup_spec.rb15
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb4
-rw-r--r--spec/features/commits_spec.rb2
-rw-r--r--spec/features/cycle_analytics_spec.rb14
-rw-r--r--spec/features/dashboard/archived_projects_spec.rb2
-rw-r--r--spec/features/dashboard/group_spec.rb3
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb40
-rw-r--r--spec/features/dashboard/shortcuts_spec.rb4
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb4
-rw-r--r--spec/features/expand_collapse_diffs_spec.rb4
-rw-r--r--spec/features/file_uploads/git_lfs_spec.rb4
-rw-r--r--spec/features/file_uploads/multipart_invalid_uploads_spec.rb2
-rw-r--r--spec/features/file_uploads/nuget_package_spec.rb2
-rw-r--r--spec/features/global_search_spec.rb6
-rw-r--r--spec/features/groups/board_spec.rb2
-rw-r--r--spec/features/groups/container_registry_spec.rb7
-rw-r--r--spec/features/groups/dependency_proxy_spec.rb16
-rw-r--r--spec/features/groups/import_export/connect_instance_spec.rb88
-rw-r--r--spec/features/groups/import_export/import_file_spec.rb8
-rw-r--r--spec/features/groups/members/filter_members_spec.rb26
-rw-r--r--spec/features/groups/members/search_members_spec.rb7
-rw-r--r--spec/features/groups/members/sort_members_spec.rb204
-rw-r--r--spec/features/groups/members/tabs_spec.rb14
-rw-r--r--spec/features/groups/navbar_spec.rb1
-rw-r--r--spec/features/groups/show_spec.rb65
-rw-r--r--spec/features/groups_spec.rb54
-rw-r--r--spec/features/ide/user_sees_editor_info_spec.rb93
-rw-r--r--spec/features/incidents/user_views_incident_spec.rb10
-rw-r--r--spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb2
-rw-r--r--spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb5
-rw-r--r--spec/features/issues/discussion_lock_spec.rb (renamed from spec/features/issuables/discussion_lock_spec.rb)0
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb8
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb112
-rw-r--r--spec/features/issues/issue_header_spec.rb164
-rw-r--r--spec/features/issues/issue_state_spec.rb81
-rw-r--r--spec/features/issues/keyboard_shortcut_spec.rb4
-rw-r--r--spec/features/issues/related_issues_spec.rb (renamed from spec/features/issuables/related_issues_spec.rb)0
-rw-r--r--spec/features/issues/service_desk_spec.rb26
-rw-r--r--spec/features/issues/user_edits_issue_spec.rb1
-rw-r--r--spec/features/issues/user_uses_quick_actions_spec.rb1
-rw-r--r--spec/features/issues/user_views_issue_spec.rb10
-rw-r--r--spec/features/markdown/copy_as_gfm_spec.rb11
-rw-r--r--spec/features/markdown/mermaid_spec.rb8
-rw-r--r--spec/features/merge_request/close_reopen_report_toggle_spec.rb (renamed from spec/features/issuables/close_reopen_report_toggle_spec.rb)118
-rw-r--r--spec/features/merge_request/merge_request_discussion_lock_spec.rb (renamed from spec/features/issuables/merge_request_discussion_lock_spec.rb)0
-rw-r--r--spec/features/merge_request/user_closes_merge_request_spec.rb23
-rw-r--r--spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb101
-rw-r--r--spec/features/merge_request/user_comments_on_diff_spec.rb26
-rw-r--r--spec/features/merge_request/user_posts_diff_notes_spec.rb10
-rw-r--r--spec/features/merge_request/user_reopens_merge_request_spec.rb28
-rw-r--r--spec/features/merge_request/user_resolves_conflicts_spec.rb5
-rw-r--r--spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb1
-rw-r--r--spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb4
-rw-r--r--spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb1
-rw-r--r--spec/features/merge_request/user_sees_versions_spec.rb16
-rw-r--r--spec/features/merge_request/user_squashes_merge_request_spec.rb (renamed from spec/features/merge_requests/user_squashes_merge_request_spec.rb)0
-rw-r--r--spec/features/merge_request/user_views_diffs_commit_spec.rb (renamed from spec/features/merge_requests/user_views_diffs_commit_spec.rb)0
-rw-r--r--spec/features/merge_request/user_views_diffs_file_by_file_spec.rb4
-rw-r--r--spec/features/merge_request/user_views_diffs_spec.rb4
-rw-r--r--spec/features/merge_requests/user_sees_empty_state_spec.rb (renamed from spec/features/merge_request/user_sees_empty_state_spec.rb)0
-rw-r--r--spec/features/milestone_spec.rb2
-rw-r--r--spec/features/operations_sidebar_link_spec.rb71
-rw-r--r--spec/features/profiles/account_spec.rb4
-rw-r--r--spec/features/profiles/active_sessions_spec.rb11
-rw-r--r--spec/features/profiles/emails_spec.rb6
-rw-r--r--spec/features/profiles/gpg_keys_spec.rb6
-rw-r--r--spec/features/profiles/keys_spec.rb2
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb26
-rw-r--r--spec/features/profiles/user_changes_notified_of_own_activity_spec.rb4
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb82
-rw-r--r--spec/features/projects/active_tabs_spec.rb8
-rw-r--r--spec/features/projects/blobs/balsamiq_spec.rb17
-rw-r--r--spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb11
-rw-r--r--spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb2
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb2
-rw-r--r--spec/features/projects/clusters_spec.rb2
-rw-r--r--spec/features/projects/container_registry_spec.rb18
-rw-r--r--spec/features/projects/diffs/diff_show_spec.rb4
-rw-r--r--spec/features/projects/environments/environment_metrics_spec.rb2
-rw-r--r--spec/features/projects/environments/environments_spec.rb55
-rw-r--r--spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb112
-rw-r--r--spec/features/projects/features_visibility_spec.rb3
-rw-r--r--spec/features/projects/gfm_autocomplete_load_spec.rb2
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb77
-rw-r--r--spec/features/projects/jobs/permissions_spec.rb162
-rw-r--r--spec/features/projects/jobs_spec.rb133
-rw-r--r--spec/features/projects/labels/issues_sorted_by_priority_spec.rb4
-rw-r--r--spec/features/projects/new_project_spec.rb54
-rw-r--r--spec/features/projects/settings/operations_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb25
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb4
-rw-r--r--spec/features/projects/settings/service_desk_setting_spec.rb55
-rw-r--r--spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb2
-rw-r--r--spec/features/projects/show/developer_views_empty_project_instructions_spec.rb20
-rw-r--r--spec/features/projects/show/no_password_spec.rb10
-rw-r--r--spec/features/projects/show/schema_markup_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_git_instructions_spec.rb6
-rw-r--r--spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb4
-rw-r--r--spec/features/projects/terraform_spec.rb94
-rw-r--r--spec/features/projects/user_creates_project_spec.rb3
-rw-r--r--spec/features/projects/user_sorts_projects_spec.rb82
-rw-r--r--spec/features/projects/user_views_empty_project_spec.rb26
-rw-r--r--spec/features/projects/wiki/user_git_access_wiki_page_spec.rb21
-rw-r--r--spec/features/projects/wikis_spec.rb1
-rw-r--r--spec/features/projects_spec.rb14
-rw-r--r--spec/features/protected_branches_spec.rb1
-rw-r--r--spec/features/protected_tags_spec.rb2
-rw-r--r--spec/features/registrations/experience_level_spec.rb10
-rw-r--r--spec/features/runners_spec.rb28
-rw-r--r--spec/features/search/user_searches_for_code_spec.rb9
-rw-r--r--spec/features/search/user_searches_for_issues_spec.rb9
-rw-r--r--spec/features/search/user_searches_for_merge_requests_spec.rb9
-rw-r--r--spec/features/search/user_searches_for_milestones_spec.rb9
-rw-r--r--spec/features/search/user_searches_for_wiki_pages_spec.rb9
-rw-r--r--spec/features/search/user_uses_search_filters_spec.rb26
-rw-r--r--spec/features/security/admin_access_spec.rb27
-rw-r--r--spec/features/security/project/internal_access_spec.rb48
-rw-r--r--spec/features/security/project/private_access_spec.rb93
-rw-r--r--spec/features/security/project/public_access_spec.rb48
-rw-r--r--spec/features/security/project/snippet/internal_access_spec.rb9
-rw-r--r--spec/features/security/project/snippet/private_access_spec.rb12
-rw-r--r--spec/features/security/project/snippet/public_access_spec.rb9
-rw-r--r--spec/features/snippets/private_snippets_spec.rb2
-rw-r--r--spec/features/snippets/public_snippets_spec.rb4
-rw-r--r--spec/features/snippets/search_snippets_spec.rb2
-rw-r--r--spec/features/snippets/user_creates_snippet_spec.rb2
-rw-r--r--spec/features/snippets/user_snippets_spec.rb8
-rw-r--r--spec/features/usage_stats_consent_spec.rb1
-rw-r--r--spec/features/users/active_sessions_spec.rb8
-rw-r--r--spec/features/users/login_spec.rb65
-rw-r--r--spec/features/users/show_spec.rb43
175 files changed, 2818 insertions, 1575 deletions
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb
index 5959fcd6306..5fdd0816006 100644
--- a/spec/features/abuse_report_spec.rb
+++ b/spec/features/abuse_report_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Abuse reports' do
sign_in(create(:user))
end
- it 'Report abuse' do
+ it 'report abuse' do
visit user_path(another_user)
click_link 'Report abuse'
diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb
index 845e186dd5b..192182adddc 100644
--- a/spec/features/admin/admin_abuse_reports_spec.rb
+++ b/spec/features/admin/admin_abuse_reports_spec.rb
@@ -7,7 +7,9 @@ RSpec.describe "Admin::AbuseReports", :js do
context 'as an admin' do
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
describe 'if a user has been reported for abuse' do
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index 48aaec6e6df..cd136af8d69 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -4,9 +4,11 @@ require 'spec_helper'
RSpec.describe 'Admin Appearance' do
let!(:appearance) { create(:appearance) }
+ let(:admin) { create(:admin) }
- it 'Create new appearance' do
- sign_in(create(:admin))
+ it 'create new appearance' do
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit admin_appearances_path
fill_in 'appearance_title', with: 'MyCompany'
@@ -25,8 +27,9 @@ RSpec.describe 'Admin Appearance' do
expect(page).to have_content 'Last edit'
end
- it 'Preview sign-in page appearance' do
- sign_in(create(:admin))
+ it 'preview sign-in page appearance' do
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit admin_appearances_path
click_link "Sign-in page"
@@ -34,8 +37,9 @@ RSpec.describe 'Admin Appearance' do
expect_custom_sign_in_appearance(appearance)
end
- it 'Preview new project page appearance' do
- sign_in(create(:admin))
+ it 'preview new project page appearance' do
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit admin_appearances_path
click_link "New project page"
@@ -45,7 +49,8 @@ RSpec.describe 'Admin Appearance' do
context 'Custom system header and footer' do
before do
- sign_in(create(:admin))
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
context 'when system header and footer messages are empty' do
@@ -75,14 +80,15 @@ RSpec.describe 'Admin Appearance' do
end
end
- it 'Custom sign-in page' do
+ it 'custom sign-in page' do
visit new_user_session_path
expect_custom_sign_in_appearance(appearance)
end
- it 'Custom new project page' do
- sign_in create(:user)
+ it 'custom new project page' do
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit new_project_path
expect_custom_new_project_appearance(appearance)
@@ -91,6 +97,7 @@ RSpec.describe 'Admin Appearance' do
context 'Profile page with custom profile image guidelines' do
before do
sign_in(create(:admin))
+ gitlab_enable_admin_mode_sign_in(admin)
visit admin_appearances_path
fill_in 'appearance_profile_image_guidelines', with: 'Custom profile image guidelines, please :smile:!'
click_button 'Update appearance settings'
@@ -104,8 +111,9 @@ RSpec.describe 'Admin Appearance' do
end
end
- it 'Appearance logo' do
- sign_in(create(:admin))
+ it 'appearance logo' do
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit admin_appearances_path
attach_file(:appearance_logo, logo_fixture)
@@ -116,8 +124,9 @@ RSpec.describe 'Admin Appearance' do
expect(page).not_to have_css(logo_selector)
end
- it 'Header logos' do
- sign_in(create(:admin))
+ it 'header logos' do
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit admin_appearances_path
attach_file(:appearance_header_logo, logo_fixture)
@@ -129,7 +138,8 @@ RSpec.describe 'Admin Appearance' do
end
it 'Favicon' do
- sign_in(create(:admin))
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit admin_appearances_path
attach_file(:appearance_favicon, logo_fixture)
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb
index 091ed0a3396..476dd4469bc 100644
--- a/spec/features/admin/admin_broadcast_messages_spec.rb
+++ b/spec/features/admin/admin_broadcast_messages_spec.rb
@@ -4,12 +4,14 @@ require 'spec_helper'
RSpec.describe 'Admin Broadcast Messages' do
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
create(:broadcast_message, :expired, message: 'Migration to new server')
visit admin_broadcast_messages_path
end
- it 'See broadcast messages list' do
+ it 'see broadcast messages list' do
expect(page).to have_content 'Migration to new server'
end
@@ -42,7 +44,7 @@ RSpec.describe 'Admin Broadcast Messages' do
expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST'
end
- it 'Edit an existing broadcast message' do
+ it 'edit an existing broadcast message' do
click_link 'Edit'
fill_in 'broadcast_message_message', with: 'Application update RIGHT NOW'
click_button 'Update broadcast message'
@@ -51,7 +53,7 @@ RSpec.describe 'Admin Broadcast Messages' do
expect(page).to have_content 'Application update RIGHT NOW'
end
- it 'Remove an existing broadcast message' do
+ it 'remove an existing broadcast message' do
click_link 'Remove'
expect(current_path).to eq admin_broadcast_messages_path
diff --git a/spec/features/admin/admin_browse_spam_logs_spec.rb b/spec/features/admin/admin_browse_spam_logs_spec.rb
index 65847876c11..471a7e8f0ab 100644
--- a/spec/features/admin/admin_browse_spam_logs_spec.rb
+++ b/spec/features/admin/admin_browse_spam_logs_spec.rb
@@ -6,10 +6,12 @@ RSpec.describe 'Admin browse spam logs' do
let!(:spam_log) { create(:spam_log, description: 'abcde ' * 20) }
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
- it 'Browse spam logs' do
+ it 'browse spam logs' do
visit admin_spam_logs_path
expect(page).to have_content('Spam Logs')
diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_builds_spec.rb
index 166fde0f37a..42827dd5b49 100644
--- a/spec/features/admin/admin_builds_spec.rb
+++ b/spec/features/admin/admin_builds_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe 'Admin Builds' do
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
describe 'GET /admin/builds' do
diff --git a/spec/features/admin/admin_cohorts_spec.rb b/spec/features/admin/admin_cohorts_spec.rb
index f91446ed222..982a9333275 100644
--- a/spec/features/admin/admin_cohorts_spec.rb
+++ b/spec/features/admin/admin_cohorts_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe 'Cohorts page' do
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
context 'with usage ping enabled' do
diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb
index 2039a6ff1ee..c326d0fd741 100644
--- a/spec/features/admin/admin_deploy_keys_spec.rb
+++ b/spec/features/admin/admin_deploy_keys_spec.rb
@@ -7,7 +7,9 @@ RSpec.describe 'admin deploy keys' do
let!(:another_deploy_key) { create(:another_deploy_key, public: true) }
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
it 'show all public deploy keys' do
diff --git a/spec/features/admin/admin_dev_ops_report_spec.rb b/spec/features/admin/admin_dev_ops_report_spec.rb
index 3b2c9d75870..a05fa0640d8 100644
--- a/spec/features/admin/admin_dev_ops_report_spec.rb
+++ b/spec/features/admin/admin_dev_ops_report_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe 'DevOps Report page', :js do
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
context 'with devops_adoption feature flag disabled' do
diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
index d7feb21a8b3..f7f0592a315 100644
--- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb
+++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe 'Admin disables Git access protocol', :js do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
context 'with HTTP disabled' do
diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb
index 216c8ae36c7..1f34c4ed17c 100644
--- a/spec/features/admin/admin_disables_two_factor_spec.rb
+++ b/spec/features/admin/admin_disables_two_factor_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe 'Admin disables 2FA for a user' do
it 'successfully', :js do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
user = create(:user, :two_factor)
edit_user(user)
@@ -19,7 +21,9 @@ RSpec.describe 'Admin disables 2FA for a user' do
end
it 'for a user without 2FA enabled' do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
user = create(:user)
edit_user(user)
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 96709cf8a12..0e350a5e12e 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -7,12 +7,14 @@ RSpec.describe 'Admin Groups' do
include Spec::Support::Helpers::Features::MembersHelpers
let(:internal) { Gitlab::VisibilityLevel::INTERNAL }
- let(:user) { create :user }
- let!(:group) { create :group }
- let!(:current_user) { create(:admin) }
+
+ let_it_be(:user) { create :user }
+ let_it_be(:group) { create :group }
+ let_it_be(:current_user) { create(:admin) }
before do
sign_in(current_user)
+ gitlab_enable_admin_mode_sign_in(current_user)
stub_application_setting(default_group_visibility: internal)
end
@@ -25,6 +27,17 @@ RSpec.describe 'Admin Groups' do
end
describe 'create a group' do
+ describe 'with expected fields' do
+ it 'renders from as expected', :aggregate_failures do
+ visit new_admin_group_path
+
+ expect(page).to have_field('name')
+ expect(page).to have_field('group_path')
+ expect(page).to have_field('group_visibility_level_0')
+ expect(page).to have_field('description')
+ end
+ end
+
it 'creates new group' do
visit admin_groups_path
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
index dfc7f5f6f84..0f6cba6c105 100644
--- a/spec/features/admin/admin_health_check_spec.rb
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe "Admin Health Check", :feature do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
describe '#show' do
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index f4a70621cee..3f63bf9a15c 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -8,7 +8,9 @@ RSpec.describe 'Admin::HookLogs' do
let(:hook_log) { create(:web_hook_log, web_hook: system_hook, internal_error_message: 'some error') }
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
it 'show list of hook logs' do
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 1c14d65a1cd..3fed402267c 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe 'Admin::Hooks' do
before do
sign_in(user)
+ gitlab_enable_admin_mode_sign_in(user)
end
describe 'GET /admin/hooks' do
diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb
index 35638e0829b..815a73b1450 100644
--- a/spec/features/admin/admin_labels_spec.rb
+++ b/spec/features/admin/admin_labels_spec.rb
@@ -7,7 +7,9 @@ RSpec.describe 'admin issues labels' do
let!(:feature_label) { Label.create(title: 'feature', template: true) }
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
describe 'list' do
diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb
index 7a9a6f2ccb8..e54837ede11 100644
--- a/spec/features/admin/admin_manage_applications_spec.rb
+++ b/spec/features/admin/admin_manage_applications_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe 'admin manage applications' do
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
it 'creates new oauth application' do
diff --git a/spec/features/admin/admin_mode/login_spec.rb b/spec/features/admin/admin_mode/login_spec.rb
index 7cbba9ec674..f1dee075925 100644
--- a/spec/features/admin/admin_mode/login_spec.rb
+++ b/spec/features/admin/admin_mode/login_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin Mode Login', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin Mode Login' do
include TermsHelper
include UserLoginHelper
include LdapHelpers
diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb
index b4d49fe760f..b7fa59bbfb7 100644
--- a/spec/features/admin/admin_mode/logout_spec.rb
+++ b/spec/features/admin/admin_mode/logout_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin Mode Logout', :js, :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin Mode Logout', :js do
include TermsHelper
include UserLoginHelper
diff --git a/spec/features/admin/admin_mode/workers_spec.rb b/spec/features/admin/admin_mode/workers_spec.rb
index d037f5555dc..fbbcf19063b 100644
--- a/spec/features/admin/admin_mode/workers_spec.rb
+++ b/spec/features/admin/admin_mode/workers_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
# Test an operation that triggers background jobs requiring administrative rights
-RSpec.describe 'Admin mode for workers', :do_not_mock_admin_mode, :request_store, :clean_gitlab_redis_shared_state do
+RSpec.describe 'Admin mode for workers', :request_store do
let(:user) { create(:user) }
let(:user_to_delete) { create(:user) }
diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb
index 3b4edbc1a07..8169b3a20db 100644
--- a/spec/features/admin/admin_mode_spec.rb
+++ b/spec/features/admin/admin_mode_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin mode', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin mode' do
include MobileHelpers
include StubENV
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 522da760062..ff4e592234b 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe "Admin::Projects" do
before do
sign_in(current_user)
+ gitlab_enable_admin_mode_sign_in(current_user)
end
describe "GET /admin/projects" do
diff --git a/spec/features/admin/admin_requests_profiles_spec.rb b/spec/features/admin/admin_requests_profiles_spec.rb
index c649fdd8e19..e92528d431d 100644
--- a/spec/features/admin/admin_requests_profiles_spec.rb
+++ b/spec/features/admin/admin_requests_profiles_spec.rb
@@ -7,7 +7,9 @@ RSpec.describe 'Admin::RequestsProfilesController' do
before do
stub_const('Gitlab::RequestProfiler::PROFILES_DIR', tmpdir)
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
after do
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 0e20ccf6bec..e16cde3fa1c 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -9,7 +9,9 @@ RSpec.describe "Admin Runners" do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
describe "Runners page" do
@@ -282,6 +284,12 @@ RSpec.describe "Admin Runners" do
visit admin_runner_path(runner)
end
+ describe 'runner page breadcrumbs' do
+ it 'contains the current runner’s short sha' do
+ expect(page.find('h2')).to have_content(runner.short_sha)
+ end
+ end
+
describe 'projects' do
it 'contains project names' do
expect(page).to have_content(@project1.full_name)
diff --git a/spec/features/admin/admin_sees_project_statistics_spec.rb b/spec/features/admin/admin_sees_project_statistics_spec.rb
index d94889b825a..be781730924 100644
--- a/spec/features/admin/admin_sees_project_statistics_spec.rb
+++ b/spec/features/admin/admin_sees_project_statistics_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe "Admin > Admin sees project statistics" do
before do
sign_in(current_user)
+ gitlab_enable_admin_mode_sign_in(current_user)
visit admin_project_path(project)
end
@@ -15,7 +16,7 @@ RSpec.describe "Admin > Admin sees project statistics" do
let(:project) { create(:project, :repository) }
it "shows project statistics" do
- expect(page).to have_content("Storage: 0 Bytes (Repository: 0 Bytes / Wikis: 0 Bytes / Build Artifacts: 0 Bytes / LFS: 0 Bytes / Snippets: 0 Bytes)")
+ expect(page).to have_content("Storage: 0 Bytes (Repository: 0 Bytes / Wikis: 0 Bytes / Build Artifacts: 0 Bytes / LFS: 0 Bytes / Snippets: 0 Bytes / Packages: 0 Bytes / Uploads: 0 Bytes)")
end
end
diff --git a/spec/features/admin/admin_sees_projects_statistics_spec.rb b/spec/features/admin/admin_sees_projects_statistics_spec.rb
index 786fa98255c..2e96814d1e9 100644
--- a/spec/features/admin/admin_sees_projects_statistics_spec.rb
+++ b/spec/features/admin/admin_sees_projects_statistics_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe "Admin > Admin sees projects statistics" do
create(:project, :repository) { |project| project.statistics.destroy }
sign_in(current_user)
+ gitlab_enable_admin_mode_sign_in(current_user)
visit admin_projects_path
end
diff --git a/spec/features/admin/admin_serverless_domains_spec.rb b/spec/features/admin/admin_serverless_domains_spec.rb
index 256887f425f..0312e82e1ba 100644
--- a/spec/features/admin/admin_serverless_domains_spec.rb
+++ b/spec/features/admin/admin_serverless_domains_spec.rb
@@ -7,10 +7,12 @@ RSpec.describe 'Admin Serverless Domains', :js do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
- it 'Add domain with certificate' do
+ it 'add domain with certificate' do
visit admin_serverless_domains_path
fill_in 'pages_domain[domain]', with: 'foo.com'
@@ -30,7 +32,7 @@ RSpec.describe 'Admin Serverless Domains', :js do
expect(page).to have_content '/CN=test-certificate'
end
- it 'Update domain certificate' do
+ it 'update domain certificate' do
visit admin_serverless_domains_path
fill_in 'pages_domain[domain]', with: 'foo.com'
@@ -60,7 +62,7 @@ RSpec.describe 'Admin Serverless Domains', :js do
context 'when domain exists' do
let!(:domain) { create(:pages_domain, :instance_serverless) }
- it 'Displays a modal when attempting to delete a domain' do
+ it 'displays a modal when attempting to delete a domain' do
visit admin_serverless_domains_path
click_button 'Delete domain'
@@ -71,7 +73,7 @@ RSpec.describe 'Admin Serverless Domains', :js do
end
end
- it 'Displays a modal with disabled button if unable to delete a domain' do
+ it 'displays a modal with disabled button if unable to delete a domain' do
create(:serverless_domain_cluster, pages_domain: domain)
visit admin_serverless_domains_path
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 8929abc7edc..06d31b544ea 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin updates settings' do
include StubENV
include TermsHelper
include UsageDataHelpers
@@ -24,7 +24,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
visit general_admin_application_settings_path
end
- it 'Change visibility settings' do
+ it 'change visibility settings' do
page.within('.as-visibility-access') do
choose "application_setting_default_project_visibility_20"
click_button 'Save changes'
@@ -33,7 +33,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content "Application settings saved successfully"
end
- it 'Uncheck all restricted visibility levels' do
+ it 'uncheck all restricted visibility levels' do
page.within('.as-visibility-access') do
find('#application_setting_visibility_level_0').set(false)
find('#application_setting_visibility_level_10').set(false)
@@ -47,7 +47,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(find('#application_setting_visibility_level_20')).not_to be_checked
end
- it 'Modify import sources' do
+ it 'modify import sources' do
expect(current_settings.import_sources).not_to be_empty
page.within('.as-visibility-access') do
@@ -70,7 +70,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(current_settings.import_sources).to eq(['git'])
end
- it 'Change Visibility and Access Controls' do
+ it 'change Visibility and Access Controls' do
page.within('.as-visibility-access') do
uncheck 'Project export enabled'
click_button 'Save changes'
@@ -80,7 +80,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content "Application settings saved successfully"
end
- it 'Change Keys settings' do
+ it 'change Keys settings' do
page.within('.as-visibility-access') do
select 'Are forbidden', from: 'RSA SSH keys'
select 'Are allowed', from: 'DSA SSH keys'
@@ -98,7 +98,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(find_field('ED25519 SSH keys').value).to eq(forbidden)
end
- it 'Change Account and Limit Settings' do
+ it 'change Account and Limit Settings' do
page.within('.as-account-limit') do
uncheck 'Gravatar enabled'
click_button 'Save changes'
@@ -108,7 +108,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content "Application settings saved successfully"
end
- it 'Change Maximum import size' do
+ it 'change Maximum import size' do
page.within('.as-account-limit') do
fill_in 'Maximum import size (MB)', with: 15
click_button 'Save changes'
@@ -118,7 +118,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content "Application settings saved successfully"
end
- it 'Change New users set to external', :js do
+ it 'change New users set to external', :js do
user_internal_regex = find('#application_setting_user_default_internal_regex', visible: :all)
expect(user_internal_regex).to be_readonly
@@ -144,7 +144,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
end
end
- it 'Change Sign-in restrictions' do
+ it 'change Sign-in restrictions' do
page.within('.as-signin') do
fill_in 'Home page URL', with: 'https://about.gitlab.com/'
click_button 'Save changes'
@@ -154,7 +154,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content "Application settings saved successfully"
end
- it 'Terms of Service' do
+ it 'terms of Service' do
# Already have the admin accept terms, so they don't need to accept in this spec.
_existing_terms = create(:term)
accept_terms(admin)
@@ -170,7 +170,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content 'Application settings saved successfully'
end
- it 'Modify oauth providers' do
+ it 'modify oauth providers' do
expect(current_settings.disabled_oauth_sign_in_sources).to be_empty
page.within('.as-signin') do
@@ -190,7 +190,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(current_settings.disabled_oauth_sign_in_sources).not_to include('google_oauth2')
end
- it 'Oauth providers do not raise validation errors when saving unrelated changes' do
+ it 'oauth providers do not raise validation errors when saving unrelated changes' do
expect(current_settings.disabled_oauth_sign_in_sources).to be_empty
page.within('.as-signin') do
@@ -213,7 +213,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(current_settings.disabled_oauth_sign_in_sources).to include('google_oauth2')
end
- it 'Configure web terminal' do
+ it 'configure web terminal' do
page.within('.as-terminal') do
fill_in 'Max session time', with: 15
click_button 'Save changes'
@@ -255,7 +255,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
visit general_admin_application_settings_path
end
- it 'Enable hiding third party offers' do
+ it 'enable hiding third party offers' do
page.within('.as-third-party-offers') do
check 'Do not display offers from third parties within GitLab'
click_button 'Save changes'
@@ -265,7 +265,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(current_settings.hide_third_party_offers).to be true
end
- it 'Change Slack Notifications Service template settings', :js do
+ it 'change Slack Notifications Service template settings', :js do
first(:link, 'Service Templates').click
click_link 'Slack notifications'
fill_in 'Webhook', with: 'http://localhost'
@@ -315,7 +315,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
end
context 'CI/CD page' do
- it 'Change CI/CD settings' do
+ it 'change CI/CD settings' do
visit ci_cd_admin_application_settings_path
page.within('.as-ci-cd') do
@@ -380,7 +380,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
end
context 'Repository page' do
- it 'Change Repository storage settings' do
+ it 'change Repository storage settings' do
visit repository_admin_application_settings_path
page.within('.as-repository-storage') do
@@ -393,7 +393,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
end
context 'Reporting page' do
- it 'Change Spam settings' do
+ it 'change Spam settings' do
visit reporting_admin_application_settings_path
page.within('.as-spam') do
@@ -421,7 +421,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
visit metrics_and_profiling_admin_application_settings_path
end
- it 'Change Prometheus settings' do
+ it 'change Prometheus settings' do
page.within('.as-prometheus') do
check 'Enable Prometheus Metrics'
click_button 'Save changes'
@@ -431,7 +431,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content "Application settings saved successfully"
end
- it 'Change Performance bar settings' do
+ it 'change Performance bar settings' do
group = create(:group)
page.within('.as-performance-bar') do
@@ -474,7 +474,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
end
context 'Network page' do
- it 'Changes Outbound requests settings' do
+ it 'changes Outbound requests settings' do
visit network_admin_application_settings_path
page.within('.as-outbound') do
@@ -492,7 +492,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(current_settings.dns_rebinding_protection_enabled).to be false
end
- it 'Changes Issues rate limits settings' do
+ it 'changes Issues rate limits settings' do
visit network_admin_application_settings_path
page.within('.as-issue-limits') do
@@ -510,7 +510,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
visit preferences_admin_application_settings_path
end
- it 'Change Help page' do
+ it 'change Help page' do
stub_feature_flags(help_page_documentation_redirect: true)
new_support_url = 'http://example.com/help'
@@ -531,7 +531,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content "Application settings saved successfully"
end
- it 'Change Pages settings' do
+ it 'change Pages settings' do
page.within('.as-pages') do
fill_in 'Maximum size of pages (MB)', with: 15
check 'Require users to prove ownership of custom domains'
@@ -543,7 +543,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
expect(page).to have_content "Application settings saved successfully"
end
- it 'Change Real-time features settings' do
+ it 'change Real-time features settings' do
page.within('.as-realtime') do
fill_in 'Polling interval multiplier', with: 5.0
click_button 'Save changes'
@@ -564,7 +564,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
.to have_content "The form contains the following error: Polling interval multiplier must be greater than or equal to 0"
end
- it "Change Pages Let's Encrypt settings" do
+ it "change Pages Let's Encrypt settings" do
visit preferences_admin_application_settings_path
page.within('.as-pages') do
fill_in 'Email', with: 'my@test.example.com'
@@ -578,7 +578,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
end
context 'Nav bar' do
- it 'Shows default help links in nav' do
+ it 'shows default help links in nav' do
default_support_url = 'https://about.gitlab.com/getting-help/'
visit root_dashboard_path
@@ -591,7 +591,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
end
end
- it 'Shows custom support url in nav when set' do
+ it 'shows custom support url in nav when set' do
new_support_url = 'http://example.com/help'
stub_application_setting(help_page_support_url: new_support_url)
diff --git a/spec/features/admin/admin_system_info_spec.rb b/spec/features/admin/admin_system_info_spec.rb
index 6a0448fd890..2225f25aa1e 100644
--- a/spec/features/admin/admin_system_info_spec.rb
+++ b/spec/features/admin/admin_system_info_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe 'Admin System Info' do
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
describe 'GET /admin/system_info' do
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index ec3dd322f97..cae190e76b0 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
before do
sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
describe "token creation" do
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index 0fb5124f673..0e448446085 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Admin uses repository checks', :request_store, :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin uses repository checks', :request_store do
include StubENV
let(:admin) { create(:admin) }
diff --git a/spec/features/admin/clusters/applications_spec.rb b/spec/features/admin/clusters/applications_spec.rb
index 3bcadfdbfc1..e083e4fee4c 100644
--- a/spec/features/admin/clusters/applications_spec.rb
+++ b/spec/features/admin/clusters/applications_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe 'Instance-level Cluster Applications', :js do
before do
sign_in(user)
+ gitlab_enable_admin_mode_sign_in(user)
end
describe 'Installing applications' do
diff --git a/spec/features/admin/clusters/eks_spec.rb b/spec/features/admin/clusters/eks_spec.rb
index ad7122bf182..a1bac720349 100644
--- a/spec/features/admin/clusters/eks_spec.rb
+++ b/spec/features/admin/clusters/eks_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe 'Instance-level AWS EKS Cluster', :js do
before do
sign_in(user)
+ gitlab_enable_admin_mode_sign_in(user)
end
context 'when user does not have a cluster and visits group clusters page' do
diff --git a/spec/features/admin/dashboard_spec.rb b/spec/features/admin/dashboard_spec.rb
index acb8fb54e11..c040811ada1 100644
--- a/spec/features/admin/dashboard_spec.rb
+++ b/spec/features/admin/dashboard_spec.rb
@@ -6,7 +6,9 @@ RSpec.describe 'admin visits dashboard' do
include ProjectForksHelper
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
context 'counting forks', :js do
diff --git a/spec/features/admin/services/admin_activates_prometheus_spec.rb b/spec/features/admin/services/admin_activates_prometheus_spec.rb
index 199eae59afc..a225de365c8 100644
--- a/spec/features/admin/services/admin_activates_prometheus_spec.rb
+++ b/spec/features/admin/services/admin_activates_prometheus_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe 'Admin activates Prometheus', :js do
before do
sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit(admin_application_settings_services_path)
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 a37e57304aa..563bca8b32f 100644
--- a/spec/features/admin/services/admin_visits_service_templates_spec.rb
+++ b/spec/features/admin/services/admin_visits_service_templates_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe 'Admin visits service templates' do
before do
sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit(admin_application_settings_services_path)
end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
new file mode 100644
index 00000000000..e7dd50ed514
--- /dev/null
+++ b/spec/features/admin/users/user_spec.rb
@@ -0,0 +1,372 @@
+# frozen_string_literal: true
+
+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) }
+
+ 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
+
+ expect(page).to have_content(user.email)
+ expect(page).to have_content(user.name)
+ expect(page).to have_content("ID: #{user.id}")
+ expect(page).to have_content("Namespace ID: #{user.namespace_id}")
+ expect(page).to have_button('Deactivate user')
+ expect(page).to have_button('Block user')
+ expect(page).to have_button('Delete user')
+ 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)
+
+ find('button', text: 'Block user').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Block user')
+ expect(page).to have_content('You can always unblock their account, their data will remain intact.')
+
+ find('.modal-footer button', text: 'Block').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Successfully blocked')
+ expect(page).to have_content('This user is blocked')
+
+ find('button', text: 'Unblock user').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Unblock user')
+ expect(page).to have_content('You can always block their account again if needed.')
+
+ find('.modal-footer button', text: 'Unblock').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Successfully unblocked')
+ expect(page).to have_content('Block this user')
+ end
+ end
+
+ context 'when deactivating/re-activating the user' do
+ it 'shows confirmation and allows deactivating/re-activating', :js do
+ visit admin_user_path(user)
+
+ find('button', text: 'Deactivate user').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Deactivate user')
+ expect(page).to have_content('You can always re-activate their account, their data will remain intact.')
+
+ find('.modal-footer button', text: 'Deactivate').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Successfully deactivated')
+ expect(page).to have_content('Reactivate this user')
+
+ find('button', text: 'Activate user').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Activate user')
+ expect(page).to have_content('You can always deactivate their account again if needed.')
+
+ find('.modal-footer button', text: 'Activate').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Successfully activated')
+ expect(page).to have_content('Deactivate this user')
+ end
+ end
+
+ describe 'Impersonation' do
+ let_it_be(:another_user) { create(:user) }
+
+ context 'before impersonating' do
+ subject { visit admin_user_path(user_to_visit) }
+
+ let(:user_to_visit) { another_user }
+
+ context 'for other users' do
+ it 'shows impersonate button for other users' do
+ subject
+
+ expect(page).to have_content('Impersonate')
+ end
+ end
+
+ context 'for admin itself' do
+ let(:user_to_visit) { current_user }
+
+ it 'does not show impersonate button for admin itself' do
+ subject
+
+ expect(page).not_to have_content('Impersonate')
+ end
+ end
+
+ context 'for blocked user' do
+ before do
+ another_user.block
+ end
+
+ it 'does not show impersonate button for blocked user' do
+ subject
+
+ expect(page).not_to have_content('Impersonate')
+ end
+ end
+
+ context 'when impersonation is disabled' do
+ before do
+ stub_config_setting(impersonation_enabled: false)
+ end
+
+ it 'does not show impersonate button' do
+ subject
+
+ expect(page).not_to have_content('Impersonate')
+ end
+ end
+ end
+
+ context 'when impersonating' do
+ subject { click_link 'Impersonate' }
+
+ before do
+ visit admin_user_path(another_user)
+ end
+
+ it 'logs in as the user when impersonate is clicked' do
+ subject
+
+ expect(page.find(:css, '.header-user .profile-link')['data-user']).to eql(another_user.username)
+ end
+
+ it 'sees impersonation log out icon' do
+ subject
+
+ icon = first('[data-testid="incognito-icon"]')
+ expect(icon).not_to be nil
+ end
+
+ context 'a user with an expired password' do
+ before do
+ another_user.update!(password_expires_at: Time.now - 5.minutes)
+ end
+
+ it 'does not redirect to password change page' do
+ subject
+
+ expect(current_path).to eq('/')
+ end
+ end
+ end
+
+ context 'ending impersonation' do
+ subject { find(:css, 'li.impersonation a').click }
+
+ before do
+ visit admin_user_path(another_user)
+ click_link 'Impersonate'
+ end
+
+ it 'logs out of impersonated user back to original user' do
+ subject
+
+ expect(page.find(:css, '.header-user .profile-link')['data-user']).to eq(current_user.username)
+ end
+
+ it 'is redirected back to the impersonated users page in the admin after stopping' do
+ subject
+
+ expect(current_path).to eq("/admin/users/#{another_user.username}")
+ end
+
+ context 'a user with an expired password' do
+ before do
+ another_user.update!(password_expires_at: Time.now - 5.minutes)
+ end
+
+ it 'is redirected back to the impersonated users page in the admin after stopping' do
+ subject
+
+ expect(current_path).to eq("/admin/users/#{another_user.username}")
+ end
+ end
+ end
+ end
+
+ describe 'Two-factor Authentication status' do
+ it 'shows when enabled' do
+ user.update!(otp_required_for_login: true)
+
+ visit admin_user_path(user)
+
+ expect_two_factor_status('Enabled')
+ end
+
+ it 'shows when disabled' do
+ visit admin_user_path(user)
+
+ expect_two_factor_status('Disabled')
+ end
+
+ def expect_two_factor_status(status)
+ page.within('.two-factor-status') do
+ expect(page).to have_content(status)
+ end
+ end
+ end
+
+ describe 'Email verification status' do
+ let!(:secondary_email) do
+ create :email, email: 'secondary@example.com', user: user
+ end
+
+ it 'displays the correct status for an unverified email address', :aggregate_failures do
+ user.update!(confirmed_at: nil, unconfirmed_email: user.email)
+ visit admin_user_path(user)
+
+ expect(page).to have_content("#{user.email} Unverified")
+ expect(page).to have_content("#{secondary_email.email} Unverified")
+ end
+
+ it 'displays the correct status for a verified email address' do
+ visit admin_user_path(user)
+ expect(page).to have_content("#{user.email} Verified")
+
+ secondary_email.confirm
+ expect(secondary_email.confirmed?).to be_truthy
+
+ visit admin_user_path(user)
+ 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
+
+ expect(page).to have_content 'Account'
+ expect(page).to have_content 'Personal projects limit'
+ end
+ end
+
+ describe 'remove users secondary email', :js do
+ let!(: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}")
+
+ accept_confirm { find("#remove_email_#{secondary_email.id}").click }
+
+ expect(page).not_to have_content(secondary_email.email)
+ 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')
+
+ visit admin_users_path
+
+ click_link user.name
+ click_link 'SSH keys'
+
+ expect(page).to have_content(key1.title)
+ expect(page).to have_content(key2.title)
+
+ click_link key2.title
+
+ expect(page).to have_content(key2.title)
+ expect(page).to have_content(key2.key)
+
+ click_button 'Delete'
+
+ page.within('.modal') do
+ page.click_button('Delete')
+ end
+
+ expect(page).not_to have_content(key2.title)
+ end
+ end
+
+ describe 'show user identities' do
+ it 'shows user identities', :aggregate_failures do
+ visit admin_user_identities_path(user)
+
+ expect(page).to have_content(user.name)
+ expect(page).to have_content('twitter')
+ end
+ end
+
+ 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
+
+ describe 'remove user with identities' do
+ it 'removes user with twitter identity', :aggregate_failures do
+ visit admin_user_identities_path(user)
+
+ click_link 'Delete'
+
+ expect(page).to have_content(user.name)
+ expect(page).not_to have_content('twitter')
+ end
+ end
+end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/users/users_spec.rb
index 97a30143a59..9482b4f8603 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/users/users_spec.rb
@@ -2,21 +2,20 @@
require 'spec_helper'
-RSpec.describe "Admin::Users" do
+RSpec.describe 'Admin::Users' do
include Spec::Support::Helpers::Features::ResponsiveTableHelpers
- let!(:user) do
- create(:omniauth_user, provider: 'twitter', extern_uid: '123456')
- end
-
- let!(:current_user) { create(:admin, last_activity_on: 5.days.ago) }
+ 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) }
before do
sign_in(current_user)
+ gitlab_enable_admin_mode_sign_in(current_user)
end
- describe "GET /admin/users" do
+ describe 'GET /admin/users' do
before do
+ stub_feature_flags(vue_admin_users: false)
visit admin_users_path
end
@@ -27,8 +26,8 @@ RSpec.describe "Admin::Users" do
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(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')
@@ -38,7 +37,7 @@ RSpec.describe "Admin::Users" do
expect(page).to have_button('Delete user and contributions')
end
- describe "view extra user information" do
+ 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__')
@@ -86,7 +85,7 @@ RSpec.describe "Admin::Users" do
end
describe 'search and sort' do
- before 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')
@@ -205,15 +204,11 @@ RSpec.describe "Admin::Users" do
end
end
- context 'when blocking a user' do
- it 'shows confirmation and allows blocking', :js do
+ 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("[data-testid='user-action-button-#{user.id}']").click
-
- within find("[data-testid='user-action-dropdown-#{user.id}']") do
- find('li button', text: 'Block').click
- end
+ click_action_in_user_dropdown(user.id, 'Block')
wait_for_requests
@@ -228,26 +223,92 @@ RSpec.describe "Admin::Users" do
expect(page).to have_content('Successfully blocked')
expect(page).not_to have_content(user.email)
+
+ click_link 'Blocked'
+
+ wait_for_requests
+
+ expect(page).to have_content(user.email)
+
+ click_action_in_user_dropdown(user.id, 'Unblock')
+
+ expect(page).to have_content('Unblock user')
+ expect(page).to have_content('You can always block their account again if needed.')
+
+ find('.modal-footer button', text: 'Unblock').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Successfully unblocked')
+ expect(page).not_to have_content(user.email)
+ end
+ end
+
+ 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)
+
+ click_action_in_user_dropdown(user.id, 'Deactivate')
+
+ 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')
+
+ find('.modal-footer button', text: 'Deactivate').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Successfully deactivated')
+ expect(page).not_to have_content(user.email)
+
+ click_link 'Deactivated'
+
+ wait_for_requests
+
+ expect(page).to have_content(user.email)
+
+ click_action_in_user_dropdown(user.id, 'Activate')
+
+ expect(page).to have_content('Activate user')
+ expect(page).to have_content('You can always deactivate their account again if needed.')
+
+ find('.modal-footer button', text: 'Activate').click
+
+ wait_for_requests
+
+ expect(page).to have_content('Successfully activated')
+ expect(page).not_to have_content(user.email)
end
end
+
+ def click_action_in_user_dropdown(user_id, action)
+ find("[data-testid='user-action-button-#{user_id}']").click
+
+ within find("[data-testid='user-action-dropdown-#{user_id}']") do
+ find('li button', text: action).click
+ end
+
+ wait_for_requests
+ end
end
- describe "GET /admin/users/new" do
+ describe 'GET /admin/users/new' do
let(:user_username) { 'bang' }
before do
visit new_admin_user_path
- fill_in "user_name", with: "Big Bang"
- fill_in "user_username", with: user_username
- fill_in "user_email", with: "bigbang@mail.com"
+ fill_in 'user_name', with: 'Big Bang'
+ fill_in 'user_username', with: user_username
+ fill_in 'user_email', with: 'bigbang@mail.com'
end
- it "creates new user" do
- expect { click_button "Create user" }.to change {User.count}.by(1)
+ it 'creates new user' do
+ expect { click_button 'Create user' }.to change {User.count}.by(1)
end
- it "applies defaults to user" do
- click_button "Create user"
+ it 'applies defaults to user' do
+ click_button 'Create user'
user = User.find_by(username: 'bang')
expect(user.projects_limit)
.to eq(Gitlab.config.gitlab.default_projects_limit)
@@ -255,24 +316,24 @@ RSpec.describe "Admin::Users" do
.to eq(Gitlab.config.gitlab.default_can_create_group)
end
- it "creates user with valid data" do
- click_button "Create user"
+ it 'creates user with valid data' do
+ click_button 'Create user'
user = User.find_by(username: 'bang')
expect(user.name).to eq('Big Bang')
expect(user.email).to eq('bigbang@mail.com')
end
- it "calls send mail" do
+ it 'calls send mail' do
expect_next_instance_of(NotificationService) do |instance|
expect(instance).to receive(:new_user)
end
- click_button "Create user"
+ click_button 'Create user'
end
- it "sends valid email to user with email & password" do
+ it 'sends valid email to user with email & password' do
perform_enqueued_jobs do
- click_button "Create user"
+ click_button 'Create user'
end
user = User.find_by(username: 'bang')
@@ -286,7 +347,7 @@ RSpec.describe "Admin::Users" do
let(: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)
+ expect { click_button 'Create user' }.to change {User.count}.by(0)
expect(page).to have_content('The form contains the following error')
expect(page).to have_content('Username can contain only letters, digits')
@@ -356,252 +417,34 @@ RSpec.describe "Admin::Users" do
end
end
- describe "GET /admin/users/:id" do
- it "has user info" do
- visit admin_users_path
- click_link user.name
-
- expect(page).to have_content(user.email)
- expect(page).to have_content(user.name)
- expect(page).to have_content("ID: #{user.id}")
- expect(page).to have_content("Namespace ID: #{user.namespace_id}")
- expect(page).to have_button('Deactivate user')
- expect(page).to have_button('Block user')
- expect(page).to have_button('Delete user')
- expect(page).to have_button('Delete user and contributions')
- end
-
- context 'user pending approval' do
- it 'shows user info' 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_button('Block user')
- expect(page).to have_button('Delete user')
- expect(page).to have_button('Delete user and contributions')
- end
- end
-
- context 'when blocking the user' do
- it 'shows confirmation and allows blocking', :js do
- visit admin_user_path(user)
-
- find('button', text: 'Block user').click
-
- wait_for_requests
-
- expect(page).to have_content('Block user')
- expect(page).to have_content('You can always unblock their account, their data will remain intact.')
-
- find('.modal-footer button', text: 'Block').click
-
- wait_for_requests
-
- expect(page).to have_content('Successfully blocked')
- expect(page).to have_content('This user is blocked')
- end
- end
-
- describe 'Impersonation' do
- let(:another_user) { create(:user) }
-
- context 'before impersonating' do
- subject { visit admin_user_path(user_to_visit) }
-
- let(:user_to_visit) { another_user }
-
- context 'for other users' do
- it 'shows impersonate button for other users' do
- subject
-
- expect(page).to have_content('Impersonate')
- end
- end
-
- context 'for admin itself' do
- let(:user_to_visit) { current_user }
-
- it 'does not show impersonate button for admin itself' do
- subject
-
- expect(page).not_to have_content('Impersonate')
- end
- end
-
- context 'for blocked user' do
- before do
- another_user.block
- end
-
- it 'does not show impersonate button for blocked user' do
- subject
-
- expect(page).not_to have_content('Impersonate')
- end
- end
-
- context 'when impersonation is disabled' do
- before do
- stub_config_setting(impersonation_enabled: false)
- end
-
- it 'does not show impersonate button' do
- subject
-
- expect(page).not_to have_content('Impersonate')
- end
- end
- end
-
- context 'when impersonating' do
- subject { click_link 'Impersonate' }
-
- before do
- visit admin_user_path(another_user)
- end
-
- it 'logs in as the user when impersonate is clicked' do
- subject
-
- expect(page.find(:css, '.header-user .profile-link')['data-user']).to eql(another_user.username)
- end
-
- it 'sees impersonation log out icon' do
- subject
-
- icon = first('[data-testid="incognito-icon"]')
- expect(icon).not_to be nil
- end
-
- context 'a user with an expired password' do
- before do
- another_user.update(password_expires_at: Time.now - 5.minutes)
- end
-
- it 'does not redirect to password change page' do
- subject
-
- expect(current_path).to eq('/')
- end
- end
- end
-
- context 'ending impersonation' do
- subject { find(:css, 'li.impersonation a').click }
-
- before do
- visit admin_user_path(another_user)
- click_link 'Impersonate'
- end
-
- it 'logs out of impersonated user back to original user' do
- subject
-
- expect(page.find(:css, '.header-user .profile-link')['data-user']).to eq(current_user.username)
- end
-
- it 'is redirected back to the impersonated users page in the admin after stopping' do
- subject
-
- expect(current_path).to eq("/admin/users/#{another_user.username}")
- end
-
- context 'a user with an expired password' do
- before do
- another_user.update(password_expires_at: Time.now - 5.minutes)
- end
-
- it 'is redirected back to the impersonated users page in the admin after stopping' do
- subject
-
- expect(current_path).to eq("/admin/users/#{another_user.username}")
- end
- end
- end
- end
-
- describe 'Two-factor Authentication status' do
- it 'shows when enabled' do
- user.update_attribute(:otp_required_for_login, true)
-
- visit admin_user_path(user)
-
- expect_two_factor_status('Enabled')
- end
-
- it 'shows when disabled' do
- visit admin_user_path(user)
-
- expect_two_factor_status('Disabled')
- end
-
- def expect_two_factor_status(status)
- page.within('.two-factor-status') do
- expect(page).to have_content(status)
- end
- end
- end
-
- describe 'Email verification status' do
- let!(:secondary_email) do
- create :email, email: 'secondary@example.com', user: user
- end
-
- it 'displays the correct status for an unverified email address' do
- user.update(confirmed_at: nil, unconfirmed_email: user.email)
- visit admin_user_path(user)
-
- expect(page).to have_content("#{user.email} Unverified")
-
- expect(page).to have_content("#{secondary_email.email} Unverified")
- end
-
- it 'displays the correct status for a verified email address' do
- visit admin_user_path(user)
- expect(page).to have_content("#{user.email} Verified")
-
- secondary_email.confirm
- expect(secondary_email.confirmed?).to be_truthy
-
- visit admin_user_path(user)
- expect(page).to have_content("#{secondary_email.email} Verified")
- end
- end
- end
-
- describe "GET /admin/users/:id/edit" do
+ 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
+ it 'has user edit page' do
expect(page).to have_content('Name')
expect(page).to have_content('Password')
end
- describe "Update user" do
+ 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"
+ 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
+ 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
+ it 'changes user entry' do
user.reload
expect(user.name).to eq('Big Bang')
expect(user.admin?).to be_truthy
@@ -623,9 +466,9 @@ RSpec.describe "Admin::Users" do
end
end
- describe "GET /admin/users/:id/projects" do
- let(:group) { create(:group) }
- let!(:project) { create(:project, group: group) }
+ describe 'GET /admin/users/:id/projects' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
before do
group.add_developer(user)
@@ -633,7 +476,7 @@ RSpec.describe "Admin::Users" do
visit projects_admin_user_path(user)
end
- it "lists group projects" do
+ it 'lists group projects' do
within(:css, '.gl-mb-3 + .card') do
expect(page).to have_content 'Group projects'
expect(page).to have_link group.name, href: admin_group_path(group)
@@ -690,112 +533,13 @@ RSpec.describe "Admin::Users" do
visit new_admin_user_identity_path(user)
- check_breadcrumb("New Identity")
+ check_breadcrumb('New Identity')
visit admin_user_identities_path(user)
find('.table').find(:link, 'Edit').click
- check_breadcrumb("Edit Identity")
- end
- end
-
- describe 'show user attributes' do
- it do
- visit admin_users_path
-
- click_link user.name
-
- expect(page).to have_content 'Account'
- expect(page).to have_content 'Personal projects limit'
- end
- end
-
- describe 'remove users secondary email', :js do
- let!(: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}")
-
- accept_confirm { find("#remove_email_#{secondary_email.id}").click }
-
- expect(page).not_to have_content(secondary_email.email)
- end
- end
-
- describe 'show user keys', :js do
- let!(:key1) do
- 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")
- end
-
- let!(:key2) do
- create(:key, user: user, title: "ssh-rsa Key2", key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQSTWXhJAX/He+nG78MiRRRn7m0Pb0XbcgTxE0etArgoFoh9WtvDf36HG6tOSg/0UUNcp0dICsNAmhBKdncp6cIyPaXJTURPRAGvhI0/VDk4bi27bRnccGbJ/hDaUxZMLhhrzY0r22mjVf8PF6dvv5QUIQVm1/LeaWYsHHvLgiIjwrXirUZPnFrZw6VLREoBKG8uWvfSXw1L5eapmstqfsME8099oi+vWLR8MgEysZQmD28M73fgW4zek6LDQzKQyJx9nB+hJkKUDvcuziZjGmRFlNgSA2mguERwL1OXonD8WYUrBDGKroIvBT39zS5d9tQDnidEJZ9Y8gv5ViYP7x Key2")
- end
-
- it do
- visit admin_users_path
-
- click_link user.name
- click_link 'SSH keys'
-
- expect(page).to have_content(key1.title)
- expect(page).to have_content(key2.title)
-
- click_link key2.title
-
- expect(page).to have_content(key2.title)
- expect(page).to have_content(key2.key)
-
- click_button 'Delete'
-
- page.within('.modal') do
- page.click_button('Delete')
- end
-
- expect(page).not_to have_content(key2.title)
- end
- end
-
- describe 'show user identities' do
- it 'shows user identities' do
- visit admin_user_identities_path(user)
-
- expect(page).to have_content(user.name)
- expect(page).to have_content('twitter')
- end
- end
-
- 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' 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
-
- describe 'remove user with identities' do
- it 'removes user with twitter identity' do
- visit admin_user_identities_path(user)
-
- click_link 'Delete'
-
- expect(page).to have_content(user.name)
- expect(page).not_to have_content('twitter')
+ check_breadcrumb('Edit Identity')
end
end
diff --git a/spec/features/alert_management/alert_management_list_spec.rb b/spec/features/alert_management/alert_management_list_spec.rb
index 37658f8c545..44ed2f3d60c 100644
--- a/spec/features/alert_management/alert_management_list_spec.rb
+++ b/spec/features/alert_management/alert_management_list_spec.rb
@@ -5,54 +5,54 @@ require 'spec_helper'
RSpec.describe 'Alert Management index', :js do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
- let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
before_all do
project.add_developer(developer)
end
- before do
- sign_in(developer)
+ context 'when a developer displays the alert list' do
+ before do
+ sign_in(developer)
- visit project_alert_management_index_path(project)
- wait_for_requests
- end
-
- context 'when a developer displays the alert list and alert integrations are not enabled' do
- it 'shows the alert page title' do
- expect(page).to have_content('Alerts')
+ visit project_alert_management_index_path(project)
+ wait_for_requests
end
- it 'shows the empty state by default' do
+ it 'shows the alert page title and empty state without filtered search or alert table' do
+ expect(page).to have_content('Alerts')
expect(page).to have_content('Surface alerts in GitLab')
- end
-
- it 'does not show the filtered search' do
+ expect(page).not_to have_selector('.gl-table')
page.within('.layout-page') do
expect(page).not_to have_css('[data-testid="search-icon"]')
end
end
- it 'does not show the alert table' do
- expect(page).not_to have_selector('.gl-table')
+ shared_examples 'alert page with title, filtered search, and table' do
+ it 'renders correctly' do
+ expect(page).to have_content('Alerts')
+ expect(page).to have_selector('.gl-table')
+ page.within('.layout-page') do
+ expect(page).to have_css('[data-testid="search-icon"]')
+ end
+ end
end
- end
- context 'when a developer displays the alert list and an HTTP integration is enabled' do
- let_it_be(:integration) { create(:alert_management_http_integration, project: project) }
+ context 'when alerts have already been created' do
+ let_it_be(:alert) { create(:alert_management_alert, project: project) }
- it 'shows the alert page title' do
- expect(page).to have_content('Alerts')
+ it_behaves_like 'alert page with title, filtered search, and table'
end
- it 'shows the filtered search' do
- page.within('.layout-page') do
- expect(page).to have_css('[data-testid="search-icon"]')
- end
+ context 'when an HTTP integration is enabled' do
+ let_it_be(:integration) { create(:alert_management_http_integration, project: project) }
+
+ it_behaves_like 'alert page with title, filtered search, and table'
end
- it 'shows the alert table' do
- expect(page).to have_selector('.gl-table')
+ context 'when the prometheus integration is enabled' do
+ let_it_be(:integration) { create(:prometheus_service, project: project) }
+
+ it_behaves_like 'alert page with title, filtered search, and table'
end
end
end
diff --git a/spec/features/alerts_settings/user_views_alerts_settings_spec.rb b/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
index 0ded13ae607..698a36d3f76 100644
--- a/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
+++ b/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe 'Alert integrations settings form', :js do
end
describe 'when viewing alert integrations as a maintainer' do
- context 'with feature flag enabled' do
+ context 'with the default page permissions' do
before do
visit project_settings_operations_path(project, anchor: 'js-alert-management-settings')
wait_for_requests
@@ -33,19 +33,6 @@ RSpec.describe 'Alert integrations settings form', :js do
expect(page).to have_content('1. Select integration type')
end
end
-
- context 'with feature flag disabled' do
- before do
- stub_feature_flags(http_integrations_list: false)
-
- visit project_settings_operations_path(project, anchor: 'js-alert-management-settings')
- wait_for_requests
- end
-
- it 'shows the old alerts setting form' do
- expect(page).to have_content('Webhook URL')
- end
- end
end
describe 'when viewing alert integrations as a developer' do
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb
index f941adca233..8d0fa3e023b 100644
--- a/spec/features/boards/add_issues_modal_spec.rb
+++ b/spec/features/boards/add_issues_modal_spec.rb
@@ -37,6 +37,10 @@ RSpec.describe 'Issue Boards add issue modal', :js do
end
context 'modal interaction' do
+ before do
+ stub_feature_flags(add_issues_button: true)
+ end
+
it 'opens modal' do
click_button('Add issues')
@@ -72,6 +76,7 @@ RSpec.describe 'Issue Boards add issue modal', :js do
context 'issues list' do
before do
+ stub_feature_flags(add_issues_button: true)
click_button('Add issues')
wait_for_requests
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 06ec4e05828..b3cc2eb418d 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -27,11 +27,11 @@ RSpec.describe 'Issue Boards', :js do
end
it 'creates default lists' do
- lists = ['Open', 'To Do', 'Doing', 'Closed']
+ lists = %w[Open Closed]
wait_for_requests
- expect(page).to have_selector('.board', count: 4)
+ expect(page).to have_selector('.board', count: 2)
page.all('.board').each_with_index do |list, i|
expect(list.find('.board-title')).to have_content(lists[i])
diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb
index f51b4d21e3b..cefb486349d 100644
--- a/spec/features/boards/keyboard_shortcut_spec.rb
+++ b/spec/features/boards/keyboard_shortcut_spec.rb
@@ -9,7 +9,9 @@ RSpec.describe 'Issue Boards shortcut', :js do
before do
create(:board, project: project)
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit project_path(project)
end
@@ -26,7 +28,9 @@ RSpec.describe 'Issue Boards shortcut', :js do
let(:project) { create(:project, :issues_disabled) }
before do
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit project_path(project)
end
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 332c90df6d7..2af5b787a78 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -72,7 +72,7 @@ RSpec.describe 'Issue Boards', :js do
end
end
- it 'removes card from board when clicking ' do
+ it 'removes card from board when clicking' do
click_card(card)
page.within('.issue-boards-sidebar') do
diff --git a/spec/features/breadcrumbs_schema_markup_spec.rb b/spec/features/breadcrumbs_schema_markup_spec.rb
index 30d5f40fea8..a87a3d284de 100644
--- a/spec/features/breadcrumbs_schema_markup_spec.rb
+++ b/spec/features/breadcrumbs_schema_markup_spec.rb
@@ -15,15 +15,12 @@ RSpec.describe 'Breadcrumbs schema markup', :aggregate_failures do
item_list = get_schema_content
- expect(item_list.size).to eq 3
+ expect(item_list.size).to eq 2
expect(item_list[0]['name']).to eq project.namespace.name
expect(item_list[0]['item']).to eq user_url(project.owner)
expect(item_list[1]['name']).to eq project.name
expect(item_list[1]['item']).to eq project_url(project)
-
- expect(item_list[2]['name']).to eq 'Details'
- expect(item_list[2]['item']).to eq project_url(project)
end
it 'generates the breadcrumb schema for group projects' do
@@ -31,7 +28,7 @@ RSpec.describe 'Breadcrumbs schema markup', :aggregate_failures do
item_list = get_schema_content
- expect(item_list.size).to eq 4
+ expect(item_list.size).to eq 3
expect(item_list[0]['name']).to eq group.name
expect(item_list[0]['item']).to eq group_url(group)
@@ -40,9 +37,6 @@ RSpec.describe 'Breadcrumbs schema markup', :aggregate_failures do
expect(item_list[2]['name']).to eq group_project.name
expect(item_list[2]['item']).to eq project_url(group_project)
-
- expect(item_list[3]['name']).to eq 'Details'
- expect(item_list[3]['item']).to eq project_url(group_project)
end
it 'generates the breadcrumb schema for group' do
@@ -50,15 +44,12 @@ RSpec.describe 'Breadcrumbs schema markup', :aggregate_failures do
item_list = get_schema_content
- expect(item_list.size).to eq 3
+ expect(item_list.size).to eq 2
expect(item_list[0]['name']).to eq group.name
expect(item_list[0]['item']).to eq group_url(group)
expect(item_list[1]['name']).to eq subgroup.name
expect(item_list[1]['item']).to eq group_url(subgroup)
-
- expect(item_list[2]['name']).to eq 'Details'
- expect(item_list[2]['item']).to eq group_url(subgroup)
end
it 'generates the breadcrumb schema for issues' do
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index 31d6bcda9e8..6fe6c099d80 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -168,6 +168,10 @@ RSpec.describe 'Clusterable > Show page' do
let(:cluster_path) { admin_cluster_path(cluster) }
let(:cluster) { create(:cluster, :provided_by_gcp, :instance) }
+ before do
+ gitlab_enable_admin_mode_sign_in(current_user)
+ end
+
it_behaves_like 'show page' do
let(:cluster_type_label) { 'Instance cluster' }
end
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 97ee891dbb8..f8e84043c1b 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -125,7 +125,7 @@ RSpec.describe 'Commits' do
visit pipeline_path(pipeline)
end
- it 'Renders header', :js do
+ it 'renders header', :js do
expect(page).to have_content pipeline.sha[0..7]
expect(page).to have_content pipeline.git_commit_message.gsub!(/\s+/, ' ')
expect(page).to have_content pipeline.user.name
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index b63079777cb..233a93c2054 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -24,10 +24,6 @@ RSpec.describe 'Value Stream Analytics', :js do
wait_for_requests
end
- it 'shows introductory message' do
- expect(page).to have_content('Introducing Value Stream Analytics')
- end
-
it 'shows pipeline summary' do
expect(new_issues_counter).to have_content('-')
expect(commits_counter).to have_content('-')
@@ -48,6 +44,16 @@ RSpec.describe 'Value Stream Analytics', :js do
@build = create_cycle(user, project, issue, mr, milestone, pipeline)
deploy_master(user, project)
+ issue.metrics.update!(first_mentioned_in_commit_at: issue.metrics.first_associated_with_milestone_at + 1.day)
+ merge_request = issue.merge_requests_closing_issues.first.merge_request
+ merge_request.update!(created_at: issue.metrics.first_associated_with_milestone_at + 1.day)
+ merge_request.metrics.update!(
+ latest_build_started_at: 4.hours.ago,
+ latest_build_finished_at: 3.hours.ago,
+ merged_at: merge_request.created_at + 1.hour,
+ first_deployed_to_production_at: merge_request.created_at + 2.hours
+ )
+
sign_in(user)
visit project_cycle_analytics_path(project)
end
diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb
index 9965229a539..1b349fa2276 100644
--- a/spec/features/dashboard/archived_projects_spec.rb
+++ b/spec/features/dashboard/archived_projects_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe 'Dashboard Archived Project' do
end
it 'searches archived projects', :js do
- click_button 'Last updated'
+ click_button 'Name'
click_link 'Show archived projects'
expect(page).to have_link(project.name)
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index 653a16bbbcc..0b99fed2a2d 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -17,14 +17,11 @@ RSpec.describe 'Dashboard Group' do
visit dashboard_groups_path
find('.btn-success').click
new_name = 'Samurai'
- new_description = 'Tokugawa Shogunate'
fill_in 'group_name', with: new_name
- fill_in 'group_description', with: new_description
click_button 'Create group'
expect(current_path).to eq group_path(Group.find_by(name: new_name))
expect(page).to have_content(new_name)
- expect(page).to have_content(new_description)
end
end
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index 952a78ec79a..0e76b5478a1 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -52,20 +52,29 @@ RSpec.describe 'Dashboard Merge Requests' do
end
context 'merge requests exist' do
+ let_it_be(:author_user) { create(:user) }
let(:label) { create(:label) }
let!(:assigned_merge_request) do
create(:merge_request,
assignees: [current_user],
source_project: project,
- author: create(:user))
+ author: author_user)
+ end
+
+ let!(:review_requested_merge_request) do
+ create(:merge_request,
+ reviewers: [current_user],
+ source_branch: 'review',
+ source_project: project,
+ author: author_user)
end
let!(:assigned_merge_request_from_fork) do
create(:merge_request,
source_branch: 'markdown', assignees: [current_user],
target_project: public_project, source_project: forked_project,
- author: create(:user))
+ author: author_user)
end
let!(:authored_merge_request) do
@@ -94,7 +103,7 @@ RSpec.describe 'Dashboard Merge Requests' do
create(:merge_request,
source_branch: 'fix',
source_project: project,
- author: create(:user))
+ author: author_user)
end
before do
@@ -111,6 +120,10 @@ RSpec.describe 'Dashboard Merge Requests' do
expect(page).not_to have_content(labeled_merge_request.title)
end
+ it 'does not show review requested merge requests' do
+ expect(page).not_to have_content(review_requested_merge_request.title)
+ end
+
it 'shows authored merge requests', :js do
reset_filters
input_filtered_search("author:=#{current_user.to_reference}")
@@ -159,4 +172,25 @@ RSpec.describe 'Dashboard Merge Requests' do
expect(find('.issues-filters')).to have_content('Created date')
end
end
+
+ context 'merge request review', :js do
+ let_it_be(:author_user) { create(:user) }
+ let!(:review_requested_merge_request) do
+ create(:merge_request,
+ reviewers: [current_user],
+ source_branch: 'review',
+ source_project: project,
+ author: author_user)
+ end
+
+ before do
+ visit merge_requests_dashboard_path(reviewer_username: current_user.username)
+ end
+
+ it 'displays review requested merge requests' do
+ expect(page).to have_content(review_requested_merge_request.title)
+
+ expect_tokens([reviewer_token(current_user.name)])
+ end
+ end
end
diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb
index 58352518d43..b2fda28f0ec 100644
--- a/spec/features/dashboard/shortcuts_spec.rb
+++ b/spec/features/dashboard/shortcuts_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe 'Dashboard shortcuts', :js do
visit root_dashboard_path
end
- it 'Navigate to tabs' do
+ it 'navigate to tabs' do
find('body').send_keys([:shift, 'I'])
check_page_title('Issues')
@@ -45,7 +45,7 @@ RSpec.describe 'Dashboard shortcuts', :js do
visit explore_root_path
end
- it 'Navigate to tabs' do
+ it 'navigate to tabs' do
find('body').send_keys([:shift, 'G'])
find('.nothing-here-block')
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index 832f50932f4..9fa77d5917d 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -173,11 +173,11 @@ RSpec.describe 'Dashboard > User filters projects' do
end
end
- it 'defaults to "Last updated"', :js do
+ it 'defaults to "Name"', :js do
page.find('.filtered-search-block #filtered-search-sorting-dropdown').click
active_sorting_option = page.first('.filtered-search-block #filtered-search-sorting-dropdown .is-active')
- expect(active_sorting_option).to have_content 'Last updated'
+ expect(active_sorting_option).to have_content 'Name'
end
context 'Sorting by name' do
diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb
index 0912df22924..55bdf4c244e 100644
--- a/spec/features/expand_collapse_diffs_spec.rb
+++ b/spec/features/expand_collapse_diffs_spec.rb
@@ -10,7 +10,9 @@ RSpec.describe 'Expand and collapse diffs', :js do
stub_feature_flags(increased_diff_limits: false)
allow(Gitlab::CurrentSettings).to receive(:diff_max_patch_bytes).and_return(100.kilobytes)
- sign_in(create(:admin))
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
# Ensure that undiffable.md is in .gitattributes
project.repository.copy_gitattributes(branch)
diff --git a/spec/features/file_uploads/git_lfs_spec.rb b/spec/features/file_uploads/git_lfs_spec.rb
index b902d7ab702..239afb1a1bb 100644
--- a/spec/features/file_uploads/git_lfs_spec.rb
+++ b/spec/features/file_uploads/git_lfs_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe 'Upload a git lfs object', :js do
include_context 'file upload requests helpers'
let_it_be(:project) { create(:project) }
- let_it_be(:user) { create(:user, :admin) }
+ let_it_be(:user) { project.owner }
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let(:file) { fixture_file_upload('spec/fixtures/banana_sample.gif') }
@@ -19,7 +19,7 @@ RSpec.describe 'Upload a git lfs object', :js do
HTTParty.put(
url,
headers: headers,
- basic_auth: { user: user.username, password: personal_access_token.token },
+ basic_auth: { username: user.username, password: personal_access_token.token },
body: file.read
)
end
diff --git a/spec/features/file_uploads/multipart_invalid_uploads_spec.rb b/spec/features/file_uploads/multipart_invalid_uploads_spec.rb
index b3ace2e30ff..91c8e100e6a 100644
--- a/spec/features/file_uploads/multipart_invalid_uploads_spec.rb
+++ b/spec/features/file_uploads/multipart_invalid_uploads_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe 'Invalid uploads that must be rejected', :api, :js do
subject do
HTTParty.put(
url,
- basic_auth: { user: user.username, password: personal_access_token.token },
+ basic_auth: { username: user.username, password: personal_access_token.token },
body: body
)
end
diff --git a/spec/features/file_uploads/nuget_package_spec.rb b/spec/features/file_uploads/nuget_package_spec.rb
index fb1e0a54744..6e05e5d1a6e 100644
--- a/spec/features/file_uploads/nuget_package_spec.rb
+++ b/spec/features/file_uploads/nuget_package_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Upload a nuget package', :api, :js do
subject do
HTTParty.put(
url,
- basic_auth: { user: user.username, password: personal_access_token.token },
+ basic_auth: { username: user.username, password: personal_access_token.token },
body: { package: file }
)
end
diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb
index e6e4a55c1bb..19fb8e5f52c 100644
--- a/spec/features/global_search_spec.rb
+++ b/spec/features/global_search_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Global search' do
+ include AfterNextHelpers
+
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
@@ -22,9 +24,7 @@ RSpec.describe 'Global search' do
describe 'I search through the issues and I see pagination' do
before do
- allow_next_instance_of(SearchService) do |instance|
- allow(instance).to receive(:per_page).and_return(1)
- end
+ allow_next(SearchService).to receive(:per_page).and_return(1)
create_list(:issue, 2, project: project, title: 'initial')
end
diff --git a/spec/features/groups/board_spec.rb b/spec/features/groups/board_spec.rb
index 29d0347086c..b25aa26d906 100644
--- a/spec/features/groups/board_spec.rb
+++ b/spec/features/groups/board_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Group Boards' do
visit group_boards_path(group)
end
- it 'Adds an issue to the backlog' do
+ it 'adds an issue to the backlog' do
page.within(find('.board', match: :first)) do
issue_title = 'New Issue'
find(:css, '.issue-count-badge-add-button').click
diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb
index 1b23b8b4bf9..cacabdda22d 100644
--- a/spec/features/groups/container_registry_spec.rb
+++ b/spec/features/groups/container_registry_spec.rb
@@ -51,13 +51,6 @@ RSpec.describe 'Container Registry', :js do
expect(page).to have_content 'my/image'
end
- it 'image repository delete is disabled' do
- visit_container_registry
-
- delete_btn = find('[title="Remove repository"]')
- expect(delete_btn).to be_disabled
- end
-
it 'navigates to repo details' do
visit_container_registry_details('my/image')
diff --git a/spec/features/groups/dependency_proxy_spec.rb b/spec/features/groups/dependency_proxy_spec.rb
index 9bbfdc488fb..51371ddc532 100644
--- a/spec/features/groups/dependency_proxy_spec.rb
+++ b/spec/features/groups/dependency_proxy_spec.rb
@@ -79,13 +79,19 @@ RSpec.describe 'Group Dependency Proxy' do
sign_in(developer)
end
- context 'group is private' do
- let(:group) { create(:group, :private) }
+ context 'feature flag is disabled' do
+ before do
+ stub_feature_flags(dependency_proxy_for_private_groups: false)
+ end
- it 'informs user that feature is only available for public groups' do
- visit path
+ context 'group is private' do
+ let(:group) { create(:group, :private) }
- expect(page).to have_content('Dependency proxy feature is limited to public groups for now.')
+ it 'informs user that feature is only available for public groups' do
+ visit path
+
+ expect(page).to have_content('Dependency proxy feature is limited to public groups for now.')
+ end
end
end
diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb
new file mode 100644
index 00000000000..c0f967fd0b9
--- /dev/null
+++ b/spec/features/groups/import_export/connect_instance_spec.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Import/Export - Connect to another instance', :js do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
+ before_all do
+ group.add_owner(user)
+ end
+
+ before do
+ gitlab_sign_in(user)
+
+ visit new_group_path
+
+ find('#import-group-tab').click
+ end
+
+ context 'when the user provides valid credentials' do
+ it 'successfully connects to remote instance' do
+ source_url = 'https://gitlab.com'
+ pat = 'demo-pat'
+ stub_path = 'stub-group'
+
+ stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=30&top_level_only=true" % { url: source_url }).to_return(
+ body: [{
+ id: 2595438,
+ web_url: 'https://gitlab.com/groups/auto-breakfast',
+ name: 'Stub',
+ path: stub_path,
+ full_name: 'Stub',
+ full_path: stub_path
+ }].to_json,
+ headers: { 'Content-Type' => 'application/json' }
+ )
+
+ expect(page).to have_content 'Import groups from another instance of GitLab'
+
+ fill_in :bulk_import_gitlab_url, with: source_url
+ fill_in :bulk_import_gitlab_access_token, with: pat
+
+ click_on 'Connect instance'
+
+ expect(page).to have_content 'Importing groups from %{url}' % { url: source_url }
+ expect(page).to have_content stub_path
+ end
+ end
+
+ context 'when the user provides invalid url' do
+ it 'reports an error' do
+ source_url = 'invalid-url'
+ pat = 'demo-pat'
+
+ fill_in :bulk_import_gitlab_url, with: source_url
+ fill_in :bulk_import_gitlab_access_token, with: pat
+
+ click_on 'Connect instance'
+
+ expect(page).to have_content 'Specified URL cannot be used'
+ end
+ end
+
+ context 'when the user does not fill in source URL' do
+ it 'reports an error' do
+ pat = 'demo-pat'
+
+ fill_in :bulk_import_gitlab_access_token, with: pat
+
+ click_on 'Connect instance'
+
+ expect(page).to have_content 'Please fill in GitLab source URL'
+ end
+ end
+
+ context 'when the user does not fill in access token' do
+ it 'reports an error' do
+ source_url = 'https://gitlab.com'
+
+ fill_in :bulk_import_gitlab_url, with: source_url
+
+ click_on 'Connect instance'
+
+ expect(page).to have_content 'Please fill in your personal access token'
+ end
+ end
+end
diff --git a/spec/features/groups/import_export/import_file_spec.rb b/spec/features/groups/import_export/import_file_spec.rb
index f117b5d56e9..7018f3b1086 100644
--- a/spec/features/groups/import_export/import_file_spec.rb
+++ b/spec/features/groups/import_export/import_file_spec.rb
@@ -32,12 +32,12 @@ RSpec.describe 'Import/Export - Group Import', :js do
fill_in :group_name, with: group_name
find('#import-group-tab').click
- expect(page).to have_content 'Import a GitLab group export file'
+ expect(page).to have_content 'Import group from file'
attach_file(file) do
find('.js-filepicker-button').click
end
- expect { click_on 'Import group' }.to change { Group.count }.by 1
+ expect { click_on 'Import' }.to change { Group.count }.by 1
group = Group.find_by(name: group_name)
@@ -60,7 +60,7 @@ RSpec.describe 'Import/Export - Group Import', :js do
find('.js-filepicker-button').click
end
- expect { click_on 'Import group' }.to change { Group.count }.by 1
+ expect { click_on 'Import' }.to change { Group.count }.by 1
group = Group.find_by(name: 'Test Group Import')
expect(group.path).to eq 'custom-path'
@@ -94,7 +94,7 @@ RSpec.describe 'Import/Export - Group Import', :js do
find('.js-filepicker-button').click
end
- expect { click_on 'Import group' }.not_to change { Group.count }
+ expect { click_on 'Import' }.not_to change { Group.count }
page.within('.flash-container') do
expect(page).to have_content('Unable to process group import file')
diff --git a/spec/features/groups/members/filter_members_spec.rb b/spec/features/groups/members/filter_members_spec.rb
index b6d33b3f4aa..917b35659a6 100644
--- a/spec/features/groups/members/filter_members_spec.rb
+++ b/spec/features/groups/members/filter_members_spec.rb
@@ -11,8 +11,7 @@ RSpec.describe 'Groups > Members > Filter members', :js do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
- two_factor_auth_dropdown_toggle_selector = '[data-testid="member-filter-2fa-dropdown"] [data-testid="dropdown-toggle"]'
- active_inherited_members_filter_selector = '[data-testid="filter-members-with-inherited-permissions"] a.is-active'
+ filtered_search_bar_selector = '[data-testid="members-filtered-search-bar"]'
before do
group.add_owner(user)
@@ -27,7 +26,6 @@ RSpec.describe 'Groups > Members > Filter members', :js do
expect(member(0)).to include(user.name)
expect(member(1)).to include(user_with_2fa.name)
- expect(page).to have_css(two_factor_auth_dropdown_toggle_selector, text: 'Everyone')
end
it 'shows only 2FA members' do
@@ -35,7 +33,10 @@ RSpec.describe 'Groups > Members > Filter members', :js do
expect(member(0)).to include(user_with_2fa.name)
expect(all_rows.size).to eq(1)
- expect(page).to have_css(two_factor_auth_dropdown_toggle_selector, text: 'Enabled')
+
+ within filtered_search_bar_selector do
+ expect(page).to have_content '2FA = Enabled'
+ end
end
it 'shows only non 2FA members' do
@@ -43,7 +44,10 @@ RSpec.describe 'Groups > Members > Filter members', :js do
expect(member(0)).to include(user.name)
expect(all_rows.size).to eq(1)
- expect(page).to have_css(two_factor_auth_dropdown_toggle_selector, text: 'Disabled')
+
+ within filtered_search_bar_selector do
+ expect(page).to have_content '2FA = Disabled'
+ end
end
it 'shows inherited members by default' do
@@ -53,15 +57,16 @@ RSpec.describe 'Groups > Members > Filter members', :js do
expect(member(1)).to include(user_with_2fa.name)
expect(member(2)).to include(nested_group_user.name)
expect(all_rows.size).to eq(3)
-
- expect(page).to have_css(active_inherited_members_filter_selector, text: 'Show all members', visible: false)
end
it 'shows only group members' do
visit_members_list(nested_group, with_inherited_permissions: 'exclude')
expect(member(0)).to include(nested_group_user.name)
expect(all_rows.size).to eq(1)
- expect(page).to have_css(active_inherited_members_filter_selector, text: 'Show only direct members', visible: false)
+
+ within filtered_search_bar_selector do
+ expect(page).to have_content 'Membership = Direct'
+ end
end
it 'shows only inherited members' do
@@ -69,7 +74,10 @@ RSpec.describe 'Groups > Members > Filter members', :js do
expect(member(0)).to include(user.name)
expect(member(1)).to include(user_with_2fa.name)
expect(all_rows.size).to eq(2)
- expect(page).to have_css(active_inherited_members_filter_selector, text: 'Show only inherited members', visible: false)
+
+ within filtered_search_bar_selector do
+ expect(page).to have_content 'Membership = Inherited'
+ end
end
def visit_members_list(group, options = {})
diff --git a/spec/features/groups/members/search_members_spec.rb b/spec/features/groups/members/search_members_spec.rb
index 0b2d2fd478d..fe5fed307d7 100644
--- a/spec/features/groups/members/search_members_spec.rb
+++ b/spec/features/groups/members/search_members_spec.rb
@@ -21,9 +21,10 @@ RSpec.describe 'Search group member', :js do
end
it 'renders member users' do
- page.within '[data-testid="user-search-form"]' do
- fill_in 'search', with: member.name
- find('[data-testid="user-search-submit"]').click
+ page.within '[data-testid="members-filtered-search-bar"]' do
+ find_field('Filter members').click
+ find('input').native.send_keys(member.name)
+ click_button 'Search'
end
expect(members_table).to have_content(member.name)
diff --git a/spec/features/groups/members/sort_members_spec.rb b/spec/features/groups/members/sort_members_spec.rb
index f03cc36df18..68a748aa76a 100644
--- a/spec/features/groups/members/sort_members_spec.rb
+++ b/spec/features/groups/members/sort_members_spec.rb
@@ -9,8 +9,6 @@ RSpec.describe 'Groups > Members > Sort members', :js do
let(:developer) { create(:user, name: 'Mary Jane', last_sign_in_at: 5.days.ago) }
let(:group) { create(:group) }
- dropdown_toggle_selector = '[data-testid="user-sort-dropdown"] [data-testid="dropdown-toggle"]'
-
before do
create(:group_member, :owner, user: owner, group: group, created_at: 5.days.ago)
create(:group_member, :developer, user: developer, group: group, created_at: 3.days.ago)
@@ -18,76 +16,174 @@ RSpec.describe 'Groups > Members > Sort members', :js do
sign_in(owner)
end
- it 'sorts alphabetically by default' do
- visit_members_list(sort: nil)
+ context 'when `group_members_filtered_search` feature flag is enabled' do
+ def expect_sort_by(text, sort_direction)
+ within('[data-testid="members-sort-dropdown"]') do
+ expect(page).to have_css('button[aria-haspopup="true"]', text: text)
+ expect(page).to have_button("Sorting Direction: #{sort_direction == :asc ? 'Ascending' : 'Descending'}")
+ end
+ end
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Name, ascending')
- end
+ it 'sorts by account by default' do
+ visit_members_list(sort: nil)
- it 'sorts by access level ascending' do
- visit_members_list(sort: :access_level_asc)
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Access level, ascending')
- end
+ expect_sort_by('Account', :asc)
+ end
- it 'sorts by access level descending' do
- visit_members_list(sort: :access_level_desc)
+ it 'sorts by max role ascending' do
+ visit_members_list(sort: :access_level_asc)
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Access level, descending')
- end
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
- it 'sorts by last joined' do
- visit_members_list(sort: :last_joined)
+ expect_sort_by('Max role', :asc)
+ end
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Last joined')
- end
+ it 'sorts by max role descending' do
+ visit_members_list(sort: :access_level_desc)
- it 'sorts by oldest joined' do
- visit_members_list(sort: :oldest_joined)
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Oldest joined')
- end
+ expect_sort_by('Max role', :desc)
+ end
- it 'sorts by name ascending' do
- visit_members_list(sort: :name_asc)
+ it 'sorts by access granted ascending' do
+ visit_members_list(sort: :last_joined)
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Name, ascending')
- end
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
- it 'sorts by name descending' do
- visit_members_list(sort: :name_desc)
+ expect_sort_by('Access granted', :asc)
+ end
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Name, descending')
- end
+ it 'sorts by access granted descending' do
+ visit_members_list(sort: :oldest_joined)
+
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
+
+ expect_sort_by('Access granted', :desc)
+ end
+
+ it 'sorts by account ascending' do
+ visit_members_list(sort: :name_asc)
+
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
+
+ expect_sort_by('Account', :asc)
+ end
+
+ it 'sorts by account descending' do
+ visit_members_list(sort: :name_desc)
+
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
+
+ expect_sort_by('Account', :desc)
+ end
+
+ it 'sorts by last sign-in ascending', :clean_gitlab_redis_shared_state do
+ visit_members_list(sort: :recent_sign_in)
+
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
+
+ expect_sort_by('Last sign-in', :asc)
+ end
- it 'sorts by recent sign in', :clean_gitlab_redis_shared_state do
- visit_members_list(sort: :recent_sign_in)
+ it 'sorts by last sign-in descending', :clean_gitlab_redis_shared_state do
+ visit_members_list(sort: :oldest_sign_in)
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Recent sign in')
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
+
+ expect_sort_by('Last sign-in', :desc)
+ end
end
- it 'sorts by oldest sign in', :clean_gitlab_redis_shared_state do
- visit_members_list(sort: :oldest_sign_in)
+ context 'when `group_members_filtered_search` feature flag is disabled' do
+ dropdown_toggle_selector = '[data-testid="user-sort-dropdown"] [data-testid="dropdown-toggle"]'
+
+ before do
+ stub_feature_flags(group_members_filtered_search: false)
+ end
+
+ it 'sorts alphabetically by default' do
+ visit_members_list(sort: nil)
+
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Name, ascending')
+ end
+
+ it 'sorts by access level ascending' do
+ visit_members_list(sort: :access_level_asc)
+
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Access level, ascending')
+ end
+
+ it 'sorts by access level descending' do
+ visit_members_list(sort: :access_level_desc)
+
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Access level, descending')
+ end
+
+ it 'sorts by last joined' do
+ visit_members_list(sort: :last_joined)
+
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Last joined')
+ end
+
+ it 'sorts by oldest joined' do
+ visit_members_list(sort: :oldest_joined)
+
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Oldest joined')
+ end
+
+ it 'sorts by name ascending' do
+ visit_members_list(sort: :name_asc)
+
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Name, ascending')
+ end
+
+ it 'sorts by name descending' do
+ visit_members_list(sort: :name_desc)
+
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Name, descending')
+ end
+
+ it 'sorts by recent sign in', :clean_gitlab_redis_shared_state do
+ visit_members_list(sort: :recent_sign_in)
+
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Recent sign in')
+ end
+
+ it 'sorts by oldest sign in', :clean_gitlab_redis_shared_state do
+ visit_members_list(sort: :oldest_sign_in)
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Oldest sign in')
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
+ expect(page).to have_css(dropdown_toggle_selector, text: 'Oldest sign in')
+ end
end
def visit_members_list(sort:)
diff --git a/spec/features/groups/members/tabs_spec.rb b/spec/features/groups/members/tabs_spec.rb
index fa77d1a2ff8..2f95e9fa6d3 100644
--- a/spec/features/groups/members/tabs_spec.rb
+++ b/spec/features/groups/members/tabs_spec.rb
@@ -62,9 +62,10 @@ RSpec.describe 'Groups > Members > Tabs' do
click_link 'Invited'
- page.within '[data-testid="user-search-form"]' do
- fill_in 'search_invited', with: 'email'
- find('button[type="submit"]').click
+ page.within '[data-testid="members-filtered-search-bar"]' do
+ find_field('Search invited').click
+ find('input').native.send_keys('email')
+ click_button 'Search'
end
end
@@ -74,9 +75,10 @@ RSpec.describe 'Groups > Members > Tabs' do
before do
click_link 'Members'
- page.within '[data-testid="user-search-form"]' do
- fill_in 'search', with: 'test'
- find('button[type="submit"]').click
+ page.within '[data-testid="members-filtered-search-bar"]' do
+ find_field('Filter members').click
+ find('input').native.send_keys('test')
+ click_button 'Search'
end
end
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index dec07eb3783..a4c450c9a2c 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -33,6 +33,7 @@ RSpec.describe 'Group navbar' do
nav_item: _('Merge Requests'),
nav_sub_items: []
},
+ (security_and_compliance_nav_item if Gitlab.ee?),
(push_rules_nav_item if Gitlab.ee?),
{
nav_item: _('Kubernetes'),
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index 97732374eb9..3a42fd508b4 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -193,4 +193,69 @@ RSpec.describe 'Group show page' do
it_behaves_like 'page meta description', 'Lorem ipsum dolor sit amet'
end
+
+ context 'structured schema markup' do
+ let_it_be(:group) { create(:group, :public, :with_avatar, description: 'foo') }
+ let_it_be(:subgroup) { create(:group, :public, :with_avatar, parent: group, description: 'bar') }
+ let_it_be_with_reload(:project) { create(:project, :public, :with_avatar, namespace: group, description: 'foo') }
+ let_it_be(:subproject) { create(:project, :public, :with_avatar, namespace: subgroup, description: 'bar') }
+
+ it 'shows Organization structured markup', :js do
+ visit path
+ wait_for_all_requests
+
+ aggregate_failures do
+ expect(page).to have_selector('.content[itemscope][itemtype="https://schema.org/Organization"]')
+
+ page.within('.group-home-panel') do
+ expect(page).to have_selector('img.avatar[itemprop="logo"]')
+ expect(page).to have_selector('[itemprop="name"]', text: group.name)
+ expect(page).to have_selector('[itemprop="description"]', text: group.description)
+ end
+
+ page.within('[itemprop="owns"][itemtype="https://schema.org/SoftwareSourceCode"]') do
+ expect(page).to have_selector('img.avatar[itemprop="image"]')
+ expect(page).to have_selector('[itemprop="name"]', text: project.name)
+ expect(page).to have_selector('[itemprop="description"]', text: project.description)
+ end
+
+ # Finding the subgroup row and expanding it
+ el = find('[itemprop="subOrganization"][itemtype="https://schema.org/Organization"]')
+ el.click
+ wait_for_all_requests
+ page.within(el) do
+ expect(page).to have_selector('img.avatar[itemprop="logo"]')
+ expect(page).to have_selector('[itemprop="name"]', text: subgroup.name)
+ expect(page).to have_selector('[itemprop="description"]', text: subgroup.description)
+
+ page.within('[itemprop="owns"][itemtype="https://schema.org/SoftwareSourceCode"]') do
+ expect(page).to have_selector('img.avatar[itemprop="image"]')
+ expect(page).to have_selector('[itemprop="name"]', text: subproject.name)
+ expect(page).to have_selector('[itemprop="description"]', text: subproject.description)
+ end
+ end
+ end
+ end
+
+ it 'does not include structured markup in shared projects tab', :js do
+ other_project = create(:project, :public)
+ other_project.project_group_links.create!(group: group)
+
+ visit group_shared_path(group)
+ wait_for_all_requests
+
+ expect(page).to have_selector('li.group-row')
+ expect(page).not_to have_selector('[itemprop="owns"][itemtype="https://schema.org/SoftwareSourceCode"]')
+ end
+
+ it 'does not include structured markup in archived projects tab', :js do
+ project.update!(archived: true)
+
+ visit group_archived_path(group)
+ wait_for_all_requests
+
+ expect(page).to have_selector('li.group-row')
+ expect(page).not_to have_selector('[itemprop="owns"][itemtype="https://schema.org/SoftwareSourceCode"]')
+ end
+ end
end
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index b9fd3a1a5cc..c9a0844932a 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'Group' do
- let(:user) { create(:admin) }
+ let_it_be(:user) { create(:user) }
before do
sign_in(user)
@@ -21,8 +21,6 @@ RSpec.describe 'Group' do
end
describe 'as a non-admin' do
- let(:user) { create(:user) }
-
it 'creates a group and persists visibility radio selection', :js do
stub_application_setting(default_group_visibility: :private)
@@ -38,6 +36,15 @@ RSpec.describe 'Group' do
end
end
+ describe 'with expected fields' do
+ it 'renders from as expected', :aggregate_failures do
+ expect(page).to have_field('name')
+ expect(page).to have_field('group_path')
+ expect(page).to have_field('group_visibility_level_0')
+ expect(page).not_to have_field('description')
+ end
+ end
+
describe 'with space in group path' do
it 'renders new group form with validation errors' do
fill_in 'Group URL', with: 'space group'
@@ -137,9 +144,11 @@ RSpec.describe 'Group' do
end
describe 'create a nested group', :js do
- let(:group) { create(:group, path: 'foo') }
+ let_it_be(:group) { create(:group, path: 'foo') }
context 'as admin' do
+ let(:user) { create(:admin) }
+
before do
visit new_group_path(group, parent_id: group.id)
end
@@ -185,11 +194,13 @@ RSpec.describe 'Group' do
end
describe 'group edit', :js do
- let(:group) { create(:group, :public) }
- let(:path) { edit_group_path(group) }
+ let_it_be(:group) { create(:group, :public) }
+ let(:path) { edit_group_path(group) }
let(:new_name) { 'new-name' }
before do
+ group.add_owner(user)
+
visit path
end
@@ -200,6 +211,8 @@ RSpec.describe 'Group' do
it 'saves new settings' do
page.within('.gs-general') do
+ # Have to reset it to '' so it overwrites rather than appends
+ fill_in('group_name', with: '')
fill_in 'group_name', with: new_name
click_button 'Save changes'
end
@@ -226,8 +239,12 @@ RSpec.describe 'Group' do
end
describe 'group page with markdown description' do
- let(:group) { create(:group) }
- let(:path) { group_path(group) }
+ let_it_be(:group) { create(:group) }
+ let(:path) { group_path(group) }
+
+ before do
+ group.add_owner(user)
+ end
it 'parses Markdown' do
group.update_attribute(:description, 'This is **my** group')
@@ -263,9 +280,13 @@ RSpec.describe 'Group' do
end
describe 'group page with nested groups', :js do
- let!(:group) { create(:group) }
- let!(:nested_group) { create(:group, parent: group) }
- let!(:project) { create(:project, namespace: group) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:nested_group) { create(:group, parent: group) }
+ let_it_be(:project) { create(:project, namespace: group) }
+
+ before do
+ group.add_owner(user)
+ end
it 'renders projects and groups on the page' do
visit group_path(group)
@@ -292,7 +313,15 @@ RSpec.describe 'Group' do
end
describe 'new subgroup / project button' do
- let(:group) { create(:group, project_creation_level: Gitlab::Access::NO_ONE_PROJECT_ACCESS, subgroup_creation_level: Gitlab::Access::OWNER_SUBGROUP_ACCESS) }
+ let_it_be(:group, reload: true) do
+ create(:group,
+ project_creation_level: Gitlab::Access::NO_ONE_PROJECT_ACCESS,
+ subgroup_creation_level: Gitlab::Access::OWNER_SUBGROUP_ACCESS)
+ end
+
+ before do
+ group.add_owner(user)
+ end
context 'when user has subgroup creation permissions but not project creation permissions' do
it 'only displays "New subgroup" button' do
@@ -325,6 +354,7 @@ RSpec.describe 'Group' do
context 'when user has project and subgroup creation permissions' do
it 'displays "New subgroup" and "New project" buttons' do
group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
+
visit group_path(group)
page.within '[data-testid="group-buttons"]' do
diff --git a/spec/features/ide/user_sees_editor_info_spec.rb b/spec/features/ide/user_sees_editor_info_spec.rb
deleted file mode 100644
index 3760d6bd435..00000000000
--- a/spec/features/ide/user_sees_editor_info_spec.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'IDE user sees editor info', :js do
- include WebIdeSpecHelpers
-
- let_it_be(:project) { create(:project, :public, :repository) }
- let_it_be(:user) { project.owner }
-
- before do
- sign_in(user)
-
- ide_visit(project)
- end
-
- it 'shows line position' do
- ide_open_file('README.md')
-
- within find('.ide-status-bar') do
- expect(page).to have_content('1:1')
- end
-
- ide_set_editor_position(4, 10)
-
- within find('.ide-status-bar') do
- expect(page).not_to have_content('1:1')
- expect(page).to have_content('4:10')
- end
- end
-
- it 'updates after rename' do
- ide_open_file('README.md')
- ide_set_editor_position(4, 10)
-
- within find('.ide-status-bar') do
- expect(page).to have_content('markdown')
- expect(page).to have_content('4:10')
- end
-
- ide_rename_file('README.md', 'READMEZ.txt')
-
- within find('.ide-status-bar') do
- expect(page).to have_content('plaintext')
- expect(page).to have_content('1:1')
- end
- end
-
- it 'persists position after rename' do
- ide_open_file('README.md')
- ide_set_editor_position(4, 10)
-
- ide_open_file('files/js/application.js')
- ide_rename_file('README.md', 'READING_RAINBOW.md')
-
- ide_open_file('READING_RAINBOW.md')
-
- within find('.ide-status-bar') do
- expect(page).to have_content('4:10')
- end
- end
-
- it 'persists position' do
- ide_open_file('README.md')
- ide_set_editor_position(4, 10)
-
- ide_close_file('README.md')
- ide_open_file('README.md')
-
- within find('.ide-status-bar') do
- expect(page).to have_content('markdown')
- expect(page).to have_content('4:10')
- end
- end
-
- it 'persists viewer' do
- ide_open_file('README.md')
- click_link('Preview Markdown')
-
- within find('.md-previewer') do
- expect(page).to have_content('testme')
- end
-
- # Switch away from and back to the file
- ide_open_file('.gitignore')
- ide_open_file('README.md')
-
- # Preview is still enabled
- within find('.md-previewer') do
- expect(page).to have_content('testme')
- end
- end
-end
diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb
index 3595f5c03ec..b94ce3cd06f 100644
--- a/spec/features/incidents/user_views_incident_spec.rb
+++ b/spec/features/incidents/user_views_incident_spec.rb
@@ -13,8 +13,6 @@ RSpec.describe "User views incident" do
end
before do
- stub_feature_flags(vue_issue_header: false)
-
sign_in(user)
visit(project_issues_incident_path(project, incident))
@@ -24,10 +22,12 @@ RSpec.describe "User views incident" do
it_behaves_like 'page meta description', ' Description header Lorem ipsum dolor sit amet'
- it 'shows the merge request and incident actions', :aggregate_failures do
- expect(page).to have_link('New incident')
+ it 'shows the merge request and incident actions', :js, :aggregate_failures do
+ click_button 'Incident actions'
+
+ expect(page).to have_link('New incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident' } }))
expect(page).to have_button('Create merge request')
- expect(page).to have_link('Close incident')
+ expect(page).to have_button('Close incident')
end
context 'when the project is archived' do
diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
index 0f0146a26a2..d773126e00c 100644
--- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
@@ -105,7 +105,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
visit new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
end
- it 'Shows a notice to ask someone else to resolve the threads' do
+ it 'shows a notice to ask someone else to resolve the threads' do
expect(page).to have_content("The threads at #{merge_request.to_reference} will stay unresolved. Ask someone with permission to resolve them.")
end
end
diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
index b449939a70c..99dc71f0559 100644
--- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
@@ -31,7 +31,8 @@ RSpec.describe 'Resolve an open thread in a merge request by creating an issue',
visit project_merge_request_path(project, merge_request)
end
- it 'does not show a link to create a new issue' do
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/285453
+ xit 'does not show a link to create a new issue' do
expect(page).not_to have_css resolve_discussion_selector
end
end
@@ -81,7 +82,7 @@ RSpec.describe 'Resolve an open thread in a merge request by creating an issue',
discussion_to_resolve: discussion.id)
end
- it 'Shows a notice to ask someone else to resolve the threads' do
+ it 'shows a notice to ask someone else to resolve the threads' do
expect(page).to have_content("The thread at #{merge_request.to_reference}"\
" (discussion #{discussion.first_note.id}) will stay unresolved."\
" Ask someone with permission to resolve it.")
diff --git a/spec/features/issuables/discussion_lock_spec.rb b/spec/features/issues/discussion_lock_spec.rb
index 13f1742fbf6..13f1742fbf6 100644
--- a/spec/features/issuables/discussion_lock_spec.rb
+++ b/spec/features/issues/discussion_lock_spec.rb
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index 080943da185..4f4584e7dce 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -153,6 +153,14 @@ RSpec.describe 'Filter issues', :js do
end
end
+ describe 'filter by reviewer' do
+ it 'does not allow filtering by reviewer' do
+ find('.filtered-search').click
+
+ expect(page).not_to have_button('Reviewer')
+ end
+ end
+
describe 'filter issues by label' do
context 'only label' do
it 'filters issues by searched label' do
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 06f79f94e8d..07bf821a590 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -418,6 +418,46 @@ RSpec.describe 'GFM autocomplete', :js do
end
end
+ context 'when other notes are destroyed' do
+ let!(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: issue.project) }
+
+ # This is meant to protect against this issue https://gitlab.com/gitlab-org/gitlab/-/issues/228729
+ it 'keeps autocomplete key listeners' do
+ visit project_issue_path(project, issue)
+ note = find('#note-body')
+
+ start_comment_with_emoji(note)
+
+ start_and_cancel_discussion
+
+ note.fill_in(with: '')
+ start_comment_with_emoji(note)
+ note.native.send_keys(:enter)
+
+ expect(note.value).to eql('Hello :100: ')
+ end
+
+ def start_comment_with_emoji(note)
+ note.native.send_keys('Hello :10')
+
+ wait_for_requests
+
+ find('.atwho-view li', text: '100')
+ end
+
+ def start_and_cancel_discussion
+ click_button('Reply...')
+
+ fill_in('note_note', with: 'Whoops!')
+
+ page.accept_alert 'Are you sure you want to cancel creating this comment?' do
+ click_button('Cancel')
+ end
+
+ wait_for_requests
+ end
+ end
+
shared_examples 'autocomplete suggestions' do
it 'suggests objects correctly' do
page.within '.timeline-content-form' do
@@ -550,6 +590,15 @@ RSpec.describe 'GFM autocomplete', :js do
expect(find('.tribute-container ul', visible: true)).to have_text('alert milestone')
end
+ it 'does not open autocomplete menu when trigger character is prefixed with text' do
+ page.within '.timeline-content-form' do
+ find('#note-body').native.send_keys('testing')
+ find('#note-body').native.send_keys('@')
+ end
+
+ expect(page).not_to have_selector('.tribute-container', visible: true)
+ end
+
it 'selects the first item for assignee dropdowns' do
page.within '.timeline-content-form' do
find('#note-body').native.send_keys('@')
@@ -618,21 +667,6 @@ RSpec.describe 'GFM autocomplete', :js do
expect(page).to have_selector('.tribute-container', visible: true)
end
- it "does not show dropdown when preceded with a special character" do
- note = find('#note-body')
- page.within '.timeline-content-form' do
- note.native.send_keys("@")
- end
-
- expect(page).to have_selector('.tribute-container', visible: true)
-
- page.within '.timeline-content-form' do
- note.native.send_keys("@")
- end
-
- expect(page).not_to have_selector('.tribute-container')
- end
-
it "does not throw an error if no labels exist" do
note = find('#note-body')
page.within '.timeline-content-form' do
@@ -653,14 +687,6 @@ RSpec.describe 'GFM autocomplete', :js do
expect_to_wrap(false, user_item, note, user.username)
end
- it 'doesn\'t open autocomplete after non-word character' do
- page.within '.timeline-content-form' do
- find('#note-body').native.send_keys("@#{user.username[0..2]}!")
- end
-
- expect(page).not_to have_selector('.tribute-container')
- end
-
it 'triggers autocomplete after selecting a quick action' do
note = find('#note-body')
page.within '.timeline-content-form' do
@@ -848,46 +874,6 @@ RSpec.describe 'GFM autocomplete', :js do
it_behaves_like 'autocomplete suggestions'
end
-
- context 'when other notes are destroyed' do
- let!(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: issue.project) }
-
- # This is meant to protect against this issue https://gitlab.com/gitlab-org/gitlab/-/issues/228729
- it 'keeps autocomplete key listeners' do
- visit project_issue_path(project, issue)
- note = find('#note-body')
-
- start_comment_with_emoji(note)
-
- start_and_cancel_discussion
-
- note.fill_in(with: '')
- start_comment_with_emoji(note)
- note.native.send_keys(:enter)
-
- expect(note.value).to eql('Hello :100: ')
- end
-
- def start_comment_with_emoji(note)
- note.native.send_keys('Hello :10')
-
- wait_for_requests
-
- find('.atwho-view li', text: '100')
- end
-
- def start_and_cancel_discussion
- click_button('Reply...')
-
- fill_in('note_note', with: 'Whoops!')
-
- page.accept_alert 'Are you sure you want to cancel creating this comment?' do
- click_button('Cancel')
- end
-
- wait_for_requests
- end
- end
end
private
diff --git a/spec/features/issues/issue_header_spec.rb b/spec/features/issues/issue_header_spec.rb
new file mode 100644
index 00000000000..cf375d8fb67
--- /dev/null
+++ b/spec/features/issues/issue_header_spec.rb
@@ -0,0 +1,164 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'issue header', :js do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:closed_issue) { create(:issue, :closed, project: project) }
+ let_it_be(:closed_locked_issue) { create(:issue, :closed, :locked, project: project) }
+ let_it_be(:authored_issue) { create(:issue, project: project, author: user) }
+
+ context 'when user has permission to update' do
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ context 'within the issue actions dropdown menu' do
+ before do
+ visit project_issue_path(project, issue)
+
+ # Click on the ellipsis icon
+ click_button 'Issue actions'
+ end
+
+ it 'only shows the "New issue" and "Report abuse" items', :aggregate_failures do
+ expect(page).to have_link 'New issue'
+ expect(page).to have_link 'Report abuse'
+ expect(page).not_to have_link 'Submit as spam'
+ end
+ end
+
+ context 'when the issue is open' do
+ before do
+ visit project_issue_path(project, issue)
+ end
+
+ it 'has a "Close issue" button' do
+ expect(page).to have_button 'Close issue'
+ end
+ end
+
+ context 'when the issue is closed' do
+ before do
+ visit project_issue_path(project, closed_issue)
+ end
+
+ it 'has a "Reopen issue" button' do
+ expect(page).to have_button 'Reopen issue'
+ end
+ end
+
+ context 'when the issue is closed and locked' do
+ before do
+ visit project_issue_path(project, closed_locked_issue)
+ end
+
+ it 'does not have a "Reopen issue" button' do
+ expect(page).not_to have_button 'Reopen issue'
+ end
+ end
+
+ context 'when the current user is the issue author' do
+ before do
+ visit project_issue_path(project, authored_issue)
+ end
+
+ it 'does not show "Report abuse" link in dropdown' do
+ click_button 'Issue actions'
+
+ expect(page).not_to have_link 'Report abuse'
+ end
+ end
+ end
+
+ context 'when user is admin and the project is set up for spam' do
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:user_agent_detail) { create(:user_agent_detail, subject: issue) }
+
+ before do
+ stub_application_setting(akismet_enabled: true)
+ project.add_maintainer(admin)
+ sign_in(admin)
+ end
+
+ context 'within the issue actions dropdown menu' do
+ before do
+ visit project_issue_path(project, issue)
+
+ # Click on the ellipsis icon
+ click_button 'Issue actions'
+ end
+
+ it 'has "Submit as spam" item' do
+ expect(page).to have_link 'Submit as spam'
+ end
+ end
+ end
+
+ context 'when user does not have permission to update' do
+ before do
+ project.add_guest(user)
+ sign_in(user)
+ end
+
+ context 'within the issue actions dropdown menu' do
+ before do
+ visit project_issue_path(project, issue)
+
+ # Click on the ellipsis icon
+ click_button 'Issue actions'
+ end
+
+ it 'only shows the "New issue" and "Report abuse" items', :aggregate_failures do
+ expect(page).to have_link 'New issue'
+ expect(page).to have_link 'Report abuse'
+ expect(page).not_to have_link 'Submit as spam'
+ end
+ end
+
+ context 'when the issue is open' do
+ before do
+ visit project_issue_path(project, issue)
+ end
+
+ it 'does not have a "Close issue" button' do
+ expect(page).not_to have_button 'Close issue'
+ end
+ end
+
+ context 'when the issue is closed' do
+ before do
+ visit project_issue_path(project, closed_issue)
+ end
+
+ it 'does not have a "Reopen issue" button' do
+ expect(page).not_to have_button 'Reopen issue'
+ end
+ end
+
+ context 'when the issue is closed and locked' do
+ before do
+ visit project_issue_path(project, closed_locked_issue)
+ end
+
+ it 'does not have a "Reopen issue" button' do
+ expect(page).not_to have_button 'Reopen issue'
+ end
+ end
+
+ context 'when the current user is the issue author' do
+ before do
+ visit project_issue_path(project, authored_issue)
+ end
+
+ it 'does not show "Report abuse" link in dropdown' do
+ click_button 'Issue actions'
+
+ expect(page).not_to have_link 'Report abuse'
+ end
+ end
+ end
+end
diff --git a/spec/features/issues/issue_state_spec.rb b/spec/features/issues/issue_state_spec.rb
new file mode 100644
index 00000000000..0ef6eb56dff
--- /dev/null
+++ b/spec/features/issues/issue_state_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'issue state', :js do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ shared_examples 'issue closed' do |selector|
+ it 'can close an issue' do
+ expect(find('.status-box')).to have_content 'Open'
+
+ within selector do
+ click_button 'Close issue'
+ end
+
+ expect(find('.status-box')).to have_content 'Closed'
+ end
+ end
+
+ shared_examples 'issue reopened' do |selector|
+ it 'can reopen an issue' do
+ expect(find('.status-box')).to have_content 'Closed'
+
+ within selector do
+ click_button 'Reopen issue'
+ end
+
+ expect(find('.status-box')).to have_content 'Open'
+ end
+ end
+
+ describe 'when open' do
+ context 'when clicking the top `Close issue` button', :aggregate_failures do
+ let(:open_issue) { create(:issue, project: project) }
+
+ before do
+ visit project_issue_path(project, open_issue)
+ end
+
+ it_behaves_like 'issue closed', '.detail-page-header'
+ end
+
+ context 'when clicking the bottom `Close issue` button', :aggregate_failures do
+ let(:open_issue) { create(:issue, project: project) }
+
+ before do
+ visit project_issue_path(project, open_issue)
+ end
+
+ it_behaves_like 'issue closed', '.timeline-content-form'
+ end
+ end
+
+ describe 'when closed' do
+ context 'when clicking the top `Reopen issue` button', :aggregate_failures do
+ let(:closed_issue) { create(:issue, project: project, state: 'closed') }
+
+ before do
+ visit project_issue_path(project, closed_issue)
+ end
+
+ it_behaves_like 'issue reopened', '.detail-page-header'
+ end
+
+ context 'when clicking the bottom `Reopen issue` button', :aggregate_failures do
+ let(:closed_issue) { create(:issue, project: project, state: 'closed') }
+
+ before do
+ visit project_issue_path(project, closed_issue)
+ end
+
+ it_behaves_like 'issue reopened', '.timeline-content-form'
+ end
+ end
+end
diff --git a/spec/features/issues/keyboard_shortcut_spec.rb b/spec/features/issues/keyboard_shortcut_spec.rb
index ab40f124257..502412bab5d 100644
--- a/spec/features/issues/keyboard_shortcut_spec.rb
+++ b/spec/features/issues/keyboard_shortcut_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe 'Issues shortcut', :js do
let(:project) { create(:project) }
before do
- sign_in(create(:admin))
+ sign_in(project.owner)
visit project_path(project)
end
@@ -23,7 +23,7 @@ RSpec.describe 'Issues shortcut', :js do
let(:project) { create(:project, :issues_disabled) }
before do
- sign_in(create(:admin))
+ sign_in(project.owner)
visit project_path(project)
end
diff --git a/spec/features/issuables/related_issues_spec.rb b/spec/features/issues/related_issues_spec.rb
index 837859bbe26..837859bbe26 100644
--- a/spec/features/issuables/related_issues_spec.rb
+++ b/spec/features/issues/related_issues_spec.rb
diff --git a/spec/features/issues/service_desk_spec.rb b/spec/features/issues/service_desk_spec.rb
index 1512d539dec..02804d84a21 100644
--- a/spec/features/issues/service_desk_spec.rb
+++ b/spec/features/issues/service_desk_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
RSpec.describe 'Service Desk Issue Tracker', :js do
let(:project) { create(:project, :private, service_desk_enabled: true) }
- let(:user) { create(:user) }
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:support_bot) { User.support_bot }
before do
# The following two conditions equate to Gitlab::ServiceDesk.supported == true
@@ -27,6 +29,16 @@ RSpec.describe 'Service Desk Issue Tracker', :js do
end
end
+ context 'issue page' do
+ let(:service_desk_issue) { create(:issue, project: project, author: support_bot, service_desk_reply_to: 'service.desk@example.com') }
+
+ it 'shows service_desk_reply_to in issue header' do
+ visit project_issue_path(project, service_desk_issue)
+
+ expect(page).to have_text('by service.desk@example.com via GitLab Support Bot')
+ end
+ end
+
describe 'issues list' do
context 'when service desk is supported' do
context 'when there are no issues' do
@@ -66,10 +78,10 @@ RSpec.describe 'Service Desk Issue Tracker', :js do
end
context 'when there are issues' do
- let(:support_bot) { User.support_bot }
- let(:other_user) { create(:user) }
- let!(:service_desk_issue) { create(:issue, project: project, author: support_bot) }
- let!(:other_user_issue) { create(:issue, project: project, author: other_user) }
+ let_it_be(:project) { create(:project, :private, service_desk_enabled: true) }
+ let_it_be(:other_user) { create(:user) }
+ let_it_be(:service_desk_issue) { create(:issue, project: project, author: support_bot, service_desk_reply_to: 'service.desk@example.com') }
+ let_it_be(:other_user_issue) { create(:issue, project: project, author: other_user) }
describe 'service desk info content' do
before do
@@ -94,6 +106,10 @@ RSpec.describe 'Service Desk Issue Tracker', :js do
it 'only displays issues created by support bot' do
expect(page).to have_selector('.issues-list .issue', count: 1)
end
+
+ it 'shows service_desk_reply_to in issues list' do
+ expect(page).to have_text('by service.desk@example.com via GitLab Support Bot')
+ end
end
describe 'search box' do
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index 11b905735de..9d4a6cdb522 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -22,6 +22,7 @@ RSpec.describe "Issues > User edits issue", :js do
context "from edit page" do
before do
+ stub_licensed_features(multiple_issue_assignees: false)
visit edit_project_issue_path(project, issue)
end
diff --git a/spec/features/issues/user_uses_quick_actions_spec.rb b/spec/features/issues/user_uses_quick_actions_spec.rb
index c5eb3f415ff..d88b816b186 100644
--- a/spec/features/issues/user_uses_quick_actions_spec.rb
+++ b/spec/features/issues/user_uses_quick_actions_spec.rb
@@ -43,5 +43,6 @@ RSpec.describe 'Issues > User uses quick actions', :js do
it_behaves_like 'create_merge_request quick action'
it_behaves_like 'move quick action'
it_behaves_like 'zoom quick actions'
+ it_behaves_like 'clone quick action'
end
end
diff --git a/spec/features/issues/user_views_issue_spec.rb b/spec/features/issues/user_views_issue_spec.rb
index 4128f3478bb..8792d76981f 100644
--- a/spec/features/issues/user_views_issue_spec.rb
+++ b/spec/features/issues/user_views_issue_spec.rb
@@ -13,8 +13,6 @@ RSpec.describe "User views issue" do
end
before do
- stub_feature_flags(vue_issue_header: false)
-
sign_in(user)
visit(project_issue_path(project, issue))
@@ -24,10 +22,12 @@ RSpec.describe "User views issue" do
it_behaves_like 'page meta description', ' Description header Lorem ipsum dolor sit amet'
- it 'shows the merge request and issue actions', :aggregate_failures do
- expect(page).to have_link('New issue')
+ it 'shows the merge request and issue actions', :js, :aggregate_failures do
+ click_button 'Issue actions'
+
+ expect(page).to have_link('New issue', href: new_project_issue_path(project))
expect(page).to have_button('Create merge request')
- expect(page).to have_link('Close issue')
+ expect(page).to have_button('Close issue')
end
context 'when the project is archived' do
diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb
index fbf4e531db1..c9dc764f93b 100644
--- a/spec/features/markdown/copy_as_gfm_spec.rb
+++ b/spec/features/markdown/copy_as_gfm_spec.rb
@@ -7,10 +7,6 @@ RSpec.describe 'Copy as GFM', :js do
include RepoHelpers
include ActionView::Helpers::JavaScriptHelper
- before do
- sign_in(create(:admin))
- end
-
describe 'Copying rendered GFM' do
before do
@feat = MarkdownFeature.new
@@ -18,6 +14,9 @@ RSpec.describe 'Copy as GFM', :js do
# `markdown` helper expects a `@project` variable
@project = @feat.project
+ user = create(:user)
+ @project.add_maintainer(user)
+ sign_in(user)
visit project_issue_path(@project, @feat.issue)
end
@@ -650,6 +649,10 @@ RSpec.describe 'Copy as GFM', :js do
describe 'Copying code' do
let(:project) { create(:project, :repository) }
+ before do
+ sign_in(project.owner)
+ end
+
context 'from a diff' do
shared_examples 'copying code from a diff' do
context 'selecting one word of text' do
diff --git a/spec/features/markdown/mermaid_spec.rb b/spec/features/markdown/mermaid_spec.rb
index 58314a49c4b..23cdd9d2ce5 100644
--- a/spec/features/markdown/mermaid_spec.rb
+++ b/spec/features/markdown/mermaid_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe 'Mermaid rendering', :js do
expect(page.html.scan(expected).count).to be(4)
end
- it 'renders only 2 Mermaid blocks and ', :js, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/234081' } do
+ it 'renders only 2 Mermaid blocks and', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/234081' do
description = <<~MERMAID
```mermaid
graph LR
@@ -78,7 +78,7 @@ RSpec.describe 'Mermaid rendering', :js do
end
end
- it 'correctly sizes mermaid diagram inside <details> block', :js do
+ it 'correctly sizes mermaid diagram inside <details> block' do
description = <<~MERMAID
<details>
<summary>Click to show diagram</summary>
@@ -112,7 +112,7 @@ RSpec.describe 'Mermaid rendering', :js do
end
end
- it 'correctly sizes mermaid diagram block', :js do
+ it 'correctly sizes mermaid diagram block' do
description = <<~MERMAID
```mermaid
graph TD;
@@ -134,7 +134,7 @@ RSpec.describe 'Mermaid rendering', :js do
expect(page).to have_css('svg.mermaid[style*="max-width"][width="100%"]')
end
- it 'display button when diagram exceeds length', :js do
+ it 'display button when diagram exceeds length', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/287806' do
graph_edges = "A-->B;B-->A;" * 420
description = <<~MERMAID
diff --git a/spec/features/issuables/close_reopen_report_toggle_spec.rb b/spec/features/merge_request/close_reopen_report_toggle_spec.rb
index 867d2ff7aae..8a4277d87c9 100644
--- a/spec/features/issuables/close_reopen_report_toggle_spec.rb
+++ b/spec/features/merge_request/close_reopen_report_toggle_spec.rb
@@ -7,51 +7,10 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle' do
let(:user) { create(:user) }
- before do
- stub_feature_flags(vue_issue_header: false)
- end
-
- shared_examples 'an issuable close/reopen/report toggle' do
- let(:container) { find('.issuable-close-dropdown') }
- let(:human_model_name) { issuable.model_name.human.downcase }
-
- it 'shows toggle' do
- expect(page).to have_button("Close #{human_model_name}")
- expect(page).to have_selector('.issuable-close-dropdown')
- end
-
- it 'opens a dropdown when toggle is clicked' do
- container.find('.dropdown-toggle').click
-
- expect(container).to have_selector('.dropdown-menu')
- expect(container).to have_content("Close #{human_model_name}")
- expect(container).to have_content('Report abuse')
- expect(container).to have_content("Report #{human_model_name.pluralize} that are abusive, inappropriate or spam.")
-
- if issuable.is_a?(MergeRequest)
- page.within('.js-issuable-close-dropdown') do
- expect(page).to have_link('Close merge request')
- end
- else
- expect(container).to have_selector('.close-item.droplab-item-selected')
- end
-
- expect(container).to have_selector('.report-item')
- expect(container).not_to have_selector('.report-item.droplab-item-selected')
- expect(container).not_to have_selector('.reopen-item')
- end
-
- it 'links to Report Abuse' do
- container.find('.dropdown-toggle').click
- container.find('.report-abuse-link').click
-
- expect(page).to have_content('Report abuse to admin')
- end
- end
-
- context 'on an issue' do
- let(:project) { create(:project) }
- let(:issuable) { create(:issue, project: project) }
+ context 'on a merge request' do
+ let(:container) { find('.detail-page-header-actions') }
+ let(:project) { create(:project, :repository) }
+ let(:issuable) { create(:merge_request, source_project: project) }
before do
project.add_maintainer(user)
@@ -60,67 +19,38 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle' do
context 'when user has permission to update', :js do
before do
- visit project_issue_path(project, issuable)
+ visit project_merge_request_path(project, issuable)
end
- it_behaves_like 'an issuable close/reopen/report toggle'
-
- context 'when the issue is closed and locked' do
- let(:issuable) { create(:issue, :closed, :locked, project: project) }
+ context 'close/reopen/report toggle' do
+ it 'opens a dropdown when toggle is clicked' do
+ click_button 'Toggle dropdown'
- it 'hides the reopen button' do
- expect(page).not_to have_button('Reopen issue')
+ expect(container).to have_link("Close merge request")
+ expect(container).to have_link('Report abuse')
+ expect(container).to have_text("Report merge requests that are abusive, inappropriate or spam.")
end
- context 'when the issue author is the current user' do
- before do
- issuable.update(author: user)
- end
+ it 'links to Report Abuse' do
+ click_button 'Toggle dropdown'
+ click_link 'Report abuse'
- it 'hides the reopen button' do
- expect(page).not_to have_button('Reopen issue')
- end
+ expect(page).to have_content('Report abuse to admin')
end
end
- end
-
- context 'when user doesnt have permission to update' do
- let(:cant_project) { create(:project) }
- let(:cant_issuable) { create(:issue, project: cant_project) }
-
- before do
- cant_project.add_guest(user)
-
- visit project_issue_path(cant_project, cant_issuable)
- end
-
- it 'only shows the `Report abuse` and `New issue` buttons' do
- expect(page).to have_link('Report abuse')
- expect(page).to have_link('New issue')
- expect(page).not_to have_button('Close issue')
- expect(page).not_to have_button('Reopen issue')
- expect(page).not_to have_link(title: 'Edit title and description')
- end
- end
- end
-
- context 'on a merge request' do
- let(:container) { find('.detail-page-header-actions') }
- let(:project) { create(:project, :repository) }
- let(:issuable) { create(:merge_request, source_project: project) }
- before do
- project.add_maintainer(user)
- login_as user
- end
+ context 'when the merge request is open' do
+ let(:issuable) { create(:merge_request, :opened, source_project: project) }
- context 'when user has permission to update', :js do
- before do
- visit project_merge_request_path(project, issuable)
+ it 'shows the `Edit` and `Mark as draft` buttons' do
+ expect(container).to have_link('Edit')
+ expect(container).to have_link('Mark as draft')
+ expect(container).not_to have_button('Report abuse')
+ expect(container).not_to have_button('Close merge request')
+ expect(container).not_to have_link('Reopen merge request')
+ end
end
- it_behaves_like 'an issuable close/reopen/report toggle'
-
context 'when the merge request is closed' do
let(:issuable) { create(:merge_request, :closed, source_project: project) }
diff --git a/spec/features/issuables/merge_request_discussion_lock_spec.rb b/spec/features/merge_request/merge_request_discussion_lock_spec.rb
index 4e0265839f6..4e0265839f6 100644
--- a/spec/features/issuables/merge_request_discussion_lock_spec.rb
+++ b/spec/features/merge_request/merge_request_discussion_lock_spec.rb
diff --git a/spec/features/merge_request/user_closes_merge_request_spec.rb b/spec/features/merge_request/user_closes_merge_request_spec.rb
deleted file mode 100644
index e6b6778c76e..00000000000
--- a/spec/features/merge_request/user_closes_merge_request_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'User closes a merge requests', :js do
- let(:project) { create(:project, :repository) }
- let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
- let(:user) { create(:user) }
-
- before do
- project.add_maintainer(user)
- sign_in(user)
-
- visit(merge_request_path(merge_request))
- end
-
- it 'closes a merge request' do
- click_button('Close merge request', match: :first)
-
- expect(page).to have_content(merge_request.title)
- expect(page).to have_content('Closed by')
- end
-end
diff --git a/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb b/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb
new file mode 100644
index 00000000000..6376f9ab5fd
--- /dev/null
+++ b/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User closes/reopens a merge request', :js do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ describe 'when open' do
+ context 'when clicking the top `Close merge request` link', :aggregate_failures do
+ let(:open_merge_request) { create(:merge_request, source_project: project, target_project: project) }
+
+ before do
+ visit merge_request_path(open_merge_request)
+ end
+
+ it 'can close a merge request' do
+ expect(find('.status-box')).to have_content 'Open'
+
+ within '.detail-page-header' do
+ click_button 'Toggle dropdown'
+ click_link 'Close merge request'
+ end
+
+ wait_for_requests
+
+ expect(find('.status-box')).to have_content 'Closed'
+ end
+ end
+
+ context 'when clicking the bottom `Close merge request` button', :aggregate_failures do
+ let(:open_merge_request) { create(:merge_request, source_project: project, target_project: project) }
+
+ before do
+ visit merge_request_path(open_merge_request)
+ end
+
+ it 'can close a merge request' do
+ expect(find('.status-box')).to have_content 'Open'
+
+ within '.timeline-content-form' do
+ click_button 'Close merge request'
+
+ # Clicking the bottom `Close merge request` button does not yet update
+ # the header status so for now we'll check that the button text changes
+ expect(page).not_to have_button 'Close merge request'
+ expect(page).to have_button 'Reopen merge request'
+ end
+ end
+ end
+ end
+
+ describe 'when closed' do
+ context 'when clicking the top `Reopen merge request` link', :aggregate_failures do
+ let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') }
+
+ before do
+ visit merge_request_path(closed_merge_request)
+ end
+
+ it 'can reopen a merge request' do
+ expect(find('.status-box')).to have_content 'Closed'
+
+ within '.detail-page-header' do
+ click_button 'Toggle dropdown'
+ click_link 'Reopen merge request'
+ end
+
+ wait_for_requests
+
+ expect(find('.status-box')).to have_content 'Open'
+ end
+ end
+
+ context 'when clicking the bottom `Reopen merge request` button', :aggregate_failures do
+ let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') }
+
+ before do
+ visit merge_request_path(closed_merge_request)
+ end
+
+ it 'can reopen a merge request' do
+ expect(find('.status-box')).to have_content 'Closed'
+
+ within '.timeline-content-form' do
+ click_button 'Reopen merge request'
+
+ # Clicking the bottom `Reopen merge request` button does not yet update
+ # the header status so for now we'll check that the button text changes
+ expect(page).not_to have_button 'Reopen merge request'
+ expect(page).to have_button 'Close merge request'
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb
index c452408cff2..0fd140a00bd 100644
--- a/spec/features/merge_request/user_comments_on_diff_spec.rb
+++ b/spec/features/merge_request/user_comments_on_diff_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe 'User comments on a diff', :js do
click_button('Add comment now')
end
- page.within('.diff-files-holder > div:nth-child(3)') do
+ page.within('.diff-files-holder > div:nth-child(6)') do
expect(page).to have_content('Line is wrong')
find('.js-diff-more-actions').click
@@ -53,7 +53,7 @@ RSpec.describe 'User comments on a diff', :js do
wait_for_requests
- page.within('.diff-files-holder > div:nth-child(2) .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(5) .note-body > .note-text') do
expect(page).to have_content('Line is correct')
end
@@ -67,7 +67,7 @@ RSpec.describe 'User comments on a diff', :js do
wait_for_requests
# Hide the comment.
- page.within('.diff-files-holder > div:nth-child(3)') do
+ page.within('.diff-files-holder > div:nth-child(6)') do
find('.js-diff-more-actions').click
click_button 'Hide comments on this file'
@@ -76,22 +76,22 @@ RSpec.describe 'User comments on a diff', :js do
# At this moment a user should see only one comment.
# The other one should be hidden.
- page.within('.diff-files-holder > div:nth-child(2) .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(5) .note-body > .note-text') do
expect(page).to have_content('Line is correct')
end
# Show the comment.
- page.within('.diff-files-holder > div:nth-child(3)') do
+ page.within('.diff-files-holder > div:nth-child(6)') do
find('.js-diff-more-actions').click
click_button 'Show comments on this file'
end
# Now both the comments should be shown.
- page.within('.diff-files-holder > div:nth-child(3) .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(6) .note-body > .note-text') do
expect(page).to have_content('Line is wrong')
end
- page.within('.diff-files-holder > div:nth-child(2) .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(5) .note-body > .note-text') do
expect(page).to have_content('Line is correct')
end
@@ -102,11 +102,11 @@ RSpec.describe 'User comments on a diff', :js do
wait_for_requests
- page.within('.diff-files-holder > div:nth-child(3) .parallel .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(6) .parallel .note-body > .note-text') do
expect(page).to have_content('Line is wrong')
end
- page.within('.diff-files-holder > div:nth-child(2) .parallel .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(5) .parallel .note-body > .note-text') do
expect(page).to have_content('Line is correct')
end
end
@@ -136,7 +136,7 @@ RSpec.describe 'User comments on a diff', :js do
add_comment('-13', '+15')
end
- it 'allows comments on previously hidden lines at the top of a file' do
+ it 'allows comments on previously hidden lines at the top of a file', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/285294' do
# Click -9, expand up, select 1 add and verify comment
page.within('[data-path="files/ruby/popen.rb"]') do
all('.js-unfold-all')[0].click
@@ -204,7 +204,7 @@ RSpec.describe 'User comments on a diff', :js do
click_button('Add comment now')
end
- page.within('.diff-file:nth-of-type(5) .discussion .note') do
+ page.within('.diff-file:nth-of-type(1) .discussion .note') do
find('.js-note-edit').click
page.within('.current-note-edit-form') do
@@ -215,7 +215,7 @@ RSpec.describe 'User comments on a diff', :js do
expect(page).not_to have_button('Save comment', disabled: true)
end
- page.within('.diff-file:nth-of-type(5) .discussion .note') do
+ page.within('.diff-file:nth-of-type(1) .discussion .note') do
expect(page).to have_content('Typo, please fix').and have_no_content('Line is wrong')
end
end
@@ -234,7 +234,7 @@ RSpec.describe 'User comments on a diff', :js do
expect(page).to have_content('1')
end
- page.within('.diff-file:nth-of-type(5) .discussion .note') do
+ page.within('.diff-file:nth-of-type(1) .discussion .note') do
find('.more-actions').click
find('.more-actions .dropdown-menu li', match: :first)
diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb
index 9556142ecb8..794dfd7c8da 100644
--- a/spec/features/merge_request/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb
@@ -74,7 +74,10 @@ RSpec.describe 'Merge request > User posts diff notes', :js do
context 'with an unfolded line' do
before do
- find('.js-unfold', match: :first).click
+ page.within('.file-holder[id="a5cc2925ca8258af241be7e5b0381edf30266302"]') do
+ find('.js-unfold', match: :first).click
+ end
+
wait_for_requests
end
@@ -137,7 +140,10 @@ RSpec.describe 'Merge request > User posts diff notes', :js do
context 'with an unfolded line' do
before do
- find('.js-unfold', match: :first).click
+ page.within('.file-holder[id="a5cc2925ca8258af241be7e5b0381edf30266302"]') do
+ find('.js-unfold', match: :first).click
+ end
+
wait_for_requests
end
diff --git a/spec/features/merge_request/user_reopens_merge_request_spec.rb b/spec/features/merge_request/user_reopens_merge_request_spec.rb
deleted file mode 100644
index 4a05a3be59a..00000000000
--- a/spec/features/merge_request/user_reopens_merge_request_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'User reopens a merge requests', :js do
- let(:project) { create(:project, :public, :repository) }
- let!(:merge_request) { create(:closed_merge_request, source_project: project, target_project: project) }
- let(:user) { create(:user) }
-
- before do
- project.add_maintainer(user)
- sign_in(user)
-
- visit(merge_request_path(merge_request))
- end
-
- it 'reopens a merge request' do
- find('.js-issuable-close-dropdown .dropdown-toggle').click
-
- click_link('Reopen merge request', match: :first)
-
- wait_for_requests
-
- page.within('.status-box') do
- expect(page).to have_content('Open')
- end
- end
-end
diff --git a/spec/features/merge_request/user_resolves_conflicts_spec.rb b/spec/features/merge_request/user_resolves_conflicts_spec.rb
index 06405232462..1b1152897fc 100644
--- a/spec/features/merge_request/user_resolves_conflicts_spec.rb
+++ b/spec/features/merge_request/user_resolves_conflicts_spec.rb
@@ -8,11 +8,6 @@ RSpec.describe 'Merge request > User resolves conflicts', :js do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
- before do
- # In order to have the diffs collapsed, we need to disable the increase feature
- stub_feature_flags(gitlab_git_diff_size_limit_increase: false)
- end
-
def create_merge_request(source_branch)
create(:merge_request, source_branch: source_branch, target_branch: 'conflict-start', source_project: project, merge_status: :unchecked) do |mr|
mr.mark_as_unmergeable
diff --git a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
index 00f0c88497b..cb7c952dfe4 100644
--- a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
+++ b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
@@ -111,7 +111,6 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'shows resolved thread when toggled' do
find(".timeline-content .discussion[data-discussion-id='#{note.discussion_id}'] .discussion-toggle-button").click
- expect(page.find(".line-holder-placeholder")).to be_visible
expect(page.find(".timeline-content #note_#{note.id}")).to be_visible
end
diff --git a/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb b/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb
index e47f9ff2660..38546fd629d 100644
--- a/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb
+++ b/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb
@@ -18,8 +18,8 @@ RSpec.describe 'Merge request > User sees check out branch modal', :js do
expect(page).to have_content('Check out, review, and merge locally')
end
- it 'closes the check out branch modal with escape keypress' do
- find('#modal_merge_info').send_keys(:escape)
+ it 'closes the check out branch modal with the close action' do
+ find('.modal button[aria-label="Close"]').click
expect(page).not_to have_content('Check out, review, and merge locally')
end
diff --git a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
index 7b319f6aff8..6647a4e9291 100644
--- a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
@@ -27,7 +27,6 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
before do
stub_application_setting(auto_devops_enabled: false)
- stub_feature_flags(ci_merge_request_pipeline: true)
stub_ci_pipeline_yaml_file(YAML.dump(config))
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb
index fb616ceae9d..8930c55a28c 100644
--- a/spec/features/merge_request/user_sees_versions_spec.rb
+++ b/spec/features/merge_request/user_sees_versions_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
let!(:params) { {} }
before do
+ stub_feature_flags(diffs_gradual_load: false)
+
project.add_maintainer(user)
sign_in(user)
visit diffs_project_merge_request_path(project, merge_request, params)
@@ -73,12 +75,12 @@ RSpec.describe 'Merge request > User sees versions', :js do
it 'shows the commit SHAs for every version in the dropdown' do
page.within '.mr-version-dropdown' do
- find('.btn-default').click
+ find('.gl-dropdown-toggle').click
+ end
- page.within('.dropdown-content') do
- shas = merge_request.merge_request_diffs.map { |diff| Commit.truncate_sha(diff.head_commit_sha) }
- shas.each { |sha| expect(page).to have_content(sha) }
- end
+ page.within '.mr-version-dropdown' do
+ shas = merge_request.merge_request_diffs.map { |diff| Commit.truncate_sha(diff.head_commit_sha) }
+ shas.each { |sha| expect(page).to have_content(sha) }
end
end
@@ -182,7 +184,7 @@ RSpec.describe 'Merge request > User sees versions', :js do
it 'has 0 chages between versions' do
page.within '.mr-version-compare-dropdown' do
- expect(find('.dropdown-menu-toggle')).to have_content 'version 1'
+ expect(find('.gl-dropdown-toggle')).to have_content 'version 1'
end
page.within '.mr-version-dropdown' do
@@ -203,7 +205,7 @@ RSpec.describe 'Merge request > User sees versions', :js do
it 'sets the compared versions to be the same' do
page.within '.mr-version-compare-dropdown' do
- expect(find('.dropdown-menu-toggle')).to have_content 'version 2'
+ expect(find('.gl-dropdown-toggle')).to have_content 'version 2'
end
page.within '.mr-version-dropdown' do
diff --git a/spec/features/merge_requests/user_squashes_merge_request_spec.rb b/spec/features/merge_request/user_squashes_merge_request_spec.rb
index 84964bd0637..84964bd0637 100644
--- a/spec/features/merge_requests/user_squashes_merge_request_spec.rb
+++ b/spec/features/merge_request/user_squashes_merge_request_spec.rb
diff --git a/spec/features/merge_requests/user_views_diffs_commit_spec.rb b/spec/features/merge_request/user_views_diffs_commit_spec.rb
index cf92603972e..cf92603972e 100644
--- a/spec/features/merge_requests/user_views_diffs_commit_spec.rb
+++ b/spec/features/merge_request/user_views_diffs_commit_spec.rb
diff --git a/spec/features/merge_request/user_views_diffs_file_by_file_spec.rb b/spec/features/merge_request/user_views_diffs_file_by_file_spec.rb
index bb4bf0864c9..ad9c342df3e 100644
--- a/spec/features/merge_request/user_views_diffs_file_by_file_spec.rb
+++ b/spec/features/merge_request/user_views_diffs_file_by_file_spec.rb
@@ -23,12 +23,12 @@ RSpec.describe 'User views diffs file-by-file', :js do
it 'shows diffs file-by-file' do
page.within('#diffs') do
expect(page).to have_selector('.file-holder', count: 1)
- expect(page).to have_selector('.diff-file .file-title', text: '.DS_Store')
+ expect(page).to have_selector('.diff-file .file-title', text: 'files/ruby/popen.rb')
find('.page-link.next-page-item').click
expect(page).to have_selector('.file-holder', count: 1)
- expect(page).to have_selector('.diff-file .file-title', text: '.gitignore')
+ expect(page).to have_selector('.diff-file .file-title', text: 'files/ruby/regex.rb')
end
end
end
diff --git a/spec/features/merge_request/user_views_diffs_spec.rb b/spec/features/merge_request/user_views_diffs_spec.rb
index e1865fe2e14..a0b3067994c 100644
--- a/spec/features/merge_request/user_views_diffs_spec.rb
+++ b/spec/features/merge_request/user_views_diffs_spec.rb
@@ -22,8 +22,8 @@ RSpec.describe 'User views diffs', :js do
it 'unfolds diffs upwards' do
first('.js-unfold').click
- page.within('.file-holder[id="a5cc2925ca8258af241be7e5b0381edf30266302"]') do
- expect(find('.text-file')).to have_content('.bundle')
+ page.within('.file-holder[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd"]') do
+ expect(find('.text-file')).to have_content('fileutils')
expect(page).to have_selector('.new_line [data-linenumber="1"]', count: 1)
end
end
diff --git a/spec/features/merge_request/user_sees_empty_state_spec.rb b/spec/features/merge_requests/user_sees_empty_state_spec.rb
index ac07b31731d..ac07b31731d 100644
--- a/spec/features/merge_request/user_sees_empty_state_spec.rb
+++ b/spec/features/merge_requests/user_sees_empty_state_spec.rb
diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb
index dce76e4df6d..b9594293996 100644
--- a/spec/features/milestone_spec.rb
+++ b/spec/features/milestone_spec.rb
@@ -101,7 +101,7 @@ RSpec.describe 'Milestone' do
end
describe 'Deleting a milestone' do
- it "The delete milestone button does not show for unauthorized users" do
+ it "the delete milestone button does not show for unauthorized users" do
create(:milestone, project: project, title: 8.7)
sign_out(user)
diff --git a/spec/features/operations_sidebar_link_spec.rb b/spec/features/operations_sidebar_link_spec.rb
index 32e2833dafb..798f9092db0 100644
--- a/spec/features/operations_sidebar_link_spec.rb
+++ b/spec/features/operations_sidebar_link_spec.rb
@@ -2,31 +2,88 @@
require 'spec_helper'
-RSpec.describe 'Operations dropdown sidebar' do
- let_it_be(:project) { create(:project, :repository) }
+RSpec.describe 'Operations dropdown sidebar', :aggregate_failures do
+ let_it_be_with_reload(:project) { create(:project, :internal, :repository) }
let(:user) { create(:user) }
+ let(:access_level) { ProjectFeature::PUBLIC }
+ let(:role) { nil }
before do
- project.add_role(user, role)
+ project.add_role(user, role) if role
+ project.project_feature.update_attribute(:operations_access_level, access_level)
+
sign_in(user)
visit project_issues_path(project)
end
+ shared_examples 'shows Operations menu based on the access level' do
+ context 'when operations project feature is PRIVATE' do
+ let(:access_level) { ProjectFeature::PRIVATE }
+
+ it 'shows the `Operations` menu' do
+ expect(page).to have_selector('a.shortcuts-operations', text: 'Operations')
+ end
+ end
+
+ context 'when operations project feature is DISABLED' do
+ let(:access_level) { ProjectFeature::DISABLED }
+
+ it 'does not show the `Operations` menu' do
+ expect(page).not_to have_selector('a.shortcuts-operations')
+ end
+ end
+ end
+
+ context 'user is not a member' do
+ it 'has the correct `Operations` menu items', :aggregate_failures do
+ expect(page).to have_selector('a.shortcuts-operations', text: 'Operations')
+ expect(page).to have_link(title: 'Incidents', href: project_incidents_path(project))
+ expect(page).to have_link(title: 'Environments', href: project_environments_path(project))
+
+ expect(page).not_to have_link(title: 'Metrics', href: project_metrics_dashboard_path(project))
+ expect(page).not_to have_link(title: 'Alerts', href: project_alert_management_index_path(project))
+ expect(page).not_to have_link(title: 'Error Tracking', href: project_error_tracking_index_path(project))
+ expect(page).not_to have_link(title: 'Product Analytics', href: project_product_analytics_path(project))
+ expect(page).not_to have_link(title: 'Serverless', href: project_serverless_functions_path(project))
+ expect(page).not_to have_link(title: 'Logs', href: project_logs_path(project))
+ expect(page).not_to have_link(title: 'Kubernetes', href: project_clusters_path(project))
+ end
+
+ context 'when operations project feature is PRIVATE' do
+ let(:access_level) { ProjectFeature::PRIVATE }
+
+ it 'does not show the `Operations` menu' do
+ expect(page).not_to have_selector('a.shortcuts-operations')
+ end
+ end
+
+ context 'when operations project feature is DISABLED' do
+ let(:access_level) { ProjectFeature::DISABLED }
+
+ it 'does not show the `Operations` menu' do
+ expect(page).not_to have_selector('a.shortcuts-operations')
+ end
+ end
+ end
+
context 'user has guest role' do
let(:role) { :guest }
it 'has the correct `Operations` menu items' do
+ expect(page).to have_selector('a.shortcuts-operations', text: 'Operations')
expect(page).to have_link(title: 'Incidents', href: project_incidents_path(project))
+ expect(page).to have_link(title: 'Environments', href: project_environments_path(project))
expect(page).not_to have_link(title: 'Metrics', href: project_metrics_dashboard_path(project))
expect(page).not_to have_link(title: 'Alerts', href: project_alert_management_index_path(project))
- expect(page).not_to have_link(title: 'Environments', href: project_environments_path(project))
expect(page).not_to have_link(title: 'Error Tracking', href: project_error_tracking_index_path(project))
expect(page).not_to have_link(title: 'Product Analytics', href: project_product_analytics_path(project))
expect(page).not_to have_link(title: 'Serverless', href: project_serverless_functions_path(project))
expect(page).not_to have_link(title: 'Logs', href: project_logs_path(project))
expect(page).not_to have_link(title: 'Kubernetes', href: project_clusters_path(project))
end
+
+ it_behaves_like 'shows Operations menu based on the access level'
end
context 'user has reporter role' do
@@ -44,6 +101,8 @@ RSpec.describe 'Operations dropdown sidebar' do
expect(page).not_to have_link(title: 'Logs', href: project_logs_path(project))
expect(page).not_to have_link(title: 'Kubernetes', href: project_clusters_path(project))
end
+
+ it_behaves_like 'shows Operations menu based on the access level'
end
context 'user has developer role' do
@@ -61,6 +120,8 @@ RSpec.describe 'Operations dropdown sidebar' do
expect(page).not_to have_link(title: 'Serverless', href: project_serverless_functions_path(project))
expect(page).not_to have_link(title: 'Kubernetes', href: project_clusters_path(project))
end
+
+ it_behaves_like 'shows Operations menu based on the access level'
end
context 'user has maintainer role' do
@@ -77,5 +138,7 @@ RSpec.describe 'Operations dropdown sidebar' do
expect(page).to have_link(title: 'Logs', href: project_logs_path(project))
expect(page).to have_link(title: 'Kubernetes', href: project_clusters_path(project))
end
+
+ it_behaves_like 'shows Operations menu based on the access level'
end
end
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index 62d8a96c1b2..2e8d9ef80cd 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -78,14 +78,14 @@ RSpec.describe 'Profile > Account', :js do
update_username(new_username)
visit new_project_path
expect(current_path).to eq(new_project_path)
- expect(find('.breadcrumbs-sub-title')).to have_content('Details')
+ expect(find('.breadcrumbs')).to have_content(user.name)
end
it 'the old project path redirects to the new path' do
update_username(new_username)
visit old_project_path
expect(current_path).to eq(new_project_path)
- expect(find('.breadcrumbs-sub-title')).to have_content('Details')
+ expect(find('.breadcrumbs')).to have_content(user.name)
end
end
end
diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb
index 75531d43df2..fd64704b7c8 100644
--- a/spec/features/profiles/active_sessions_spec.rb
+++ b/spec/features/profiles/active_sessions_spec.rb
@@ -11,8 +11,8 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
let(:admin) { create(:admin) }
- it 'User sees their active sessions' do
- Timecop.freeze(Time.zone.parse('2018-03-12 09:06')) do
+ it 'user sees their active sessions' do
+ travel_to(Time.zone.parse('2018-03-12 09:06')) do
Capybara::Session.new(:session1)
Capybara::Session.new(:session2)
Capybara::Session.new(:session3)
@@ -45,6 +45,7 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
)
gitlab_sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
visit admin_user_path(user)
@@ -55,8 +56,8 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
visit profile_active_sessions_path
expect(page).to(
- have_selector('ul.list-group li.list-group-item', { text: 'Signed in on',
- count: 2 }))
+ have_selector('ul.list-group li.list-group-item', text: 'Signed in on',
+ count: 2))
expect(page).to have_content(
'127.0.0.1 ' \
@@ -81,7 +82,7 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
end
end
- it 'User can revoke a session', :js do
+ it 'user can revoke a session', :js do
Capybara::Session.new(:session1)
Capybara::Session.new(:session2)
diff --git a/spec/features/profiles/emails_spec.rb b/spec/features/profiles/emails_spec.rb
index fc7de6d8b23..bdf1f8b022a 100644
--- a/spec/features/profiles/emails_spec.rb
+++ b/spec/features/profiles/emails_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'Profile > Emails' do
end
end
- it 'User removes email' do
+ it 'user removes email' do
user.emails.create(email: 'my@email.com')
visit profile_emails_path
expect(page).to have_content("my@email.com")
@@ -51,7 +51,7 @@ RSpec.describe 'Profile > Emails' do
expect(page).not_to have_content("my@email.com")
end
- it 'User confirms email' do
+ it 'user confirms email' do
email = user.emails.create(email: 'my@email.com')
visit profile_emails_path
expect(page).to have_content("#{email.email} Unverified")
@@ -63,7 +63,7 @@ RSpec.describe 'Profile > Emails' do
expect(page).to have_content("#{email.email} Verified")
end
- it 'User re-sends confirmation email' do
+ it 'user re-sends confirmation email' do
email = user.emails.create(email: 'my@email.com')
visit profile_emails_path
diff --git a/spec/features/profiles/gpg_keys_spec.rb b/spec/features/profiles/gpg_keys_spec.rb
index 18ed4e646b3..4eedeeac262 100644
--- a/spec/features/profiles/gpg_keys_spec.rb
+++ b/spec/features/profiles/gpg_keys_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe 'Profile > GPG Keys' do
end
end
- it 'User sees their key' do
+ it 'user sees their key' do
create(:gpg_key, user: user, key: GpgHelpers::User2.public_key)
visit profile_gpg_keys_path
@@ -45,7 +45,7 @@ RSpec.describe 'Profile > GPG Keys' do
expect(page).to have_content(GpgHelpers::User2.fingerprint)
end
- it 'User removes a key via the key index' do
+ it 'user removes a key via the key index' do
create(:gpg_key, user: user, key: GpgHelpers::User2.public_key)
visit profile_gpg_keys_path
@@ -54,7 +54,7 @@ RSpec.describe 'Profile > GPG Keys' do
expect(page).to have_content('Your GPG keys (0)')
end
- it 'User revokes a key via the key index' do
+ it 'user revokes a key via the key index' do
gpg_key = create :gpg_key, user: user, key: GpgHelpers::User2.public_key
gpg_signature = create :gpg_signature, gpg_key: gpg_key, verification_status: :verified
diff --git a/spec/features/profiles/keys_spec.rb b/spec/features/profiles/keys_spec.rb
index 23bbe9c1587..c1e2d19ad9a 100644
--- a/spec/features/profiles/keys_spec.rb
+++ b/spec/features/profiles/keys_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe 'Profile > SSH Keys' do
end
end
- it 'User sees their keys' do
+ it 'user sees their keys' do
key = create(:key, user: user)
visit profile_keys_path
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index de5a594aca6..88bfc71cfbe 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -18,6 +18,10 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
find("#created-personal-access-token").value
end
+ def feed_token
+ find("#feed_token").value
+ end
+
def disallow_personal_access_token_saves!
allow(PersonalAccessTokens::CreateService).to receive(:new).and_return(pat_create_service)
@@ -112,4 +116,26 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
end
end
end
+
+ describe "feed token" do
+ context "when enabled" do
+ it "displays feed token" do
+ allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false)
+ visit profile_personal_access_tokens_path
+
+ expect(page).to have_content("Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.")
+ expect(feed_token).to eq(user.feed_token)
+ end
+ end
+
+ context "when disabled" do
+ it "does not display feed token" do
+ allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(true)
+ visit profile_personal_access_tokens_path
+
+ expect(page).not_to have_content("Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.")
+ expect(page).not_to have_css("#feed_token")
+ end
+ end
+ end
end
diff --git a/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb b/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
index a5b7b1fba9d..1b6215c1308 100644
--- a/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
+++ b/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Profile > Notifications > User changes notified_of_own_activity
sign_in(user)
end
- it 'User opts into receiving notifications about their own activity' do
+ it 'user opts into receiving notifications about their own activity' do
visit profile_notifications_path
expect(page).not_to have_checked_field('user[notified_of_own_activity]')
@@ -20,7 +20,7 @@ RSpec.describe 'Profile > Notifications > User changes notified_of_own_activity
expect(page).to have_checked_field('user[notified_of_own_activity]')
end
- it 'User opts out of receiving notifications about their own activity' do
+ it 'user opts out of receiving notifications about their own activity' do
user.update!(notified_of_own_activity: true)
visit profile_notifications_path
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index d0340dfc880..239bc04a9cb 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'User edit profile' do
+ include Spec::Support::Helpers::Features::NotesHelpers
+
let(:user) { create(:user) }
before do
@@ -226,7 +228,7 @@ RSpec.describe 'User edit profile' do
end
def open_edit_status_modal
- open_modal 'Edit status'
+ open_modal 'Edit status'
end
def set_user_status_in_modal
@@ -289,6 +291,10 @@ RSpec.describe 'User edit profile' do
toggle_busy_status
set_user_status_in_modal
+
+ wait_for_requests
+ visit root_path(user)
+
open_edit_status_modal
expect(busy_status.checked?).to eq(true)
@@ -366,26 +372,37 @@ RSpec.describe 'User edit profile' do
expect(page).not_to have_selector '.cover-status'
end
- it 'clears the user status with the "Remove status" button' do
- user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread')
+ context 'Remove status button' do
+ before do
+ user.status = UserStatus.new(message: 'Eating bread', emoji: 'stuffed_flatbread')
- visit_user
- wait_for_requests
+ visit_user
+ wait_for_requests
- within('.cover-status') do
- expect(page).to have_emoji(user_status.emoji)
- expect(page).to have_content user_status.message
+ open_edit_status_modal
+
+ page.within "#set-user-status-modal" do
+ click_button 'Remove status'
+ end
+
+ wait_for_requests
end
- open_edit_status_modal
+ it 'clears the user status with the "Remove status" button' do
+ visit_user
- page.within "#set-user-status-modal" do
- click_button 'Remove status'
+ expect(page).not_to have_selector '.cover-status'
end
- visit_user
+ it 'shows the "Set status" menu item in the user menu' do
+ visit root_path(user)
- expect(page).not_to have_selector '.cover-status'
+ find('.header-user-dropdown-toggle').click
+
+ page.within ".header-user" do
+ expect(page).to have_content('Set status')
+ end
+ end
end
it 'displays a default emoji if only message is entered' do
@@ -398,6 +415,45 @@ RSpec.describe 'User edit profile' do
end
end
+ context 'note header' do
+ let(:project) { create(:project_empty_repo, :public) }
+ let(:issue) { create(:issue, project: project) }
+ let(:emoji) { "stuffed_flatbread" }
+
+ before do
+ project.add_guest(user)
+ create(:user_status, user: user, message: 'Taking notes', emoji: emoji)
+
+ visit(project_issue_path(project, issue))
+
+ add_note("This is a comment")
+ visit(project_issue_path(project, issue))
+
+ wait_for_requests
+ end
+
+ it 'displays the status emoji' do
+ first_note = page.find_all(".main-notes-list .timeline-entry").first
+
+ expect(first_note).to have_emoji(emoji)
+ end
+
+ it 'clears the status emoji' do
+ open_edit_status_modal
+
+ page.within "#set-user-status-modal" do
+ click_button 'Remove status'
+ end
+
+ visit(project_issue_path(project, issue))
+ wait_for_requests
+
+ first_note = page.find_all(".main-notes-list .timeline-entry").first
+
+ expect(first_note).not_to have_css('.user-status-emoji')
+ end
+ end
+
context 'with set_user_availability_status feature flag disabled' do
before do
stub_feature_flags(set_user_availability_status: false)
diff --git a/spec/features/projects/active_tabs_spec.rb b/spec/features/projects/active_tabs_spec.rb
index 349e5f5e177..8001ce0f454 100644
--- a/spec/features/projects/active_tabs_spec.rb
+++ b/spec/features/projects/active_tabs_spec.rb
@@ -124,15 +124,15 @@ RSpec.describe 'Project active tab' do
context 'on project Analytics' do
before do
- visit charts_project_graph_path(project, 'master')
+ visit project_cycle_analytics_path(project)
end
- context 'on project Analytics/Repository Analytics' do
+ context 'on project Analytics/Value Stream Analytics' do
it_behaves_like 'page has active tab', _('Analytics')
- it_behaves_like 'page has active sub tab', _('Repository')
+ it_behaves_like 'page has active sub tab', _('Value Stream')
end
- context 'on project Analytics/Cycle Analytics' do
+ context 'on project Analytics/"CI / CD"' do
before do
click_tab(_('CI / CD'))
end
diff --git a/spec/features/projects/blobs/balsamiq_spec.rb b/spec/features/projects/blobs/balsamiq_spec.rb
new file mode 100644
index 00000000000..bce60856544
--- /dev/null
+++ b/spec/features/projects/blobs/balsamiq_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Balsamiq file blob', :js do
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ visit project_blob_path(project, 'add-balsamiq-file/files/images/balsamiq.bmpr')
+
+ wait_for_requests
+ end
+
+ it 'displays Balsamiq file content' do
+ expect(page).to have_content("Mobile examples")
+ end
+end
diff --git a/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb b/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
index 6b9fd41059d..484f740faee 100644
--- a/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
+++ b/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
@@ -9,12 +9,9 @@ RSpec.describe 'User creates new blob', :js do
let(:project) { create(:project, :empty_repo) }
shared_examples 'creating a file' do
- before do
- sign_in(user)
+ it 'allows the user to add a new file in Web IDE' do
visit project_path(project)
- end
- it 'allows the user to add a new file in Web IDE' do
click_link 'New file'
wait_for_requests
@@ -31,6 +28,7 @@ RSpec.describe 'User creates new blob', :js do
describe 'as a maintainer' do
before do
project.add_maintainer(user)
+ sign_in(user)
end
it_behaves_like 'creating a file'
@@ -39,6 +37,11 @@ RSpec.describe 'User creates new blob', :js do
describe 'as an admin' do
let(:user) { create(:user, :admin) }
+ before do
+ sign_in(user)
+ gitlab_enable_admin_mode_sign_in(user)
+ end
+
it_behaves_like 'creating a file'
end
diff --git a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
index 3069405ba63..1c79b2ddc38 100644
--- a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
+++ b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
@@ -5,8 +5,8 @@ require 'spec_helper'
RSpec.describe 'User follows pipeline suggest nudge spec when feature is enabled', :js do
include CookieHelper
- let(:user) { create(:user, :admin) }
let(:project) { create(:project, :empty_repo) }
+ let(:user) { project.owner }
describe 'viewing the new blob page' do
before do
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index a0519d88532..d34dde6a8f2 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
+RSpec.describe 'Gcp Cluster', :js do
include GoogleApi::CloudPlatformHelpers
let(:project) { create(:project) }
diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb
index 6c6e65005f6..6da66989b09 100644
--- a/spec/features/projects/clusters_spec.rb
+++ b/spec/features/projects/clusters_spec.rb
@@ -110,7 +110,7 @@ RSpec.describe 'Clusters', :js do
visit project_clusters_path(project)
end
- it 'user sees a add cluster button ' do
+ it 'user sees a add cluster button' do
expect(page).to have_selector('.js-add-cluster:not(.readonly)')
end
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index 45bf35a6aab..ee453aa7bbf 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -94,7 +94,8 @@ RSpec.describe 'Container Registry', :js do
end
it('pagination navigate to the second page') do
- visit_second_page
+ visit_next_page
+
expect(page).to have_content '20'
end
end
@@ -116,22 +117,23 @@ RSpec.describe 'Container Registry', :js do
context 'when there are more than 10 images' do
before do
- create_list(:container_repository, 12, project: project)
project.container_repositories << container_repository
+ create_list(:container_repository, 12, project: project)
+
visit_container_registry
end
it 'shows pagination' do
- expect(page).to have_css '.gl-pagination'
+ expect(page).to have_css '.gl-keyset-pagination'
end
it 'pagination goes to second page' do
- visit_second_page
+ visit_next_page
expect(page).to have_content 'my/image'
end
it 'pagination is preserved after navigating back from details' do
- visit_second_page
+ visit_next_page
click_link 'my/image'
breadcrumb = find '.breadcrumbs'
breadcrumb.click_link 'Container Registry'
@@ -148,8 +150,8 @@ RSpec.describe 'Container Registry', :js do
click_link name
end
- def visit_second_page
- pagination = find '.gl-pagination'
- pagination.click_link '2'
+ def visit_next_page
+ pagination = find '.gl-keyset-pagination'
+ pagination.click_button 'Next'
end
end
diff --git a/spec/features/projects/diffs/diff_show_spec.rb b/spec/features/projects/diffs/diff_show_spec.rb
index 19f111a727b..747277e2562 100644
--- a/spec/features/projects/diffs/diff_show_spec.rb
+++ b/spec/features/projects/diffs/diff_show_spec.rb
@@ -155,10 +155,6 @@ RSpec.describe 'Diff file viewer', :js do
context 'binary file that appears to be text in the first 1024 bytes' do
before do
- # The file we're visiting is smaller than 10 KB and we want it collapsed
- # so we need to disable the size increase feature.
- stub_feature_flags(gitlab_git_diff_size_limit_increase: false)
-
visit_commit('7b1cf4336b528e0f3d1d140ee50cafdbc703597c')
end
diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb
index 8315c821b6d..e8f197b67c2 100644
--- a/spec/features/projects/environments/environment_metrics_spec.rb
+++ b/spec/features/projects/environments/environment_metrics_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe 'Environment > Metrics' do
end
around do |example|
- Timecop.freeze(current_time) { example.run }
+ travel_to(current_time) { example.run }
end
shared_examples 'has environment selector' do
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 8c032660726..27167f95104 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -12,8 +12,20 @@ RSpec.describe 'Environments page', :js do
sign_in(user)
end
+ def actions_button_selector
+ '[data-testid="environment-actions-button"]'
+ end
+
+ def action_link_selector
+ '[data-testid="manual-action-link"]'
+ end
+
def stop_button_selector
- %q{button[title="Stop environment"]}
+ 'button[title="Stop environment"]'
+ end
+
+ def upcoming_deployment_content_selector
+ '[data-testid="upcoming-deployment-content"]'
end
describe 'page tabs' do
@@ -187,18 +199,17 @@ RSpec.describe 'Environments page', :js do
end
it 'shows a play button' do
- find('.js-environment-actions-dropdown').click
-
+ find(actions_button_selector).click
expect(page).to have_content(action.name)
end
it 'allows to play a manual action', :js do
expect(action).to be_manual
- find('.js-environment-actions-dropdown').click
+ find(actions_button_selector).click
expect(page).to have_content(action.name)
- expect { find('.js-manual-action-link').click }
+ expect { find(action_link_selector).click }
.not_to change { Ci::Pipeline.count }
end
@@ -301,11 +312,11 @@ RSpec.describe 'Environments page', :js do
end
it 'has a dropdown for actionable jobs' do
- expect(page).to have_selector('.dropdown-new.btn.btn-default [data-testid="play-icon"]')
+ expect(page).to have_selector("#{actions_button_selector} [data-testid=\"play-icon\"]")
end
it "has link to the delayed job's action" do
- find('.js-environment-actions-dropdown').click
+ find(actions_button_selector).click
expect(page).to have_button('delayed job')
expect(page).to have_content(/\d{2}:\d{2}:\d{2}/)
@@ -320,7 +331,7 @@ RSpec.describe 'Environments page', :js do
end
it "shows 00:00:00 as the remaining time" do
- find('.js-environment-actions-dropdown').click
+ find(actions_button_selector).click
expect(page).to have_content("00:00:00")
end
@@ -328,8 +339,8 @@ RSpec.describe 'Environments page', :js do
context 'when user played a delayed job immediately' do
before do
- find('.js-environment-actions-dropdown').click
- page.accept_confirm { click_button('delayed job') }
+ find(actions_button_selector).click
+ accept_confirm { find(action_link_selector).click }
wait_for_requests
end
@@ -355,6 +366,26 @@ RSpec.describe 'Environments page', :js do
expect(page).to have_content('No deployments yet')
end
end
+
+ context 'when there is an upcoming deployment' do
+ let_it_be(:project) { create(:project, :repository) }
+
+ let!(:deployment) do
+ create(:deployment, :running,
+ environment: environment,
+ sha: project.commit.id)
+ end
+
+ it "renders the upcoming deployment", :aggregate_failures do
+ visit_environments(project)
+
+ within(upcoming_deployment_content_selector) do
+ expect(page).to have_content("##{deployment.iid}")
+ expect(page).to have_selector("a[href=\"#{project_job_path(project, deployment.deployable)}\"]")
+ expect(page).to have_link(href: /#{deployment.user.username}/)
+ end
+ end
+ end
end
it 'does have a new environment button' do
@@ -423,10 +454,10 @@ RSpec.describe 'Environments page', :js do
expect(page).to have_content 'review-1'
expect(page).to have_content 'review-2'
within('.ci-table') do
- within('.gl-responsive-table-row:nth-child(3)') do
+ within('[data-qa-selector="environment_item"]', text: 'review-1') do
expect(find('.js-auto-stop').text).not_to be_empty
end
- within('.gl-responsive-table-row:nth-child(4)') do
+ within('[data-qa-selector="environment_item"]', text: 'review-2') do
expect(find('.js-auto-stop').text).not_to be_empty
end
end
diff --git a/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb
index 830dda737b0..eaafc7e607b 100644
--- a/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb
+++ b/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb
@@ -67,118 +67,6 @@ RSpec.describe 'User creates feature flag', :js do
end
end
- context 'with new version flags disabled' do
- before do
- stub_feature_flags(feature_flags_new_version: false)
- end
-
- context 'when creates without changing scopes' do
- before do
- visit(new_project_feature_flag_path(project))
- set_feature_flag_info('ci_live_trace', 'For live trace')
- click_button 'Create feature flag'
- expect(page).to have_current_path(project_feature_flags_path(project))
- end
-
- it 'shows the created feature flag' do
- within_feature_flag_row(1) do
- expect(page.find('.feature-flag-name')).to have_content('ci_live_trace')
- expect_status_toggle_button_to_be_checked
-
- within_feature_flag_scopes do
- expect(page.find('[data-qa-selector="feature-flag-scope-info-badge"]:nth-child(1)')).to have_content('*')
- end
- end
- end
- end
-
- context 'when creates with disabling the default scope' do
- before do
- visit(new_project_feature_flag_path(project))
- set_feature_flag_info('ci_live_trace', 'For live trace')
-
- within_scope_row(1) do
- within_status { find('.project-feature-toggle').click }
- end
-
- click_button 'Create feature flag'
- end
-
- it 'shows the created feature flag' do
- within_feature_flag_row(1) do
- expect(page.find('.feature-flag-name')).to have_content('ci_live_trace')
- expect_status_toggle_button_to_be_checked
-
- within_feature_flag_scopes do
- expect(page.find('[data-qa-selector="feature-flag-scope-muted-badge"]:nth-child(1)')).to have_content('*')
- end
- end
- end
- end
-
- context 'when creates with an additional scope' do
- before do
- visit(new_project_feature_flag_path(project))
- set_feature_flag_info('mr_train', '')
-
- within_scope_row(2) do
- within_environment_spec do
- find('.js-env-search > input').set("review/*")
- find('.js-create-button').click
- end
- end
-
- within_scope_row(2) do
- within_status { find('.project-feature-toggle').click }
- end
-
- click_button 'Create feature flag'
- end
-
- it 'shows the created feature flag' do
- within_feature_flag_row(1) do
- expect(page.find('.feature-flag-name')).to have_content('mr_train')
- expect_status_toggle_button_to_be_checked
-
- within_feature_flag_scopes do
- expect(page.find('[data-qa-selector="feature-flag-scope-info-badge"]:nth-child(1)')).to have_content('*')
- expect(page.find('[data-qa-selector="feature-flag-scope-info-badge"]:nth-child(2)')).to have_content('review/*')
- end
- end
- end
- end
-
- context 'when searches an environment name for scope creation' do
- let!(:environment) { create(:environment, name: 'production', project: project) }
-
- before do
- visit(new_project_feature_flag_path(project))
- set_feature_flag_info('mr_train', '')
-
- within_scope_row(2) do
- within_environment_spec do
- find('.js-env-search > input').set('prod')
- click_button 'production'
- end
- end
-
- click_button 'Create feature flag'
- end
-
- it 'shows the created feature flag' do
- within_feature_flag_row(1) do
- expect(page.find('.feature-flag-name')).to have_content('mr_train')
- expect_status_toggle_button_to_be_checked
-
- within_feature_flag_scopes do
- expect(page.find('[data-qa-selector="feature-flag-scope-info-badge"]:nth-child(1)')).to have_content('*')
- expect(page.find('[data-qa-selector="feature-flag-scope-muted-badge"]:nth-child(2)')).to have_content('production')
- end
- end
- end
- end
- end
-
private
def set_feature_flag_info(name, description)
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index 467adb25a17..2f0fbd29cb5 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe 'Edit Project Settings' do
sign_in(member)
end
- tools = { builds: "pipelines", issues: "issues", wiki: "wiki", snippets: "snippets", merge_requests: "merge_requests" }
+ tools = { builds: "pipelines", issues: "issues", wiki: "wiki", snippets: "snippets", merge_requests: "merge_requests", analytics: "analytics" }
tools.each do |tool_name, shortcut_name|
describe "feature #{tool_name}" do
@@ -150,6 +150,7 @@ RSpec.describe 'Edit Project Settings' do
before do
non_member.update_attribute(:admin, true)
sign_in(non_member)
+ gitlab_enable_admin_mode_sign_in(non_member)
end
it 'renders 404 if feature is disabled' do
diff --git a/spec/features/projects/gfm_autocomplete_load_spec.rb b/spec/features/projects/gfm_autocomplete_load_spec.rb
index b02483be489..f4cd65bcba1 100644
--- a/spec/features/projects/gfm_autocomplete_load_spec.rb
+++ b/spec/features/projects/gfm_autocomplete_load_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe 'GFM autocomplete loading', :js do
let(:project) { create(:project) }
before do
- sign_in(create(:admin))
+ sign_in(project.owner)
visit project_path(project)
end
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index 83ceffa621c..af228764c17 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -28,73 +28,40 @@ RSpec.describe 'Import/Export - project import integration test', :js do
let(:project_name) { 'Test Project Name' + randomHex }
let(:project_path) { 'test-project-name' + randomHex }
- context 'prefilled the path' do
- it 'user imports an exported project successfully', :sidekiq_might_not_need_inline do
- visit new_project_path
+ it 'user imports an exported project successfully', :sidekiq_might_not_need_inline do
+ visit new_project_path
+ click_import_project_tab
+ click_link 'GitLab export'
- fill_in :project_name, with: project_name, visible: true
- click_import_project_tab
- click_link 'GitLab export'
+ fill_in :name, with: 'Test Project Name', visible: true
+ fill_in :path, with: 'test-project-path', visible: true
+ attach_file('file', file)
- expect(page).to have_content('Import an exported GitLab project')
- expect(URI.parse(current_url).query).to eq("namespace_id=#{namespace.id}&name=#{ERB::Util.url_encode(project_name)}&path=#{project_path}")
+ expect { click_on 'Import project' }.to change { Project.count }.by(1)
- attach_file('file', file)
- click_on 'Import project'
-
- expect(Project.count).to eq(1)
-
- project = Project.last
- expect(project).not_to be_nil
- expect(project.description).to eq("Foo Bar")
- expect(project.issues).not_to be_empty
- expect(project.merge_requests).not_to be_empty
- expect(wiki_exists?(project)).to be true
- expect(project.import_state.status).to eq('finished')
- end
+ project = Project.last
+ expect(project).not_to be_nil
+ expect(page).to have_content("Project 'test-project-path' is being imported")
end
- context 'path is not prefilled' do
- it 'user imports an exported project successfully', :sidekiq_might_not_need_inline do
- visit new_project_path
- click_import_project_tab
- click_link 'GitLab export'
+ it 'invalid project' do
+ project = create(:project, namespace: user.namespace)
- fill_in :name, with: 'Test Project Name', visible: true
- fill_in :path, with: 'test-project-path', visible: true
- attach_file('file', file)
+ visit new_project_path
- expect { click_on 'Import project' }.to change { Project.count }.by(1)
+ click_import_project_tab
+ click_link 'GitLab export'
+ fill_in :name, with: project.name, visible: true
+ attach_file('file', file)
+ click_on 'Import project'
- project = Project.last
- expect(project).not_to be_nil
- expect(page).to have_content("Project 'test-project-path' is being imported")
+ page.within('.flash-container') do
+ expect(page).to have_content('Project could not be imported')
end
end
end
- it 'invalid project' do
- project = create(:project, namespace: user.namespace)
-
- visit new_project_path
-
- fill_in :project_name, with: project.name, visible: true
- click_import_project_tab
- click_link 'GitLab export'
- attach_file('file', file)
- click_on 'Import project'
-
- page.within('.flash-container') do
- expect(page).to have_content('Project could not be imported')
- end
- end
-
- def wiki_exists?(project)
- wiki = ProjectWiki.new(project)
- wiki.repository.exists? && !wiki.repository.empty?
- end
-
def click_import_project_tab
- find('#import-project-tab').click
+ find('[data-qa-selector="import_project_link"]').click
end
end
diff --git a/spec/features/projects/jobs/permissions_spec.rb b/spec/features/projects/jobs/permissions_spec.rb
index 7f46a369dd6..b1e8127c54c 100644
--- a/spec/features/projects/jobs/permissions_spec.rb
+++ b/spec/features/projects/jobs/permissions_spec.rb
@@ -3,11 +3,13 @@
require 'spec_helper'
RSpec.describe 'Project Jobs Permissions' do
- let(:user) { create(:user) }
- let(:group) { create(:group, name: 'some group') }
- let(:project) { create(:project, :repository, namespace: group) }
- let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
- let!(:job) { create(:ci_build, :running, :coverage, :trace_artifact, pipeline: pipeline) }
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be_with_reload(:group) { create(:group, name: 'some group') }
+ let_it_be_with_reload(:project) { create(:project, :repository, namespace: group) }
+ let_it_be_with_reload(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:job) { create(:ci_build, :running, :coverage, :trace_artifact, pipeline: pipeline) }
before do
sign_in(user)
@@ -34,7 +36,7 @@ RSpec.describe 'Project Jobs Permissions' do
context 'when public access for jobs is disabled' do
before do
- project.update(public_builds: false)
+ project.update!(public_builds: false)
end
context 'when user is a guest' do
@@ -48,7 +50,7 @@ RSpec.describe 'Project Jobs Permissions' do
context 'when project is internal' do
before do
- project.update(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
end
it_behaves_like 'recent job page details responds with status', 404
@@ -58,12 +60,30 @@ RSpec.describe 'Project Jobs Permissions' do
context 'when public access for jobs is enabled' do
before do
- project.update(public_builds: true)
+ project.update!(public_builds: true)
+ end
+
+ context 'when user is a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like 'recent job page details responds with status', 200
+ it_behaves_like 'project jobs page responds with status', 200
+ end
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it_behaves_like 'recent job page details responds with status', 200
+ it_behaves_like 'project jobs page responds with status', 200
end
context 'when project is internal' do
before do
- project.update(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
end
it_behaves_like 'recent job page details responds with status', 200 do
@@ -89,7 +109,7 @@ RSpec.describe 'Project Jobs Permissions' do
describe 'artifacts page' do
context 'when recent job has artifacts available' do
- before do
+ before_all do
archive = fixture_file_upload('spec/fixtures/ci_build_artifacts.zip')
create(:ci_job_artifact, :archive, file: archive, job: job)
@@ -97,7 +117,7 @@ RSpec.describe 'Project Jobs Permissions' do
context 'when public access for jobs is disabled' do
before do
- project.update(public_builds: false)
+ project.update!(public_builds: false)
end
context 'when user with guest role' do
@@ -128,4 +148,124 @@ RSpec.describe 'Project Jobs Permissions' do
end
end
end
+
+ context 'with CI_DEBUG_TRACE' do
+ let_it_be(:ci_instance_variable) { create(:ci_instance_variable, key: 'CI_DEBUG_TRACE') }
+
+ describe 'trace endpoint' do
+ let_it_be(:job) { create(:ci_build, :trace_artifact, pipeline: pipeline) }
+
+ where(:public_builds, :user_project_role, :ci_debug_trace, :expected_status_code) do
+ true | 'developer' | true | 200
+ true | 'guest' | true | 403
+ true | 'developer' | false | 200
+ true | 'guest' | false | 200
+ false | 'developer' | true | 200
+ false | 'guest' | true | 403
+ false | 'developer' | false | 200
+ false | 'guest' | false | 403
+ end
+
+ with_them do
+ before do
+ ci_instance_variable.update!(value: ci_debug_trace)
+ project.update!(public_builds: public_builds)
+ project.add_role(user, user_project_role)
+ end
+
+ it 'renders trace to authorized users' do
+ visit trace_project_job_path(project, job)
+
+ expect(status_code).to eq(expected_status_code)
+ end
+ end
+
+ context 'when restrict_access_to_build_debug_mode feature not enabled' do
+ where(:public_builds, :user_project_role, :ci_debug_trace, :expected_status_code) do
+ true | 'developer' | true | 200
+ true | 'guest' | true | 200
+ true | 'developer' | false | 200
+ true | 'guest' | false | 200
+ false | 'developer' | true | 200
+ false | 'guest' | true | 403
+ false | 'developer' | false | 200
+ false | 'guest' | false | 403
+ end
+
+ with_them do
+ before do
+ stub_feature_flags(restrict_access_to_build_debug_mode: false)
+ ci_instance_variable.update!(value: ci_debug_trace)
+ project.update!(public_builds: public_builds)
+ project.add_role(user, user_project_role)
+ end
+
+ it 'renders trace to authorized users' do
+ visit trace_project_job_path(project, job)
+
+ expect(status_code).to eq(expected_status_code)
+ end
+ end
+ end
+ end
+
+ describe 'raw page' do
+ let_it_be(:job) { create(:ci_build, :running, :coverage, :trace_artifact, pipeline: pipeline) }
+
+ where(:public_builds, :user_project_role, :ci_debug_trace, :expected_status_code, :expected_msg) do
+ true | 'developer' | true | 200 | nil
+ true | 'guest' | true | 403 | 'You must have developer or higher permissions'
+ true | 'developer' | false | 200 | nil
+ true | 'guest' | false | 200 | nil
+ false | 'developer' | true | 200 | nil
+ false | 'guest' | true | 403 | 'You must have developer or higher permissions'
+ false | 'developer' | false | 200 | nil
+ false | 'guest' | false | 403 | 'The current user is not authorized to access the job log'
+ end
+
+ with_them do
+ before do
+ ci_instance_variable.update!(value: ci_debug_trace)
+ project.update!(public_builds: public_builds)
+ project.add_role(user, user_project_role)
+ end
+
+ it 'renders raw trace to authorized users' do
+ visit raw_project_job_path(project, job)
+
+ expect(status_code).to eq(expected_status_code)
+ expect(page).to have_content(expected_msg)
+ end
+ end
+
+ context 'when restrict_access_to_build_debug_mode feature not enabled' do
+ where(:public_builds, :user_project_role, :ci_debug_trace, :expected_status_code, :expected_msg) do
+ true | 'developer' | true | 200 | nil
+ true | 'guest' | true | 200 | nil
+ true | 'developer' | false | 200 | nil
+ true | 'guest' | false | 200 | nil
+ false | 'developer' | true | 200 | nil
+ false | 'guest' | true | 403 | 'The current user is not authorized to access the job log'
+ false | 'developer' | false | 200 | nil
+ false | 'guest' | false | 403 | 'The current user is not authorized to access the job log'
+ end
+
+ with_them do
+ before do
+ stub_feature_flags(restrict_access_to_build_debug_mode: false)
+ ci_instance_variable.update!(value: ci_debug_trace)
+ project.update!(public_builds: public_builds)
+ project.add_role(user, user_project_role)
+ end
+
+ it 'renders raw trace to authorized users' do
+ visit raw_project_job_path(project, job)
+
+ expect(status_code).to eq(expected_status_code)
+ expect(page).to have_content(expected_msg)
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index e19337e1ff5..4edda9febbe 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -25,72 +25,113 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
describe "GET /:project/jobs" do
- let!(:job) { create(:ci_build, pipeline: pipeline) }
-
- context "Pending scope" do
+ context 'with no jobs' do
before do
- visit project_jobs_path(project, scope: :pending)
- end
+ stub_experiment(jobs_empty_state: experiment_active)
+ stub_experiment_for_subject(jobs_empty_state: in_experiment_group)
- it "shows Pending tab jobs" do
- expect(page).to have_selector('.nav-links li.active', text: 'Pending')
- expect(page).to have_content job.short_sha
- expect(page).to have_content job.ref
- expect(page).to have_content job.name
+ visit project_jobs_path(project)
end
- end
- context "Running scope" do
- before do
- job.run!
- visit project_jobs_path(project, scope: :running)
- end
+ context 'when experiment not active' do
+ let(:experiment_active) { false }
+ let(:in_experiment_group) { false }
- it "shows Running tab jobs" do
- expect(page).to have_selector('.nav-links li.active', text: 'Running')
- expect(page).to have_content job.short_sha
- expect(page).to have_content job.ref
- expect(page).to have_content job.name
+ it 'shows the empty state control page' do
+ expect(page).to have_content('No jobs to show')
+ expect(page).to have_link('Get started with Pipelines')
+ end
end
- end
- context "Finished scope" do
- before do
- job.run!
- visit project_jobs_path(project, scope: :finished)
+ context 'when experiment active and user in control group' do
+ let(:experiment_active) { true }
+ let(:in_experiment_group) { false }
+
+ it 'shows the empty state control page' do
+ expect(page).to have_content('No jobs to show')
+ expect(page).to have_link('Get started with Pipelines')
+ end
end
- it "shows Finished tab jobs" do
- expect(page).to have_selector('.nav-links li.active', text: 'Finished')
- expect(page).to have_content 'No jobs to show'
+ context 'when experiment active and user in experimental group' do
+ let(:experiment_active) { true }
+ let(:in_experiment_group) { true }
+
+ it 'shows the empty state experiment page' do
+ expect(page).to have_content('Use jobs to automate your tasks')
+ expect(page).to have_link('Create CI/CD configuration file')
+ end
end
end
- context "All jobs" do
- before do
- project.builds.running_or_pending.each(&:success)
- visit project_jobs_path(project)
+ context 'with a job' do
+ let!(:job) { create(:ci_build, pipeline: pipeline) }
+
+ context "Pending scope" do
+ before do
+ visit project_jobs_path(project, scope: :pending)
+ end
+
+ it "shows Pending tab jobs" do
+ expect(page).to have_selector('.nav-links li.active', text: 'Pending')
+ expect(page).to have_content job.short_sha
+ expect(page).to have_content job.ref
+ expect(page).to have_content job.name
+ end
end
- it "shows All tab jobs" do
- expect(page).to have_selector('.nav-links li.active', text: 'All')
- expect(page).to have_content job.short_sha
- expect(page).to have_content job.ref
- expect(page).to have_content job.name
+ context "Running scope" do
+ before do
+ job.run!
+ visit project_jobs_path(project, scope: :running)
+ end
+
+ it "shows Running tab jobs" do
+ expect(page).to have_selector('.nav-links li.active', text: 'Running')
+ expect(page).to have_content job.short_sha
+ expect(page).to have_content job.ref
+ expect(page).to have_content job.name
+ end
end
- end
- context "when visiting old URL" do
- let(:jobs_url) do
- project_jobs_path(project)
+ context "Finished scope" do
+ before do
+ job.run!
+ visit project_jobs_path(project, scope: :finished)
+ end
+
+ it "shows Finished tab jobs" do
+ expect(page).to have_selector('.nav-links li.active', text: 'Finished')
+ expect(page).to have_content 'No jobs to show'
+ end
end
- before do
- visit jobs_url.sub('/-/jobs', '/builds')
+ context "All jobs" do
+ before do
+ project.builds.running_or_pending.each(&:success)
+ visit project_jobs_path(project)
+ end
+
+ it "shows All tab jobs" do
+ expect(page).to have_selector('.nav-links li.active', text: 'All')
+ expect(page).to have_content job.short_sha
+ expect(page).to have_content job.ref
+ expect(page).to have_content job.name
+ end
end
- it "redirects to new URL" do
- expect(page.current_path).to eq(jobs_url)
+ context "when visiting old URL" do
+ let(:jobs_url) do
+ project_jobs_path(project)
+ end
+
+ before do
+ visit jobs_url.sub('/-/jobs', '/builds')
+ end
+
+ it "redirects to new URL" do
+ expect(page.current_path).to eq(jobs_url)
+ end
end
end
end
diff --git a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
index 85a08c441ca..0a373b0d51a 100644
--- a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
+++ b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'Issue prioritization' do
# According to https://gitlab.com/gitlab-org/gitlab-foss/issues/14189#note_4360653
context 'when issues have one label', :js do
- it 'Are sorted properly' do
+ it 'are sorted properly' do
# Issues
issue_1 = create(:issue, title: 'issue_1', project: project)
issue_2 = create(:issue, title: 'issue_2', project: project)
@@ -45,7 +45,7 @@ RSpec.describe 'Issue prioritization' do
end
context 'when issues have multiple labels', :js do
- it 'Are sorted properly' do
+ it 'are sorted properly' do
# Issues
issue_1 = create(:issue, title: 'issue_1', project: project)
issue_2 = create(:issue, title: 'issue_2', project: project)
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 6a2ec9aa4a8..4aabf040655 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'New project' do
+RSpec.describe 'New project', :js do
include Select2Helper
context 'as a user' do
@@ -18,6 +18,7 @@ RSpec.describe 'New project' do
)
visit new_project_path
+ find('[data-qa-selector="blank_project_link"]').click
expect(page).to have_content 'Other visibility settings have been disabled by the administrator.'
end
@@ -28,6 +29,7 @@ RSpec.describe 'New project' do
)
visit new_project_path
+ find('[data-qa-selector="blank_project_link"]').click
expect(page).to have_content 'Visibility settings have been disabled by the administrator.'
end
@@ -42,17 +44,18 @@ RSpec.describe 'New project' do
it 'shows "New project" page', :js do
visit new_project_path
+ find('[data-qa-selector="blank_project_link"]').click
expect(page).to have_content('Project name')
expect(page).to have_content('Project URL')
expect(page).to have_content('Project slug')
- find('#import-project-tab').click
+ click_link('New project')
+ find('[data-qa-selector="import_project_link"]').click
expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket')
expect(page).to have_link('GitLab.com')
- expect(page).to have_link('Google Code')
expect(page).to have_button('Repo by URL')
expect(page).to have_link('GitLab export')
end
@@ -61,7 +64,7 @@ RSpec.describe 'New project' do
before do
visit new_project_path
- find('#import-project-tab').click
+ find('[data-qa-selector="import_project_link"]').click
end
it { expect(page).to have_link('Manifest file') }
@@ -73,6 +76,7 @@ RSpec.describe 'New project' do
stub_application_setting(default_project_visibility: level)
visit new_project_path
+ find('[data-qa-selector="blank_project_link"]').click
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
@@ -80,6 +84,7 @@ RSpec.describe 'New project' do
it "saves visibility level #{level} on validation error" do
visit new_project_path
+ find('[data-qa-selector="blank_project_link"]').click
choose(s_(key))
click_button('Create project')
@@ -97,6 +102,7 @@ RSpec.describe 'New project' do
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE)
visit new_project_path(namespace_id: group.id)
+ find('[data-qa-selector="blank_project_link"]').click
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
@@ -112,6 +118,7 @@ RSpec.describe 'New project' do
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
+ find('[data-qa-selector="blank_project_link"]').click
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
@@ -123,6 +130,7 @@ RSpec.describe 'New project' do
context 'Readme selector' do
it 'shows the initialize with Readme checkbox on "Blank project" tab' do
visit new_project_path
+ find('[data-qa-selector="blank_project_link"]').click
expect(page).to have_css('input#project_initialize_with_readme')
expect(page).to have_content('Initialize repository with a README')
@@ -130,7 +138,7 @@ RSpec.describe 'New project' do
it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
visit new_project_path
- find('#create-from-template-pane').click
+ find('[data-qa-selector="create_from_template_link"]').click
first('.choose-template').click
page.within '.project-fields-form' do
@@ -141,7 +149,7 @@ RSpec.describe 'New project' do
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
visit new_project_path
- find('#import-project-tab').click
+ find('[data-qa-selector="import_project_link"]').click
first('.js-import-git-toggle-button').click
page.within '.toggle-import-form' do
@@ -155,13 +163,12 @@ RSpec.describe 'New project' do
context 'with user namespace' do
before do
visit new_project_path
+ find('[data-qa-selector="blank_project_link"]').click
end
it 'selects the user namespace' do
page.within('#blank-project-pane') do
- namespace = find('#project_namespace_id')
-
- expect(namespace.text).to eq user.username
+ expect(page).to have_select('project[namespace_id]', visible: false, selected: user.username)
end
end
end
@@ -172,13 +179,12 @@ RSpec.describe 'New project' do
before do
group.add_owner(user)
visit new_project_path(namespace_id: group.id)
+ find('[data-qa-selector="blank_project_link"]').click
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
- namespace = find('#project_namespace_id option[selected]')
-
- expect(namespace.text).to eq group.name
+ expect(page).to have_select('project[namespace_id]', visible: false, selected: group.name)
end
end
end
@@ -190,13 +196,12 @@ RSpec.describe 'New project' do
before do
group.add_maintainer(user)
visit new_project_path(namespace_id: subgroup.id)
+ find('[data-qa-selector="blank_project_link"]').click
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
- namespace = find('#project_namespace_id option[selected]')
-
- expect(namespace.text).to eq subgroup.full_path
+ expect(page).to have_select('project[namespace_id]', visible: false, selected: subgroup.full_path)
end
end
end
@@ -211,6 +216,7 @@ RSpec.describe 'New project' do
internal_group.add_owner(user)
private_group.add_owner(user)
visit new_project_path(namespace_id: public_group.id)
+ find('[data-qa-selector="blank_project_link"]').click
end
it 'enables the correct visibility options' do
@@ -240,7 +246,7 @@ RSpec.describe 'New project' do
context 'Import project options', :js do
before do
visit new_project_path
- find('#import-project-tab').click
+ find('[data-qa-selector="import_project_link"]').click
end
context 'from git repository url, "Repo by URL"' do
@@ -285,17 +291,6 @@ RSpec.describe 'New project' do
end
end
- context 'from Google Code' do
- before do
- first('.import_google_code').click
- end
-
- it 'shows import instructions' do
- expect(page).to have_content('Import projects from Google Code')
- expect(current_path).to eq new_import_google_code_path
- end
- end
-
context 'from manifest file' do
before do
first('.import_manifest').click
@@ -315,13 +310,12 @@ RSpec.describe 'New project' do
before do
group.add_developer(user)
visit new_project_path(namespace_id: group.id)
+ find('[data-qa-selector="blank_project_link"]').click
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
- namespace = find('#project_namespace_id option[selected]')
-
- expect(namespace.text).to eq group.full_path
+ expect(page).to have_select('project[namespace_id]', visible: false, selected: group.full_path)
end
end
end
diff --git a/spec/features/projects/settings/operations_settings_spec.rb b/spec/features/projects/settings/operations_settings_spec.rb
index de7251db5c9..1d9f256a819 100644
--- a/spec/features/projects/settings/operations_settings_spec.rb
+++ b/spec/features/projects/settings/operations_settings_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
describe 'Settings > Operations' do
describe 'Incidents' do
- let(:create_issue) { 'Create an issue. Issues are created for each alert triggered.' }
+ let(:create_issue) { 'Create an incident. Incidents are created for each alert triggered.' }
let(:send_email) { 'Send a separate email notification to Developers.' }
before do
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index cb333bdb428..2b03ecf5af1 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -26,20 +26,20 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
subject
settings_block = find('#js-registry-policies')
- expect(settings_block).to have_text 'Cleanup policy for tags'
+ expect(settings_block).to have_text 'Clean up image tags'
end
it 'saves cleanup policy submit the form' do
subject
within '#js-registry-policies' do
- within '.gl-card-body' do
- select('7 days until tags are automatically removed', from: 'Expiration interval:')
- select('Every day', from: 'Expiration schedule:')
- select('50 tags per image name', from: 'Number of tags to retain:')
- fill_in('Tags with names matching this regex pattern will expire:', with: '.*-production')
- end
- submit_button = find('.gl-card-footer .btn.btn-success')
+ select('Every day', from: 'Run cleanup')
+ select('50 tags per image name', from: 'Keep the most recent:')
+ fill_in('Keep tags matching:', with: 'stable')
+ select('7 days', from: 'Remove tags older than:')
+ fill_in('Remove tags matching:', with: '.*-production')
+
+ submit_button = find('.btn.btn-success')
expect(submit_button).not_to be_disabled
submit_button.click
end
@@ -51,10 +51,9 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
subject
within '#js-registry-policies' do
- within '.gl-card-body' do
- fill_in('Tags with names matching this regex pattern will expire:', with: '*-production')
- end
- submit_button = find('.gl-card-footer .btn.btn-success')
+ fill_in('Remove tags matching:', with: '*-production')
+
+ submit_button = find('.btn.btn-success')
expect(submit_button).not_to be_disabled
submit_button.click
end
@@ -85,7 +84,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
within '#js-registry-policies' do
case result
when :available_section
- expect(find('.gl-card-header')).to have_content('Tag expiration policy')
+ expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
when :disabled_message
expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled')
end
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index 8c7b7bc70a2..3e520142117 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -289,13 +289,13 @@ RSpec.describe 'Projects > Settings > Repository settings' do
visit project_settings_repository_path(project)
end
- context 'when project mirroring is enabled' do
+ context 'when project mirroring is enabled', :enable_admin_mode do
let(:mirror_available) { true }
include_examples 'shows mirror settings'
end
- context 'when project mirroring is disabled' do
+ context 'when project mirroring is disabled', :enable_admin_mode do
let(:mirror_available) { false }
include_examples 'shows mirror settings'
diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb
index 59e6f54da2f..d31913d2dcf 100644
--- a/spec/features/projects/settings/service_desk_setting_spec.rb
+++ b/spec/features/projects/settings/service_desk_setting_spec.rb
@@ -14,20 +14,57 @@ RSpec.describe 'Service Desk Setting', :js do
allow_any_instance_of(Project).to receive(:present).with(current_user: user).and_return(presenter)
allow(::Gitlab::IncomingEmail).to receive(:enabled?) { true }
allow(::Gitlab::IncomingEmail).to receive(:supports_wildcard?) { true }
-
- visit edit_project_path(project)
end
it 'shows activation checkbox' do
+ visit edit_project_path(project)
+
expect(page).to have_selector("#service-desk-checkbox")
end
- it 'shows incoming email after activating' do
- find("#service-desk-checkbox").click
- wait_for_requests
- project.reload
- expect(project.service_desk_enabled).to be_truthy
- expect(project.service_desk_address).to be_present
- expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_address)
+ context 'when service_desk_email is disabled' do
+ before do
+ allow(::Gitlab::ServiceDeskEmail).to receive(:enabled?).and_return(false)
+
+ visit edit_project_path(project)
+ end
+
+ it 'shows incoming email but not project name suffix after activating' do
+ find("#service-desk-checkbox").click
+
+ wait_for_requests
+
+ project.reload
+ expect(project.service_desk_enabled).to be_truthy
+ expect(project.service_desk_address).to be_present
+ expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_incoming_address)
+ expect(page).not_to have_selector('#service-desk-project-suffix')
+ end
+ end
+
+ context 'when service_desk_email is enabled' do
+ before do
+ allow(::Gitlab::ServiceDeskEmail).to receive(:enabled?) { true }
+ allow(::Gitlab::ServiceDeskEmail).to receive(:address_for_key) { 'address-suffix@example.com' }
+
+ visit edit_project_path(project)
+ end
+
+ it 'allows setting of custom address suffix' do
+ find("#service-desk-checkbox").click
+ wait_for_requests
+
+ project.reload
+ expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_incoming_address)
+
+ page.within '#js-service-desk' do
+ fill_in('service-desk-project-suffix', with: 'foo')
+ click_button 'Save changes'
+ end
+
+ wait_for_requests
+
+ expect(find('[data-testid="incoming-email"]').value).to eq('address-suffix@example.com')
+ end
end
end
diff --git a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
index ba504624823..91a7753fe6d 100644
--- a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
+++ b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe "User interacts with deploy keys", :js do
click_button("Enable")
- expect(page).not_to have_selector(".fa-spinner")
+ expect(page).not_to have_selector(".gl-spinner")
expect(current_path).to eq(project_settings_repository_path(project))
find(".js-deployKeys-tab-enabled_keys").click
diff --git a/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
deleted file mode 100644
index 8d239cb2cbf..00000000000
--- a/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Projects > Show > Developer views empty project instructions' do
- let(:project) { create(:project, :empty_repo) }
- let(:developer) { create(:user) }
-
- before do
- project.add_developer(developer)
-
- sign_in(developer)
- end
-
- it 'displays "git clone" instructions' do
- visit project_path(project)
-
- expect(page).to have_content("git clone")
- end
-end
diff --git a/spec/features/projects/show/no_password_spec.rb b/spec/features/projects/show/no_password_spec.rb
index 79cd65e5406..d18ff75b324 100644
--- a/spec/features/projects/show/no_password_spec.rb
+++ b/spec/features/projects/show/no_password_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'No Password Alert' do
let(:user) { create(:user) }
it 'shows no alert' do
- expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you set a password on your account"
+ expect(page).not_to have_content "You won't be able to pull or push repositories via HTTP until you set a password on your account"
end
end
@@ -23,7 +23,7 @@ RSpec.describe 'No Password Alert' do
let(:user) { create(:user, password_automatically_set: true) }
it 'shows a password alert' do
- expect(page).to have_content "You won't be able to pull or push project code via HTTP until you set a password on your account"
+ expect(page).to have_content "You won't be able to pull or push repositories via HTTP until you set a password on your account"
end
end
end
@@ -41,7 +41,7 @@ RSpec.describe 'No Password Alert' do
gitlab_sign_in_via('saml', user, 'my-uid')
visit project_path(project)
- expect(page).to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account"
+ expect(page).to have_content "You won't be able to pull or push repositories via HTTP until you create a personal access token on your account"
end
end
@@ -51,7 +51,7 @@ RSpec.describe 'No Password Alert' do
gitlab_sign_in_via('saml', user, 'my-uid')
visit project_path(project)
- expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account"
+ expect(page).not_to have_content "You won't be able to pull or push repositories via HTTP until you create a personal access token on your account"
end
end
end
@@ -65,7 +65,7 @@ RSpec.describe 'No Password Alert' do
end
it 'shows no alert' do
- expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you"
+ expect(page).not_to have_content "You won't be able to pull or push repositories via HTTP until you"
end
end
end
diff --git a/spec/features/projects/show/schema_markup_spec.rb b/spec/features/projects/show/schema_markup_spec.rb
index e651798af23..1777b72cbf5 100644
--- a/spec/features/projects/show/schema_markup_spec.rb
+++ b/spec/features/projects/show/schema_markup_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe 'Projects > Show > Schema Markup' do
expect(page).to have_selector('img[itemprop="image"]')
expect(page).to have_selector('[itemprop="name"]', text: project.name)
expect(page).to have_selector('[itemprop="identifier"]', text: "Project ID: #{project.id}")
- expect(page).to have_selector('[itemprop="abstract"]', text: project.description)
+ expect(page).to have_selector('[itemprop="description"]', text: project.description)
expect(page).to have_selector('[itemprop="license"]', text: project.repository.license.name)
expect(find_all('[itemprop="keywords"]').map(&:text)).to match_array(project.tag_list.map(&:capitalize))
expect(page).to have_selector('[itemprop="about"]')
diff --git a/spec/features/projects/show/user_sees_git_instructions_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb
index 3b77fd7eebf..febdb70de86 100644
--- a/spec/features/projects/show/user_sees_git_instructions_spec.rb
+++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb
@@ -122,13 +122,11 @@ RSpec.describe 'Projects > Show > User sees Git instructions' do
context 'when project is not empty' do
let_it_be(:project) { create(:project, :public, :repository) }
- before do
- visit(project_path(project))
- end
-
context 'when not signed in' do
before do
allow(Gitlab.config.gitlab).to receive(:host).and_return('www.example.com')
+
+ visit(project_path(project))
end
include_examples 'shows details of non empty project'
diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
index 189aa45ff75..9b51e867156 100644
--- a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
+++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
visit project_path(project)
end
- it 'Project buttons are not visible' do
+ it 'project buttons are not visible' do
visit project_path(project)
page.within('.project-buttons') do
@@ -165,7 +165,7 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
context 'when the project does not have a README' do
it 'shows the single file editor "Add README" button' do
- allow(project.repository).to receive(:readme).and_return(nil)
+ allow(project.repository).to receive(:readme_path).and_return(nil)
visit project_path(project)
diff --git a/spec/features/projects/terraform_spec.rb b/spec/features/projects/terraform_spec.rb
index 2680dfb2b13..dfa4dad8490 100644
--- a/spec/features/projects/terraform_spec.rb
+++ b/spec/features/projects/terraform_spec.rb
@@ -4,44 +4,94 @@ require 'spec_helper'
RSpec.describe 'Terraform', :js do
let_it_be(:project) { create(:project) }
+ let_it_be(:terraform_state) { create(:terraform_state, :locked, :with_version, project: project) }
- let(:user) { project.creator }
+ context 'when user is a terraform administrator' do
+ let(:admin) { project.creator }
- before do
- gitlab_sign_in(user)
- end
-
- context 'when user does not have any terraform states and visits index page' do
before do
- visit project_terraform_index_path(project)
+ gitlab_sign_in(admin)
end
- it 'sees an empty state' do
- expect(page).to have_content('Get started with Terraform')
+ context 'when user does not have any terraform states and visits the index page' do
+ let(:empty_project) { create(:project) }
+
+ before do
+ empty_project.add_maintainer(admin)
+ visit project_terraform_index_path(empty_project)
+ end
+
+ it 'sees an empty state' do
+ expect(page).to have_content('Get started with Terraform')
+ end
end
- end
- context 'when user has a terraform state' do
- let_it_be(:terraform_state) { create(:terraform_state, :locked, project: project) }
+ context 'when user has a terraform state' do
+ context 'when user visits the index page' do
+ before do
+ visit project_terraform_index_path(project)
+ end
- context 'when user visits the index page' do
- before do
- visit project_terraform_index_path(project)
+ it 'displays a tab with states count' do
+ expect(page).to have_content("States #{project.terraform_states.size}")
+ end
+
+ it 'displays a table with terraform states' do
+ expect(page).to have_selector(
+ '[data-testid="terraform-states-table-name"]',
+ count: project.terraform_states.size
+ )
+ end
+
+ it 'displays terraform actions dropdown' do
+ expect(page).to have_selector(
+ '[data-testid*="terraform-state-actions"]',
+ count: project.terraform_states.size
+ )
+ end
+
+ it 'displays terraform information' do
+ expect(page).to have_content(terraform_state.name)
+ end
end
- it 'displays a tab with states count' do
- expect(page).to have_content("States #{project.terraform_states.size}")
+ context 'when clicking on the delete button' do
+ let(:additional_state) { create(:terraform_state, project: project) }
+
+ it 'removes the state', :aggregate_failures do
+ visit project_terraform_index_path(project)
+
+ expect(page).to have_content(additional_state.name)
+
+ find("[data-testid='terraform-state-actions-#{additional_state.name}']").click
+ find('[data-testid="terraform-state-remove"]').click
+ fill_in "terraform-state-remove-input-#{additional_state.name}", with: additional_state.name
+ click_button 'Remove'
+
+ expect(page).not_to have_content(additional_state.name)
+ expect { additional_state.reload }.to raise_error ActiveRecord::RecordNotFound
+ end
end
+ end
+ end
+
+ context 'when user is a terraform developer' do
+ let_it_be(:developer) { create(:user) }
- it 'displays a table with terraform states' do
+ before do
+ project.add_developer(developer)
+ gitlab_sign_in(developer)
+ visit project_terraform_index_path(project)
+ end
+
+ context 'when user visits the index page' do
+ it 'displays a table without an action dropdown', :aggregate_failures do
expect(page).to have_selector(
- '[data-testid="terraform-states-table"] tbody tr',
+ '[data-testid="terraform-states-table-name"]',
count: project.terraform_states.size
)
- end
- it 'displays terraform information' do
- expect(page).to have_content(terraform_state.name)
+ expect(page).not_to have_selector('[data-testid*="terraform-state-actions"]')
end
end
end
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index b204ae76e07..feb5f348256 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe 'User creates a project', :js do
it 'creates a new project' do
visit(new_project_path)
+ find('[data-qa-selector="blank_project_link"]').click
fill_in(:project_name, with: 'Empty')
page.within('#content-body') do
@@ -39,6 +40,7 @@ RSpec.describe 'User creates a project', :js do
it 'creates a new project' do
visit(new_project_path)
+ find('[data-qa-selector="blank_project_link"]').click
fill_in :project_name, with: 'A Subgroup Project'
fill_in :project_path, with: 'a-subgroup-project'
@@ -67,6 +69,7 @@ RSpec.describe 'User creates a project', :js do
it 'creates a new project' do
visit(new_project_path)
+ find('[data-qa-selector="blank_project_link"]').click
fill_in :project_name, with: 'a-new-project'
fill_in :project_path, with: 'a-new-project'
diff --git a/spec/features/projects/user_sorts_projects_spec.rb b/spec/features/projects/user_sorts_projects_spec.rb
new file mode 100644
index 00000000000..6a5ed49f1a6
--- /dev/null
+++ b/spec/features/projects/user_sorts_projects_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User sorts projects and order persists' do
+ include CookieHelper
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:group_member) { create(:group_member, :maintainer, user: user, group: group) }
+ let_it_be(:project) { create(:project, :public, group: group) }
+
+ shared_examples_for "sort order persists across all views" do |project_paths_label, group_paths_label|
+ it "is set on the dashboard_projects_path" do
+ visit(dashboard_projects_path)
+
+ expect(find('.dropdown-menu a.is-active', text: project_paths_label)).to have_content(project_paths_label)
+ end
+
+ it "is set on the explore_projects_path" do
+ visit(explore_projects_path)
+
+ expect(find('.dropdown-menu a.is-active', text: project_paths_label)).to have_content(project_paths_label)
+ end
+
+ it "is set on the group_canonical_path" do
+ visit(group_canonical_path(group))
+
+ expect(find('.dropdown-menu a.is-active', text: group_paths_label)).to have_content(group_paths_label)
+ end
+
+ it "is set on the details_group_path" do
+ visit(details_group_path(group))
+
+ expect(find('.dropdown-menu a.is-active', text: group_paths_label)).to have_content(group_paths_label)
+ end
+ end
+
+ context "from explore projects" do
+ before do
+ sign_in(user)
+ visit(explore_projects_path)
+ find('#sort-projects-dropdown').click
+ first(:link, 'Last updated').click
+ end
+
+ it_behaves_like "sort order persists across all views", "Last updated", "Last updated"
+ end
+
+ context 'from dashboard projects' do
+ before do
+ sign_in(user)
+ visit(dashboard_projects_path)
+ find('#sort-projects-dropdown').click
+ first(:link, 'Name').click
+ end
+
+ it_behaves_like "sort order persists across all views", "Name", "Name"
+ end
+
+ context 'from group homepage' do
+ before do
+ sign_in(user)
+ visit(group_canonical_path(group))
+ find('button.dropdown-menu-toggle').click
+ first(:link, 'Last created').click
+ end
+
+ it_behaves_like "sort order persists across all views", "Created date", "Last created"
+ end
+
+ context 'from group details' do
+ before do
+ sign_in(user)
+ visit(details_group_path(group))
+ find('button.dropdown-menu-toggle').click
+ first(:link, 'Most stars').click
+ end
+
+ it_behaves_like "sort order persists across all views", "Stars", "Most stars"
+ end
+end
diff --git a/spec/features/projects/user_views_empty_project_spec.rb b/spec/features/projects/user_views_empty_project_spec.rb
index 9202d18b86f..3d4d9a7ea96 100644
--- a/spec/features/projects/user_views_empty_project_spec.rb
+++ b/spec/features/projects/user_views_empty_project_spec.rb
@@ -7,12 +7,9 @@ RSpec.describe 'User views an empty project' do
let(:user) { create(:user) }
shared_examples 'allowing push to default branch' do
- before do
- sign_in(user)
+ it 'shows push-to-master instructions' do
visit project_path(project)
- end
- it 'shows push-to-master instructions' do
expect(page).to have_content('git push -u origin master')
end
end
@@ -20,6 +17,7 @@ RSpec.describe 'User views an empty project' do
describe 'as a maintainer' do
before do
project.add_maintainer(user)
+ sign_in(user)
end
it_behaves_like 'allowing push to default branch'
@@ -28,17 +26,33 @@ RSpec.describe 'User views an empty project' do
describe 'as an admin' do
let(:user) { create(:user, :admin) }
- it_behaves_like 'allowing push to default branch'
+ context 'when admin mode is enabled' do
+ before do
+ sign_in(user)
+ gitlab_enable_admin_mode_sign_in(user)
+ end
+
+ it_behaves_like 'allowing push to default branch'
+ end
+
+ context 'when admin mode is disabled' do
+ it 'does not show push-to-master instructions' do
+ visit project_path(project)
+
+ expect(page).not_to have_content('git push -u origin master')
+ end
+ end
end
describe 'as a developer' do
before do
project.add_developer(user)
sign_in(user)
- visit project_path(project)
end
it 'does not show push-to-master instructions' do
+ visit project_path(project)
+
expect(page).not_to have_content('git push -u origin master')
end
end
diff --git a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
deleted file mode 100644
index 83679c6bd1d..00000000000
--- a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Projects > Wiki > User views Git access wiki page' do
- let(:user) { create(:user) }
- let(:project) { create(:project, :wiki_repo, :public) }
- let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') }
-
- before do
- sign_in(user)
- end
-
- it 'Visit Wiki Page Current Commit' do
- visit project_wiki_path(project, wiki_page)
-
- click_link 'Clone repository'
- expect(page).to have_text("Clone repository #{project.wiki.full_path}")
- expect(page).to have_text(project.wiki.http_url_to_repo)
- end
-end
diff --git a/spec/features/projects/wikis_spec.rb b/spec/features/projects/wikis_spec.rb
index 1c66ad81145..621f8c71b20 100644
--- a/spec/features/projects/wikis_spec.rb
+++ b/spec/features/projects/wikis_spec.rb
@@ -17,4 +17,5 @@ RSpec.describe 'Project wikis' do
it_behaves_like 'User views a wiki page'
it_behaves_like 'User views wiki pages'
it_behaves_like 'User views wiki sidebar'
+ it_behaves_like 'User views Git access wiki page'
end
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 9b5f4ca6d48..618a256d4fb 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Project' do
shared_examples 'creates from template' do |template, sub_template_tab = nil|
it "is created from template", :js do
- find('#create-from-template-tab').click
+ find('[data-qa-selector="create_from_template_link"]').click
find(".project-template #{sub_template_tab}").click if sub_template_tab
find("label[for=#{template.name}]").click
fill_in("project_name", with: template.name)
@@ -34,7 +34,7 @@ RSpec.describe 'Project' do
end
context 'create with sample data template' do
- it_behaves_like 'creates from template', Gitlab::SampleDataTemplate.find(:basic), '.sample-data-templates-tab'
+ it_behaves_like 'creates from template', Gitlab::SampleDataTemplate.find(:sample)
end
end
@@ -47,9 +47,7 @@ RSpec.describe 'Project' do
end
it 'shows the command in a popover', :js do
- page.within '.profile-settings-sidebar' do
- click_link 'Show command'
- end
+ click_link 'Show command'
expect(page).to have_css('.popover .push-to-create-popover #push_to_create_tip')
expect(page).to have_content 'Private projects can be created in your personal namespace with:'
@@ -61,7 +59,7 @@ RSpec.describe 'Project' do
let(:path) { project_path(project) }
before do
- sign_in(create(:admin))
+ sign_in(project.owner)
end
it 'parses Markdown' do
@@ -125,7 +123,7 @@ RSpec.describe 'Project' do
let(:path) { project_path(project) }
before do
- sign_in(create(:admin))
+ sign_in(project.owner)
visit path
end
@@ -156,7 +154,7 @@ RSpec.describe 'Project' do
let(:path) { project_path(project) }
before do
- sign_in(create(:admin))
+ sign_in(project.owner)
visit path
end
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index 3be01595502..95d268ab1be 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -73,6 +73,7 @@ RSpec.describe 'Protected Branches', :js do
context 'logged in as admin' do
before do
sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
end
describe "explicit protected branches" do
diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb
index 12e4bbde293..25447db3c8d 100644
--- a/spec/features/protected_tags_spec.rb
+++ b/spec/features/protected_tags_spec.rb
@@ -5,8 +5,8 @@ require 'spec_helper'
RSpec.describe 'Protected Tags', :js do
include ProtectedTagHelpers
- let(:user) { create(:user, :admin) }
let(:project) { create(:project, :repository) }
+ let(:user) { project.owner }
before do
sign_in(user)
diff --git a/spec/features/registrations/experience_level_spec.rb b/spec/features/registrations/experience_level_spec.rb
index 06d380926cd..25496e2fef1 100644
--- a/spec/features/registrations/experience_level_spec.rb
+++ b/spec/features/registrations/experience_level_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Experience level screen' do
before do
group.add_owner(user)
gitlab_sign_in(user)
- stub_experiment_for_user(onboarding_issues: true)
+ stub_experiment_for_subject(onboarding_issues: true)
visit users_sign_up_experience_level_path(namespace_path: group.to_param)
end
@@ -23,14 +23,14 @@ RSpec.describe 'Experience level screen' do
it 'shows the option for novice' do
is_expected.to have_content('Novice')
- is_expected.to have_content('I’m not very familiar with the basics of project management and DevOps')
- is_expected.to have_content('Show me everything')
+ is_expected.to have_content('I’m not familiar with the basics of DevOps')
+ is_expected.to have_content('Show me the basics')
end
it 'shows the option for experienced' do
is_expected.to have_content('Experienced')
- is_expected.to have_content('I’m familiar with the basics of project management and DevOps')
- is_expected.to have_content('Show me more advanced stuff')
+ is_expected.to have_content('I’m familiar with the basics of DevOps')
+ is_expected.to have_content('Show me advanced features')
end
it 'does not display any flash messages' do
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 9697e10c3d1..5cddad81927 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -179,16 +179,32 @@ RSpec.describe 'Runners' do
context 'when a project has disabled shared_runners' do
let(:project) { create(:project, shared_runners_enabled: false) }
- before do
- project.add_maintainer(user)
+ context 'when feature flag: vueify_shared_runners_toggle is disabled' do
+ before do
+ stub_feature_flags(vueify_shared_runners_toggle: false)
+ project.add_maintainer(user)
+ end
+
+ it 'user enables shared runners' do
+ visit project_runners_path(project)
+
+ click_on 'Enable shared runners'
+
+ expect(page.find('.shared-runners-description')).to have_content('Disable shared runners')
+ expect(page).not_to have_selector('#toggle-shared-runners-form')
+ end
end
- it 'user enables shared runners' do
- visit project_runners_path(project)
+ context 'when feature flag: vueify_shared_runners_toggle is enabled' do
+ before do
+ project.add_maintainer(user)
+ end
- click_on 'Enable shared runners'
+ it 'user enables shared runners' do
+ visit project_runners_path(project)
- expect(page.find('.shared-runners-description')).to have_content('Disable shared runners')
+ expect(page).to have_selector('#toggle-shared-runners-form')
+ end
end
end
diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb
index f761bd30baf..ee3717b3e42 100644
--- a/spec/features/search/user_searches_for_code_spec.rb
+++ b/spec/features/search/user_searches_for_code_spec.rb
@@ -27,8 +27,13 @@ RSpec.describe 'User searches for code' do
context 'when on a project page', :js do
before do
visit(search_path)
- find('.js-search-project-dropdown').click
- find('[data-testid="project-filter"]').click_link(project.full_name)
+ find('[data-testid="project-filter"]').click
+
+ wait_for_requests
+
+ page.within('[data-testid="project-filter"]') do
+ click_on(project.full_name)
+ end
end
include_examples 'top right search form'
diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb
index e2ae2738d2f..e253b9f2f7a 100644
--- a/spec/features/search/user_searches_for_issues_spec.rb
+++ b/spec/features/search/user_searches_for_issues_spec.rb
@@ -85,8 +85,13 @@ RSpec.describe 'User searches for issues', :js do
context 'when on a project page' do
it 'finds an issue' do
- find('.js-search-project-dropdown').click
- find('[data-testid="project-filter"]').click_link(project.full_name)
+ find('[data-testid="project-filter"]').click
+
+ wait_for_requests
+
+ page.within('[data-testid="project-filter"]') do
+ click_on(project.full_name)
+ end
search_for_issue(issue1.title)
diff --git a/spec/features/search/user_searches_for_merge_requests_spec.rb b/spec/features/search/user_searches_for_merge_requests_spec.rb
index 6f8f6303b66..21e8075739f 100644
--- a/spec/features/search/user_searches_for_merge_requests_spec.rb
+++ b/spec/features/search/user_searches_for_merge_requests_spec.rb
@@ -30,8 +30,13 @@ RSpec.describe 'User searches for merge requests', :js do
context 'when on a project page' do
it 'finds a merge request' do
- find('.js-search-project-dropdown').click
- find('[data-testid="project-filter"]').click_link(project.full_name)
+ find('[data-testid="project-filter"]').click
+
+ wait_for_requests
+
+ page.within('[data-testid="project-filter"]') do
+ click_on(project.full_name)
+ end
fill_in('dashboard_search', with: merge_request1.title)
find('.btn-search').click
diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb
index 1a2227db214..f4df91dbc08 100644
--- a/spec/features/search/user_searches_for_milestones_spec.rb
+++ b/spec/features/search/user_searches_for_milestones_spec.rb
@@ -30,8 +30,13 @@ RSpec.describe 'User searches for milestones', :js do
context 'when on a project page' do
it 'finds a milestone' do
- find('.js-search-project-dropdown').click
- find('[data-testid="project-filter"]').click_link(project.full_name)
+ find('[data-testid="project-filter"]').click
+
+ wait_for_requests
+
+ page.within('[data-testid="project-filter"]') do
+ click_on(project.full_name)
+ end
fill_in('dashboard_search', with: milestone1.title)
find('.btn-search').click
diff --git a/spec/features/search/user_searches_for_wiki_pages_spec.rb b/spec/features/search/user_searches_for_wiki_pages_spec.rb
index 6bf1407fd4f..72bd1193fc9 100644
--- a/spec/features/search/user_searches_for_wiki_pages_spec.rb
+++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb
@@ -18,8 +18,13 @@ RSpec.describe 'User searches for wiki pages', :js do
shared_examples 'search wiki blobs' do
it 'finds a page' do
- find('.js-search-project-dropdown').click
- find('[data-testid="project-filter"]').click_link(project.full_name)
+ find('[data-testid="project-filter"]').click
+
+ wait_for_requests
+
+ page.within('[data-testid="project-filter"]') do
+ click_on(project.full_name)
+ end
fill_in('dashboard_search', with: search_term)
find('.btn-search').click
diff --git a/spec/features/search/user_uses_search_filters_spec.rb b/spec/features/search/user_uses_search_filters_spec.rb
index bd77e6003e3..86017ca64c5 100644
--- a/spec/features/search/user_uses_search_filters_spec.rb
+++ b/spec/features/search/user_uses_search_filters_spec.rb
@@ -28,13 +28,15 @@ RSpec.describe 'User uses search filters', :js do
expect(find('[data-testid="group-filter"]')).to have_content(group.name)
- page.within('[data-testid="project-filter"]') do
- find('.js-search-project-dropdown').click
+ find('[data-testid="project-filter"]').click
- wait_for_requests
+ wait_for_requests
- expect(page).to have_link(group_project.full_name)
+ page.within('[data-testid="project-filter"]') do
+ click_on(group_project.full_name)
end
+
+ expect(find('[data-testid="project-filter"]')).to have_content(group_project.full_name)
end
context 'when the group filter is set' do
@@ -58,15 +60,15 @@ RSpec.describe 'User uses search filters', :js do
it 'shows a project' do
visit search_path
- page.within('[data-testid="project-filter"]') do
- find('.js-search-project-dropdown').click
+ find('[data-testid="project-filter"]').click
- wait_for_requests
+ wait_for_requests
- click_link(project.full_name)
+ page.within('[data-testid="project-filter"]') do
+ click_on(project.full_name)
end
- expect(find('.js-search-project-dropdown')).to have_content(project.full_name)
+ expect(find('[data-testid="project-filter"]')).to have_content(project.full_name)
end
context 'when the project filter is set' do
@@ -78,10 +80,10 @@ RSpec.describe 'User uses search filters', :js do
describe 'clear filter button' do
it 'removes Project filters' do
- link = find('[data-testid="project-filter"] .js-search-clear')
- params = CGI.parse(URI.parse(link[:href]).query)
+ find('[data-testid="project-filter"] [data-testid="clear-icon"]').click
+ wait_for_requests
- expect(params).not_to include(:project_id)
+ expect(page).to have_current_path(search_path(search: "test"))
end
end
end
diff --git a/spec/features/security/admin_access_spec.rb b/spec/features/security/admin_access_spec.rb
index 38f00f399f3..8070ae066e7 100644
--- a/spec/features/security/admin_access_spec.rb
+++ b/spec/features/security/admin_access_spec.rb
@@ -8,7 +8,14 @@ RSpec.describe "Admin::Projects" do
describe "GET /admin/projects" do
subject { admin_projects_path }
- it { is_expected.to be_allowed_for :admin }
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it { is_expected.to be_allowed_for :admin }
+ end
+
+ context 'when admin mode is disabled' do
+ it { is_expected.to be_denied_for :admin }
+ end
+
it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :visitor }
end
@@ -16,7 +23,14 @@ RSpec.describe "Admin::Projects" do
describe "GET /admin/users" do
subject { admin_users_path }
- it { is_expected.to be_allowed_for :admin }
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it { is_expected.to be_allowed_for :admin }
+ end
+
+ context 'when admin mode is disabled' do
+ it { is_expected.to be_denied_for :admin }
+ end
+
it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :visitor }
end
@@ -24,7 +38,14 @@ RSpec.describe "Admin::Projects" do
describe "GET /admin/hooks" do
subject { admin_hooks_path }
- it { is_expected.to be_allowed_for :admin }
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it { is_expected.to be_allowed_for :admin }
+ end
+
+ context 'when admin mode is disabled' do
+ it { is_expected.to be_denied_for :admin }
+ end
+
it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :visitor }
end
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index 051bd601c1d..cb9f9a6e680 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -102,7 +102,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/-/settings/ci_cd" do
subject { project_settings_ci_cd_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -116,7 +117,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/-/settings/repository" do
subject { project_settings_repository_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -146,7 +148,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/edit" do
subject { edit_project_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -160,7 +163,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/deploy_keys" do
subject { project_deploy_keys_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -190,7 +194,8 @@ RSpec.describe "Internal Project Access" do
subject { edit_project_issue_path(project, issue) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -218,7 +223,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/snippets/new" do
subject { new_project_snippet_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -246,7 +252,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/-/merge_requests/new" do
subject { project_new_merge_request_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -302,7 +309,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/-/settings/integrations" do
subject { project_settings_integrations_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -367,7 +375,8 @@ RSpec.describe "Internal Project Access" do
project.update(public_builds: false)
end
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -406,7 +415,8 @@ RSpec.describe "Internal Project Access" do
project.update(public_builds: false)
end
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -445,7 +455,8 @@ RSpec.describe "Internal Project Access" do
project.update(public_builds: false)
end
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -460,7 +471,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/pipeline_schedules" do
subject { project_pipeline_schedules_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is disabled') { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -474,7 +486,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/-/environments" do
subject { project_environments_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is disabled') { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -490,7 +503,8 @@ RSpec.describe "Internal Project Access" do
subject { project_environment_path(project, environment) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is disabled') { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -506,7 +520,8 @@ RSpec.describe "Internal Project Access" do
subject { project_environment_deployments_path(project, environment) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is disabled') { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -520,7 +535,8 @@ RSpec.describe "Internal Project Access" do
describe "GET /:project_path/-/environments/new" do
subject { new_project_environment_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index e891e79db70..dda218c5de5 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -18,7 +18,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path" do
subject { project_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -32,7 +33,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/tree/master" do
subject { project_tree_path(project, project.repository.root_ref) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -46,7 +48,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/commits/master" do
subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -60,7 +63,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/commit/:sha" do
subject { project_commit_path(project, project.repository.commit) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -74,7 +78,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/compare" do
subject { project_compare_index_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -88,7 +93,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/project_members" do
subject { project_project_members_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -102,7 +108,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/settings/ci_cd" do
subject { project_settings_ci_cd_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -116,7 +123,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/settings/repository" do
subject { project_settings_repository_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -132,7 +140,8 @@ RSpec.describe "Private Project Access" do
subject { project_blob_path(project, File.join(commit.id, '.gitignore')) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -146,7 +155,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/edit" do
subject { edit_project_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -160,7 +170,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/deploy_keys" do
subject { project_deploy_keys_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -174,7 +185,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/issues" do
subject { project_issues_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -190,7 +202,8 @@ RSpec.describe "Private Project Access" do
subject { edit_project_issue_path(project, issue) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -204,7 +217,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/snippets" do
subject { project_snippets_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -218,7 +232,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/merge_requests" do
subject { project_merge_requests_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -239,7 +254,8 @@ RSpec.describe "Private Project Access" do
end
end
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -260,7 +276,8 @@ RSpec.describe "Private Project Access" do
end
end
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -274,7 +291,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/settings/integrations" do
subject { project_settings_integrations_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -288,7 +306,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/pipelines" do
subject { project_pipelines_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -316,7 +335,8 @@ RSpec.describe "Private Project Access" do
subject { project_pipeline_path(project, pipeline) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -342,7 +362,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/builds" do
subject { project_jobs_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -371,7 +392,8 @@ RSpec.describe "Private Project Access" do
subject { project_job_path(project, build.id) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -405,7 +427,8 @@ RSpec.describe "Private Project Access" do
subject { trace_project_job_path(project, build.id) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -435,7 +458,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/environments" do
subject { project_environments_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -451,7 +475,8 @@ RSpec.describe "Private Project Access" do
subject { project_environment_path(project, environment) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -467,7 +492,8 @@ RSpec.describe "Private Project Access" do
subject { project_environment_deployments_path(project, environment) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -481,7 +507,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/environments/new" do
subject { new_project_environment_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -495,7 +522,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/pipeline_schedules" do
subject { project_pipeline_schedules_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -509,7 +537,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/pipeline_schedules/new" do
subject { new_project_pipeline_schedule_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -523,7 +552,8 @@ RSpec.describe "Private Project Access" do
describe "GET /:project_path/-/environments/new" do
subject { new_project_pipeline_schedule_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -545,7 +575,8 @@ RSpec.describe "Private Project Access" do
subject { project_container_registry_index_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 75993959f6e..f2dbab72a48 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -102,7 +102,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/-/settings/ci_cd" do
subject { project_settings_ci_cd_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -116,7 +117,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/-/settings/repository" do
subject { project_settings_repository_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -181,7 +183,8 @@ RSpec.describe "Public Project Access" do
project.update(public_builds: false)
end
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -220,7 +223,8 @@ RSpec.describe "Public Project Access" do
project.update(public_builds: false)
end
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -259,7 +263,8 @@ RSpec.describe "Public Project Access" do
project.update(public_builds: false)
end
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -274,7 +279,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/pipeline_schedules" do
subject { project_pipeline_schedules_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is disabled') { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -288,7 +294,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/-/environments" do
subject { project_environments_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is disabled') { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -304,7 +311,8 @@ RSpec.describe "Public Project Access" do
subject { project_environment_path(project, environment) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is disabled') { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -320,7 +328,8 @@ RSpec.describe "Public Project Access" do
subject { project_environment_deployments_path(project, environment) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is disabled') { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -334,7 +343,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/-/environments/new" do
subject { new_project_environment_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -363,7 +373,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/edit" do
subject { edit_project_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -377,7 +388,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/deploy_keys" do
subject { project_deploy_keys_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
@@ -407,7 +419,8 @@ RSpec.describe "Public Project Access" do
subject { edit_project_issue_path(project, issue) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -435,7 +448,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/snippets/new" do
subject { new_project_snippet_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -463,7 +477,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/-/merge_requests/new" do
subject { project_new_merge_request_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -519,7 +534,8 @@ RSpec.describe "Public Project Access" do
describe "GET /:project_path/-/settings/integrations" do
subject { project_settings_integrations_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_denied_for(:developer).of(project) }
diff --git a/spec/features/security/project/snippet/internal_access_spec.rb b/spec/features/security/project/snippet/internal_access_spec.rb
index 0667a2fd48a..12237863188 100644
--- a/spec/features/security/project/snippet/internal_access_spec.rb
+++ b/spec/features/security/project/snippet/internal_access_spec.rb
@@ -26,7 +26,8 @@ RSpec.describe "Internal Project Snippets Access" do
describe "GET /:project_path/snippets/new" do
subject { new_project_snippet_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -55,7 +56,8 @@ RSpec.describe "Internal Project Snippets Access" do
context "for a private snippet" do
subject { project_snippet_path(project, private_snippet) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -85,7 +87,8 @@ RSpec.describe "Internal Project Snippets Access" do
context "for a private snippet" do
subject { raw_project_snippet_path(project, private_snippet) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb
index 0c97b012ad1..0f7ae06a6c5 100644
--- a/spec/features/security/project/snippet/private_access_spec.rb
+++ b/spec/features/security/project/snippet/private_access_spec.rb
@@ -12,7 +12,8 @@ RSpec.describe "Private Project Snippets Access" do
describe "GET /:project_path/snippets" do
subject { project_snippets_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -26,7 +27,8 @@ RSpec.describe "Private Project Snippets Access" do
describe "GET /:project_path/snippets/new" do
subject { new_project_snippet_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -40,7 +42,8 @@ RSpec.describe "Private Project Snippets Access" do
describe "GET /:project_path/snippets/:id for a private snippet" do
subject { project_snippet_path(project, private_snippet) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -54,7 +57,8 @@ RSpec.describe "Private Project Snippets Access" do
describe "GET /:project_path/snippets/:id/raw for a private snippet" do
subject { raw_project_snippet_path(project, private_snippet) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
diff --git a/spec/features/security/project/snippet/public_access_spec.rb b/spec/features/security/project/snippet/public_access_spec.rb
index 20a271f9c0e..2ae08205602 100644
--- a/spec/features/security/project/snippet/public_access_spec.rb
+++ b/spec/features/security/project/snippet/public_access_spec.rb
@@ -27,7 +27,8 @@ RSpec.describe "Public Project Snippets Access" do
describe "GET /:project_path/snippets/new" do
subject { new_project_snippet_path(project) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -70,7 +71,8 @@ RSpec.describe "Public Project Snippets Access" do
context "for a private snippet" do
subject { project_snippet_path(project, private_snippet) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
@@ -114,7 +116,8 @@ RSpec.describe "Public Project Snippets Access" do
context "for a private snippet" do
subject { raw_project_snippet_path(project, private_snippet) }
- it { is_expected.to be_allowed_for(:admin) }
+ it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
+ it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
diff --git a/spec/features/snippets/private_snippets_spec.rb b/spec/features/snippets/private_snippets_spec.rb
index 03745c1025a..7ff27419cf7 100644
--- a/spec/features/snippets/private_snippets_spec.rb
+++ b/spec/features/snippets/private_snippets_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe 'Private Snippets', :js do
sign_in(user)
end
- it 'Private Snippet renders for creator' do
+ it 'private Snippet renders for creator' do
visit snippet_path(private_snippet)
wait_for_requests
diff --git a/spec/features/snippets/public_snippets_spec.rb b/spec/features/snippets/public_snippets_spec.rb
index d2dc85a9614..0f27d96d8e9 100644
--- a/spec/features/snippets/public_snippets_spec.rb
+++ b/spec/features/snippets/public_snippets_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe 'Public Snippets', :js do
let(:public_snippet) { create(:personal_snippet, :public, :repository) }
let(:content) { public_snippet.blobs.first.data.strip! }
- it 'Unauthenticated user should see public snippets' do
+ it 'unauthenticated user should see public snippets' do
url = Gitlab::UrlBuilder.build(public_snippet)
visit snippet_path(public_snippet)
@@ -18,7 +18,7 @@ RSpec.describe 'Public Snippets', :js do
expect(page).to have_field('Share', readonly: true, with: url)
end
- it 'Unauthenticated user should see raw public snippets' do
+ it 'unauthenticated user should see raw public snippets' do
visit raw_snippet_path(public_snippet)
expect(page).to have_content(content)
diff --git a/spec/features/snippets/search_snippets_spec.rb b/spec/features/snippets/search_snippets_spec.rb
index 4f299edc9da..46bc3b7caad 100644
--- a/spec/features/snippets/search_snippets_spec.rb
+++ b/spec/features/snippets/search_snippets_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'Search Snippets' do
- it 'User searches for snippets by title' do
+ it 'user searches for snippets by title' do
public_snippet = create(:personal_snippet, :public, title: 'Beginning and Middle')
private_snippet = create(:personal_snippet, :private, title: 'Middle and End')
diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb
index 1e51210c2b8..ca050daa62a 100644
--- a/spec/features/snippets/user_creates_snippet_spec.rb
+++ b/spec/features/snippets/user_creates_snippet_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe 'User creates snippet', :js do
snippet_fill_in_form(title: title, content: file_content, description: md_description)
end
- it 'Authenticated user creates a snippet' do
+ it 'authenticated user creates a snippet' do
fill_form
click_button('Create snippet')
diff --git a/spec/features/snippets/user_snippets_spec.rb b/spec/features/snippets/user_snippets_spec.rb
index a313dc3b26a..fe39208213a 100644
--- a/spec/features/snippets/user_snippets_spec.rb
+++ b/spec/features/snippets/user_snippets_spec.rb
@@ -13,13 +13,13 @@ RSpec.describe 'User Snippets' do
visit dashboard_snippets_path
end
- it 'View all of my snippets' do
+ it 'view all of my snippets' do
expect(page).to have_link(public_snippet.title, href: snippet_path(public_snippet))
expect(page).to have_link(internal_snippet.title, href: snippet_path(internal_snippet))
expect(page).to have_link(private_snippet.title, href: snippet_path(private_snippet))
end
- it 'View my public snippets' do
+ it 'view my public snippets' do
page.within('.snippet-scope-menu') do
click_link "Public"
end
@@ -29,7 +29,7 @@ RSpec.describe 'User Snippets' do
expect(page).not_to have_content(private_snippet.title)
end
- it 'View my internal snippets' do
+ it 'view my internal snippets' do
page.within('.snippet-scope-menu') do
click_link "Internal"
end
@@ -39,7 +39,7 @@ RSpec.describe 'User Snippets' do
expect(page).not_to have_content(private_snippet.title)
end
- it 'View my private snippets' do
+ it 'view my private snippets' do
page.within('.snippet-scope-menu') do
click_link "Private"
end
diff --git a/spec/features/usage_stats_consent_spec.rb b/spec/features/usage_stats_consent_spec.rb
index 04bdf25acc0..6fa1d7d76b5 100644
--- a/spec/features/usage_stats_consent_spec.rb
+++ b/spec/features/usage_stats_consent_spec.rb
@@ -19,6 +19,7 @@ RSpec.describe 'Usage stats consent' do
end
gitlab_sign_in(user)
+ gitlab_enable_admin_mode_sign_in(user)
end
it 'hides the banner permanently when sets usage stats' do
diff --git a/spec/features/users/active_sessions_spec.rb b/spec/features/users/active_sessions_spec.rb
index 8e2e16e555e..fab9f0884ae 100644
--- a/spec/features/users/active_sessions_spec.rb
+++ b/spec/features/users/active_sessions_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'Active user sessions', :clean_gitlab_redis_shared_state do
- it 'Successful login adds a new active user login' do
+ it 'successful login adds a new active user login' do
now = Time.zone.parse('2018-03-12 09:06')
Timecop.freeze(now) do
user = create(:user)
@@ -26,7 +26,7 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_shared_state do
end
end
- it 'Successful login cleans up obsolete entries' do
+ it 'successful login cleans up obsolete entries' do
user = create(:user)
Gitlab::Redis::SharedState.with do |redis|
@@ -40,7 +40,7 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_shared_state do
end
end
- it 'Sessionless login does not clean up obsolete entries' do
+ it 'sessionless login does not clean up obsolete entries' do
user = create(:user)
personal_access_token = create(:personal_access_token, user: user)
@@ -56,7 +56,7 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_shared_state do
end
end
- it 'Logout deletes the active user login' do
+ it 'logout deletes the active user login' do
user = create(:user)
gitlab_sign_in(user)
expect(current_path).to eq root_path
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 0761c1871d3..e4a8d836413 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -742,28 +742,65 @@ RSpec.describe 'Login' do
end
context 'when the user did not enable 2FA' do
- it 'asks to set 2FA before asking to accept the terms' do
- expect(authentication_metrics)
- .to increment(:user_authenticated_counter)
+ context 'when `vue_2fa_recovery_codes` feature flag is disabled' do
+ before do
+ stub_feature_flags(vue_2fa_recovery_codes: false)
+ end
- visit new_user_session_path
+ it 'asks to set 2FA before asking to accept the terms' do
+ expect(authentication_metrics)
+ .to increment(:user_authenticated_counter)
- fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ visit new_user_session_path
- click_button 'Sign in'
+ fill_in 'user_login', with: user.email
+ fill_in 'user_password', with: '12345678'
- expect_to_be_on_terms_page
- click_button 'Accept terms'
+ click_button 'Sign in'
+
+ expect_to_be_on_terms_page
+ click_button 'Accept terms'
+
+ expect(current_path).to eq(profile_two_factor_auth_path)
+
+ fill_in 'pin_code', with: user.reload.current_otp
- expect(current_path).to eq(profile_two_factor_auth_path)
+ click_button 'Register with two-factor app'
- fill_in 'pin_code', with: user.reload.current_otp
+ expect(page).to have_content('Congratulations! You have enabled Two-factor Authentication!')
- click_button 'Register with two-factor app'
- click_link 'Proceed'
+ click_link 'Proceed'
- expect(current_path).to eq(profile_account_path)
+ expect(current_path).to eq(profile_account_path)
+ end
+ end
+
+ context 'when `vue_2fa_recovery_codes` feature flag is enabled' do
+ it 'asks to set 2FA before asking to accept the terms', :js do
+ expect(authentication_metrics)
+ .to increment(:user_authenticated_counter)
+
+ visit new_user_session_path
+
+ fill_in 'user_login', with: user.email
+ fill_in 'user_password', with: '12345678'
+
+ click_button 'Sign in'
+
+ expect_to_be_on_terms_page
+ click_button 'Accept terms'
+
+ expect(current_path).to eq(profile_two_factor_auth_path)
+
+ fill_in 'pin_code', with: user.reload.current_otp
+
+ click_button 'Register with two-factor app'
+ click_button 'Copy codes'
+ click_link 'Proceed'
+
+ expect(current_path).to eq(profile_account_path)
+ expect(page).to have_content('Congratulations! You have enabled Two-factor Authentication!')
+ end
end
end
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index aebe2cc602d..6aeb3023db8 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe 'User page' do
let_it_be(:user) { create(:user, bio: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)') }
- subject { visit(user_path(user)) }
+ subject(:visit_profile) { visit(user_path(user)) }
context 'with public profile' do
it 'shows all the tabs' do
@@ -123,6 +123,47 @@ RSpec.describe 'User page' do
end
end
+ context 'with unconfirmed user' do
+ let_it_be(:user) { create(:user, :unconfirmed) }
+
+ shared_examples 'unconfirmed user profile' do
+ before do
+ visit_profile
+ end
+
+ it 'shows user name as unconfirmed' do
+ expect(page).to have_css(".cover-title", text: 'Unconfirmed user')
+ end
+
+ it 'shows no tab' do
+ expect(page).to have_css("div.profile-header")
+ expect(page).not_to have_css("ul.nav-links")
+ end
+
+ it 'shows no additional fields' do
+ expect(page).not_to have_css(".profile-user-bio")
+ expect(page).not_to have_css(".profile-link-holder")
+ end
+
+ it 'shows private profile message' do
+ expect(page).to have_content("This user has a private profile")
+ end
+ end
+
+ context 'when visited by an authenticated user' do
+ before do
+ authenticated_user = create(:user)
+ sign_in(authenticated_user)
+ end
+
+ it_behaves_like 'unconfirmed user profile'
+ end
+
+ context 'when visited by an unauthenticated user' do
+ it_behaves_like 'unconfirmed user profile'
+ end
+ end
+
it 'shows the status if there was one' do
create(:user_status, user: user, message: "Working hard!")