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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 16:18:24 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 16:18:24 +0300
commit0653e08efd039a5905f3fa4f6e9cef9f5d2f799c (patch)
tree4dcc884cf6d81db44adae4aa99f8ec1233a41f55 /spec/features
parent744144d28e3e7fddc117924fef88de5d9674fe4c (diff)
Add latest changes from gitlab-org/gitlab@14-3-stable-eev14.3.0-rc42
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_runners_spec.rb4
-rw-r--r--spec/features/admin/admin_sees_background_migrations_spec.rb39
-rw-r--r--spec/features/admin/admin_settings_spec.rb87
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb10
-rw-r--r--spec/features/atom/dashboard_issues_spec.rb16
-rw-r--r--spec/features/atom/issues_spec.rb94
-rw-r--r--spec/features/atom/merge_requests_spec.rb88
-rw-r--r--spec/features/boards/multi_select_spec.rb4
-rw-r--r--spec/features/boards/sidebar_labels_spec.rb3
-rw-r--r--spec/features/boards/user_adds_lists_to_board_spec.rb67
-rw-r--r--spec/features/clusters/cluster_health_dashboard_spec.rb4
-rw-r--r--spec/features/commit_spec.rb2
-rw-r--r--spec/features/cycle_analytics_spec.rb99
-rw-r--r--spec/features/global_search_spec.rb70
-rw-r--r--spec/features/groups/board_sidebar_spec.rb26
-rw-r--r--spec/features/groups/issues_spec.rb39
-rw-r--r--spec/features/groups/members/request_access_spec.rb2
-rw-r--r--spec/features/groups/packages_spec.rb8
-rw-r--r--spec/features/groups/settings/packages_and_registries_spec.rb5
-rw-r--r--spec/features/groups/settings/repository_spec.rb2
-rw-r--r--spec/features/groups/show_spec.rb167
-rw-r--r--spec/features/ics/dashboard_issues_spec.rb16
-rw-r--r--spec/features/ics/group_issues_spec.rb16
-rw-r--r--spec/features/ics/project_issues_spec.rb16
-rw-r--r--spec/features/incidents/user_views_incident_spec.rb2
-rw-r--r--spec/features/invites_spec.rb24
-rw-r--r--spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb10
-rw-r--r--spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb2
-rw-r--r--spec/features/issues/csv_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb9
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb3
-rw-r--r--spec/features/issues/issue_detail_spec.rb15
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb2
-rw-r--r--spec/features/issues/resource_label_events_spec.rb2
-rw-r--r--spec/features/issues/rss_spec.rb39
-rw-r--r--spec/features/issues/user_edits_issue_spec.rb1
-rw-r--r--spec/features/issues/user_views_issue_spec.rb2
-rw-r--r--spec/features/issues/user_views_issues_spec.rb6
-rw-r--r--spec/features/labels_hierarchy_spec.rb124
-rw-r--r--spec/features/merge_request/batch_comments_spec.rb4
-rw-r--r--spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb2
-rw-r--r--spec/features/merge_requests/rss_spec.rb46
-rw-r--r--spec/features/merge_requests/user_sees_empty_state_spec.rb21
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb14
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb29
-rw-r--r--spec/features/projects/ci/editor_spec.rb4
-rw-r--r--spec/features/projects/commits/user_browses_commits_spec.rb8
-rw-r--r--spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb16
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb1
-rw-r--r--spec/features/projects/jobs/permissions_spec.rb2
-rw-r--r--spec/features/projects/jobs/user_browses_job_spec.rb2
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb2
-rw-r--r--spec/features/projects/new_project_spec.rb4
-rw-r--r--spec/features/projects/package_files_spec.rb14
-rw-r--r--spec/features/projects/packages_spec.rb8
-rw-r--r--spec/features/projects/services/user_activates_slack_slash_command_spec.rb4
-rw-r--r--spec/features/projects/settings/access_tokens_spec.rb14
-rw-r--r--spec/features/projects/settings/monitor_settings_spec.rb27
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/service_desk_setting_spec.rb1
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb11
-rw-r--r--spec/features/projects/user_creates_project_spec.rb1
-rw-r--r--spec/features/registrations/experience_level_spec.rb44
-rw-r--r--spec/features/users/anonymous_sessions_spec.rb24
-rw-r--r--spec/features/users/login_spec.rb13
-rw-r--r--spec/features/users/show_spec.rb59
67 files changed, 884 insertions, 624 deletions
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 54c07985a21..8053be89ffc 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -356,6 +356,7 @@ RSpec.describe "Admin Runners" do
assigned_project = page.find('[data-testid="assigned-projects"]')
+ expect(page).to have_content('Runner assigned to project.')
expect(assigned_project).to have_content(@project2.path)
end
end
@@ -399,13 +400,14 @@ RSpec.describe "Admin Runners" do
visit admin_runner_path(runner)
end
- it 'enables specific runner for project' do
+ it 'removed specific runner from project' do
within '[data-testid="assigned-projects"]' do
click_on 'Disable'
end
new_runner_project = page.find('[data-testid="unassigned-projects"]')
+ expect(page).to have_content('Runner unassigned from project.')
expect(new_runner_project).to have_content(@project1.path)
end
end
diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb
index 11823195310..94fb3a0314f 100644
--- a/spec/features/admin/admin_sees_background_migrations_spec.rb
+++ b/spec/features/admin/admin_sees_background_migrations_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe "Admin > Admin sees background migrations" do
let_it_be(:finished_migration) { create(:batched_background_migration, table_name: 'finished', status: :finished) }
before_all do
- create(:batched_background_migration_job, batched_migration: failed_migration, batch_size: 30, status: :succeeded)
+ create(:batched_background_migration_job, batched_migration: failed_migration, batch_size: 10, min_value: 6, max_value: 15, status: :failed, attempts: 3)
end
before do
@@ -53,22 +53,35 @@ RSpec.describe "Admin > Admin sees background migrations" do
end
end
- it 'can view failed migrations' do
- visit admin_background_migrations_path
+ context 'when there are failed migrations' do
+ before do
+ allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
+ allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
+ end
+ end
- within '#content-body' do
- tab = find_link 'Failed'
- tab.click
+ it 'can view and retry them' do
+ visit admin_background_migrations_path
- expect(page).to have_current_path(admin_background_migrations_path(tab: 'failed'))
- expect(tab[:class]).to include('gl-tab-nav-item-active', 'gl-tab-nav-item-active-indigo')
+ within '#content-body' do
+ tab = find_link 'Failed'
+ tab.click
- expect(page).to have_selector('tbody tr', count: 1)
+ expect(page).to have_current_path(admin_background_migrations_path(tab: 'failed'))
+ expect(tab[:class]).to include('gl-tab-nav-item-active', 'gl-tab-nav-item-active-indigo')
+
+ expect(page).to have_selector('tbody tr', count: 1)
+
+ expect(page).to have_content(failed_migration.job_class_name)
+ expect(page).to have_content(failed_migration.table_name)
+ expect(page).to have_content('0.00%')
+ expect(page).to have_content(failed_migration.status.humanize)
- expect(page).to have_content(failed_migration.job_class_name)
- expect(page).to have_content(failed_migration.table_name)
- expect(page).to have_content('30.00%')
- expect(page).to have_content(failed_migration.status.humanize)
+ click_button('Retry')
+ expect(page).not_to have_content(failed_migration.job_class_name)
+ expect(page).not_to have_content(failed_migration.table_name)
+ expect(page).not_to have_content('0.00%')
+ end
end
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 4a0f7ccbb0a..b25fc9f257a 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -269,10 +269,7 @@ RSpec.describe 'Admin updates settings' do
end
context 'Integrations page' do
- let(:mailgun_events_receiver_enabled) { true }
-
before do
- stub_feature_flags(mailgun_events_receiver: mailgun_events_receiver_enabled)
visit general_admin_application_settings_path
end
@@ -286,26 +283,16 @@ RSpec.describe 'Admin updates settings' do
expect(current_settings.hide_third_party_offers).to be true
end
- context 'when mailgun_events_receiver feature flag is enabled' do
- it 'enabling Mailgun events', :aggregate_failures do
- page.within('.as-mailgun') do
- check 'Enable Mailgun event receiver'
- fill_in 'Mailgun HTTP webhook signing key', with: 'MAILGUN_SIGNING_KEY'
- click_button 'Save changes'
- end
-
- expect(page).to have_content 'Application settings saved successfully'
- expect(current_settings.mailgun_events_enabled).to be true
- expect(current_settings.mailgun_signing_key).to eq 'MAILGUN_SIGNING_KEY'
+ it 'enabling Mailgun events', :aggregate_failures do
+ page.within('.as-mailgun') do
+ check 'Enable Mailgun event receiver'
+ fill_in 'Mailgun HTTP webhook signing key', with: 'MAILGUN_SIGNING_KEY'
+ click_button 'Save changes'
end
- end
-
- context 'when mailgun_events_receiver feature flag is disabled' do
- let(:mailgun_events_receiver_enabled) { false }
- it 'does not have mailgun' do
- expect(page).not_to have_selector('.as-mailgun')
- end
+ expect(page).to have_content 'Application settings saved successfully'
+ expect(current_settings.mailgun_events_enabled).to be true
+ expect(current_settings.mailgun_signing_key).to eq 'MAILGUN_SIGNING_KEY'
end
end
@@ -559,6 +546,50 @@ RSpec.describe 'Admin updates settings' do
expect(current_settings.dns_rebinding_protection_enabled).to be false
end
+ it 'changes User and IP Rate Limits settings' do
+ visit network_admin_application_settings_path
+
+ page.within('.as-ip-limits') do
+ check 'Enable unauthenticated API request rate limit'
+ fill_in 'Maximum unauthenticated API requests per rate limit period per IP', with: 100
+ fill_in 'Unauthenticated API rate limit period in seconds', with: 200
+
+ check 'Enable unauthenticated web request rate limit'
+ fill_in 'Maximum unauthenticated web requests per rate limit period per IP', with: 300
+ fill_in 'Unauthenticated web rate limit period in seconds', with: 400
+
+ check 'Enable authenticated API request rate limit'
+ fill_in 'Maximum authenticated API requests per rate limit period per user', with: 500
+ fill_in 'Authenticated API rate limit period in seconds', with: 600
+
+ check 'Enable authenticated web request rate limit'
+ fill_in 'Maximum authenticated web requests per rate limit period per user', with: 700
+ fill_in 'Authenticated web rate limit period in seconds', with: 800
+
+ fill_in 'Plain-text response to send to clients that hit a rate limit', with: 'Custom message'
+
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+
+ expect(current_settings).to have_attributes(
+ throttle_unauthenticated_api_enabled: true,
+ throttle_unauthenticated_api_requests_per_period: 100,
+ throttle_unauthenticated_api_period_in_seconds: 200,
+ throttle_unauthenticated_enabled: true,
+ throttle_unauthenticated_requests_per_period: 300,
+ throttle_unauthenticated_period_in_seconds: 400,
+ throttle_authenticated_api_enabled: true,
+ throttle_authenticated_api_requests_per_period: 500,
+ throttle_authenticated_api_period_in_seconds: 600,
+ throttle_authenticated_web_enabled: true,
+ throttle_authenticated_web_requests_per_period: 700,
+ throttle_authenticated_web_period_in_seconds: 800,
+ rate_limiting_response_text: 'Custom message'
+ )
+ end
+
it 'changes Issues rate limits settings' do
visit network_admin_application_settings_path
@@ -570,6 +601,20 @@ RSpec.describe 'Admin updates settings' do
expect(page).to have_content "Application settings saved successfully"
expect(current_settings.issues_create_limit).to eq(0)
end
+
+ it 'changes Files API rate limits settings' do
+ visit network_admin_application_settings_path
+
+ page.within('[data-testid="files-limits-settings"]') do
+ check 'Enable unauthenticated API request rate limit'
+ fill_in 'Max unauthenticated API requests per period per IP', with: 10
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(current_settings.throttle_unauthenticated_files_api_enabled).to be true
+ expect(current_settings.throttle_unauthenticated_files_api_requests_per_period).to eq(10)
+ end
end
context 'Preferences page' do
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index 7466150addf..0966032ff37 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
click_on "Create impersonation token"
expect(active_impersonation_tokens).to have_text(name)
- expect(active_impersonation_tokens).to have_text('In')
+ expect(active_impersonation_tokens).to have_text('in')
expect(active_impersonation_tokens).to have_text('api')
expect(active_impersonation_tokens).to have_text('read_user')
expect(PersonalAccessTokensFinder.new(impersonation: true).execute.count).to equal(1)
@@ -59,6 +59,14 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
expect(active_impersonation_tokens).to have_text(impersonation_token.name)
expect(active_impersonation_tokens).not_to have_text(personal_access_token.name)
+ expect(active_impersonation_tokens).to have_text('in')
+ end
+
+ it 'shows absolute times' do
+ admin.update!(time_display_relative: false)
+ visit admin_user_impersonation_tokens_path(user_id: user.username)
+
+ expect(active_impersonation_tokens).to have_text(personal_access_token.expires_at.strftime('%b %d'))
end
end
diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb
index 511cdcc2940..855c91f70d7 100644
--- a/spec/features/atom/dashboard_issues_spec.rb
+++ b/spec/features/atom/dashboard_issues_spec.rb
@@ -4,8 +4,20 @@ require 'spec_helper'
RSpec.describe "Dashboard Issues Feed" do
describe "GET /issues" do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
+ let!(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let!(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
let!(:project1) { create(:project) }
let!(:project2) { create(:project) }
diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb
index 13798a94fe9..913f5a7bcf3 100644
--- a/spec/features/atom/issues_spec.rb
+++ b/spec/features/atom/issues_spec.rb
@@ -4,61 +4,87 @@ require 'spec_helper'
RSpec.describe 'Issues Feed' do
describe 'GET /issues' do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
- let!(:group) { create(:group) }
- let!(:project) { create(:project) }
- let!(:issue) { create(:issue, author: user, assignees: [assignee], project: project) }
+ let_it_be_with_reload(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let_it_be(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
- before do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:issue) { create(:issue, author: user, assignees: [assignee], project: project, due_date: Date.today) }
+ let_it_be(:issuable) { issue } # "alias" for shared examples
+
+ before_all do
project.add_developer(user)
group.add_developer(user)
end
+ RSpec.shared_examples 'an authenticated issue atom feed' do
+ it 'renders atom feed with additional issue information' do
+ expect(body).to have_selector('title', text: "#{project.name} issues")
+ expect(body).to have_selector('due_date', text: issue.due_date)
+ end
+ end
+
context 'when authenticated' do
- it 'renders atom feed' do
+ before do
sign_in user
visit project_issues_path(project, :atom)
-
- expect(response_headers['Content-Type'])
- .to have_content('application/atom+xml')
- expect(body).to have_selector('title', text: "#{project.name} issues")
- expect(body).to have_selector('author email', text: issue.author_public_email)
- expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('entry summary', text: issue.title)
end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated issue atom feed'
end
context 'when authenticated via personal access token' do
- it 'renders atom feed' do
+ before do
personal_access_token = create(:personal_access_token, user: user)
visit project_issues_path(project, :atom,
- private_token: personal_access_token.token)
-
- expect(response_headers['Content-Type'])
- .to have_content('application/atom+xml')
- expect(body).to have_selector('title', text: "#{project.name} issues")
- expect(body).to have_selector('author email', text: issue.author_public_email)
- expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('entry summary', text: issue.title)
+ private_token: personal_access_token.token)
end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated issue atom feed'
end
context 'when authenticated via feed token' do
- it 'renders atom feed' do
+ before do
visit project_issues_path(project, :atom,
- feed_token: user.feed_token)
+ feed_token: user.feed_token)
+ end
- expect(response_headers['Content-Type'])
- .to have_content('application/atom+xml')
- expect(body).to have_selector('title', text: "#{project.name} issues")
- expect(body).to have_selector('author email', text: issue.author_public_email)
- expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('assignee email', text: issue.assignees.first.public_email)
- expect(body).to have_selector('entry summary', text: issue.title)
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated issue atom feed'
+ end
+
+ context 'when not authenticated' do
+ before do
+ visit project_issues_path(project, :atom)
+ end
+
+ context 'and the project is private' do
+ it 'redirects to login page' do
+ expect(page).to have_current_path(new_user_session_path)
+ end
+ end
+
+ context 'and the project is public' do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue) { create(:issue, author: user, assignees: [assignee], project: project, due_date: Date.today) }
+ let_it_be(:issuable) { issue } # "alias" for shared examples
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated issue atom feed'
end
end
diff --git a/spec/features/atom/merge_requests_spec.rb b/spec/features/atom/merge_requests_spec.rb
new file mode 100644
index 00000000000..48db8fcbf1e
--- /dev/null
+++ b/spec/features/atom/merge_requests_spec.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Merge Requests Feed' do
+ describe 'GET /merge_requests' do
+ let_it_be_with_reload(:user) { create(:user, email: 'private1@example.com') }
+ let_it_be(:assignee) { create(:user, email: 'private2@example.com') }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project, assignees: [assignee]) }
+ let_it_be(:issuable) { merge_request } # "alias" for shared examples
+
+ before_all do
+ project.add_developer(user)
+ group.add_developer(user)
+ end
+
+ RSpec.shared_examples 'an authenticated merge request atom feed' do
+ it 'renders atom feed with additional merge request information' do
+ expect(body).to have_selector('title', text: "#{project.name} merge requests")
+ end
+ end
+
+ context 'when authenticated' do
+ before do
+ sign_in user
+ visit project_merge_requests_path(project, :atom)
+ end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated merge request atom feed'
+
+ context 'but the use can not see the project' do
+ let_it_be(:other_project) { create(:project) }
+
+ it 'renders 404 page' do
+ visit project_issues_path(other_project, :atom)
+
+ expect(page).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'when authenticated via personal access token' do
+ before do
+ personal_access_token = create(:personal_access_token, user: user)
+
+ visit project_merge_requests_path(project, :atom,
+ private_token: personal_access_token.token)
+ end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated merge request atom feed'
+ end
+
+ context 'when authenticated via feed token' do
+ before do
+ visit project_merge_requests_path(project, :atom,
+ feed_token: user.feed_token)
+ end
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated merge request atom feed'
+ end
+
+ context 'when not authenticated' do
+ before do
+ visit project_merge_requests_path(project, :atom)
+ end
+
+ context 'and the project is private' do
+ it 'redirects to login page' do
+ expect(page).to have_current_path(new_user_session_path)
+ end
+ end
+
+ context 'and the project is public' do
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project, assignees: [assignee]) }
+ let_it_be(:issuable) { merge_request } # "alias" for shared examples
+
+ it_behaves_like 'an authenticated issuable atom feed'
+ it_behaves_like 'an authenticated merge request atom feed'
+ end
+ end
+ end
+end
diff --git a/spec/features/boards/multi_select_spec.rb b/spec/features/boards/multi_select_spec.rb
index 057464326fa..9148fb23214 100644
--- a/spec/features/boards/multi_select_spec.rb
+++ b/spec/features/boards/multi_select_spec.rb
@@ -43,12 +43,12 @@ RSpec.describe 'Multi Select Issue', :js do
# Multi select drag&drop support is temporarily disabled
# https://gitlab.com/gitlab-org/gitlab/-/issues/289797
- stub_feature_flags(graphql_board_lists: false, board_multi_select: project)
+ stub_feature_flags(board_multi_select: project)
sign_in(user)
end
- context 'with lists' do
+ xcontext 'with lists' do
let(:label1) { create(:label, project: project, name: 'Label 1', description: 'Test') }
let(:label2) { create(:label, project: project, name: 'Label 2', description: 'Test') }
let!(:list1) { create(:list, board: board, label: label1, position: 0) }
diff --git a/spec/features/boards/sidebar_labels_spec.rb b/spec/features/boards/sidebar_labels_spec.rb
index 2f0230c61d8..fa16f47f69a 100644
--- a/spec/features/boards/sidebar_labels_spec.rb
+++ b/spec/features/boards/sidebar_labels_spec.rb
@@ -5,8 +5,9 @@ require 'spec_helper'
RSpec.describe 'Project issue boards sidebar labels', :js do
include BoardHelpers
+ let_it_be(:group) { create(:group, :public) }
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :public) }
+ let_it_be(:project) { create(:project, :public, namespace: group) }
let_it_be(:development) { create(:label, project: project, name: 'Development') }
let_it_be(:bug) { create(:label, project: project, name: 'Bug') }
let_it_be(:regression) { create(:label, project: project, name: 'Regression') }
diff --git a/spec/features/boards/user_adds_lists_to_board_spec.rb b/spec/features/boards/user_adds_lists_to_board_spec.rb
index 5128fc4004e..26c310a6f56 100644
--- a/spec/features/boards/user_adds_lists_to_board_spec.rb
+++ b/spec/features/boards/user_adds_lists_to_board_spec.rb
@@ -3,8 +3,6 @@
require 'spec_helper'
RSpec.describe 'User adds lists', :js do
- using RSpec::Parameterized::TableSyntax
-
let_it_be(:group) { create(:group, :nested) }
let_it_be(:project) { create(:project, :public, namespace: group) }
let_it_be(:group_board) { create(:board, group: group) }
@@ -17,6 +15,8 @@ RSpec.describe 'User adds lists', :js do
let_it_be(:project_label) { create(:label, project: project) }
let_it_be(:group_backlog_list) { create(:backlog_list, board: group_board) }
let_it_be(:project_backlog_list) { create(:backlog_list, board: project_board) }
+ let_it_be(:backlog) { create(:group_label, group: group, name: 'Backlog') }
+ let_it_be(:closed) { create(:group_label, group: group, name: 'Closed') }
let_it_be(:issue) { create(:labeled_issue, project: project, labels: [group_label, project_label]) }
@@ -25,15 +25,8 @@ RSpec.describe 'User adds lists', :js do
group.add_owner(user)
end
- where(:board_type, :graphql_board_lists_enabled, :board_new_list_enabled) do
- :project | true | true
- :project | false | true
- :project | true | false
- :project | false | false
- :group | true | true
- :group | false | true
- :group | true | false
- :group | false | false
+ where(:board_type) do
+ [[:project], [:group]]
end
with_them do
@@ -42,11 +35,6 @@ RSpec.describe 'User adds lists', :js do
set_cookie('sidebar_collapsed', 'true')
- stub_feature_flags(
- graphql_board_lists: graphql_board_lists_enabled,
- board_new_list: board_new_list_enabled
- )
-
if board_type == :project
visit project_board_path(project, project_board)
elsif board_type == :group
@@ -56,40 +44,43 @@ RSpec.describe 'User adds lists', :js do
wait_for_all_requests
end
- it 'creates new column for label containing labeled issue' do
- click_button button_text(board_new_list_enabled)
+ it 'creates new column for label containing labeled issue', :aggregate_failures do
+ click_button 'Create list'
wait_for_all_requests
- select_label(board_new_list_enabled, group_label)
-
- wait_for_all_requests
+ select_label(group_label)
expect(page).to have_selector('.board', text: group_label.title)
expect(find('.board:nth-child(2) .board-card')).to have_content(issue.title)
end
- end
- def select_label(board_new_list_enabled, label)
- if board_new_list_enabled
- click_button 'Select a label'
+ it 'creates new list for Backlog and closed labels' do
+ click_button 'Create list'
+ wait_for_requests
- find('label', text: label.title).click
+ select_label(backlog)
- click_button 'Add to board'
+ click_button 'Create list'
+ wait_for_requests
- wait_for_all_requests
- else
- page.within('.dropdown-menu-issues-board-new') do
- click_link label.title
- end
+ select_label(closed)
+
+ wait_for_requests
+
+ expect(page).to have_selector('.board', text: closed.title)
+ expect(find('.board:nth-child(2) .board-header')).to have_content(backlog.title)
+ expect(find('.board:nth-child(3) .board-header')).to have_content(closed.title)
+ expect(find('.board:nth-child(4) .board-header')).to have_content('Closed')
end
end
- def button_text(board_new_list_enabled)
- if board_new_list_enabled
- 'Create list'
- else
- 'Add list'
- end
+ def select_label(label)
+ click_button 'Select a label'
+
+ find('label', text: label.title).click
+
+ click_button 'Add to board'
+
+ wait_for_all_requests
end
end
diff --git a/spec/features/clusters/cluster_health_dashboard_spec.rb b/spec/features/clusters/cluster_health_dashboard_spec.rb
index e4a36f654e5..88d6976c2be 100644
--- a/spec/features/clusters/cluster_health_dashboard_spec.rb
+++ b/spec/features/clusters/cluster_health_dashboard_spec.rb
@@ -80,8 +80,8 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
expect(page).to have_content('Avg')
end
- it 'focuses the single panel on toggle', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338341' do
- click_button('More actions')
+ it 'focuses the single panel on toggle' do
+ click_button('More actions', match: :first)
click_button('Expand panel')
expect(page).to have_css('.prometheus-graph', count: 1)
diff --git a/spec/features/commit_spec.rb b/spec/features/commit_spec.rb
index 80a30ab01b2..3fd613ce393 100644
--- a/spec/features/commit_spec.rb
+++ b/spec/features/commit_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'Commit' do
visit project_commit_path(project, commit)
end
- it "shows an adjusted count for changed files on this page" do
+ it "shows an adjusted count for changed files on this page", :js do
expect(page).to have_content("Showing 1 changed file")
end
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index de6cb53fdfa..bec474f6cfe 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -5,35 +5,40 @@ require 'spec_helper'
RSpec.describe 'Value Stream Analytics', :js do
let_it_be(:user) { create(:user) }
let_it_be(:guest) { create(:user) }
- let_it_be(:project) { create(:project, :repository) }
let_it_be(:stage_table_selector) { '[data-testid="vsa-stage-table"]' }
+ let_it_be(:stage_table_event_selector) { '[data-testid="vsa-stage-event"]' }
let_it_be(:metrics_selector) { "[data-testid='vsa-time-metrics']" }
+ let_it_be(:metric_value_selector) { "[data-testid='displayValue']" }
+ let(:stage_table) { page.find(stage_table_selector) }
+ let(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
let(:milestone) { create(:milestone, project: project) }
let(:mr) { create_merge_request_closing_issue(user, project, issue, commit_message: "References #{issue.to_reference}") }
let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha, head_pipeline_of: mr) }
+ def metrics_values
+ page.find(metrics_selector).all(metric_value_selector).collect(&:text)
+ end
+
+ def set_daterange(from_date, to_date)
+ page.find(".js-daterange-picker-from input").set(from_date)
+ page.find(".js-daterange-picker-to input").set(to_date)
+ wait_for_all_requests
+ end
+
context 'as an allowed user' do
context 'when project is new' do
- before(:all) do
- project.add_maintainer(user)
- end
-
before do
+ project.add_maintainer(user)
sign_in(user)
visit project_cycle_analytics_path(project)
wait_for_requests
end
- it 'displays metrics' do
- aggregate_failures 'with relevant values' do
- expect(new_issues_counter).to have_content('-')
- expect(commits_counter).to have_content('-')
- expect(deploys_counter).to have_content('-')
- expect(deployment_frequency_counter).to have_content('-')
- end
+ it 'displays metrics with relevant values' do
+ expect(metrics_values).to eq(['-'] * 4)
end
it 'shows active stage with empty message' do
@@ -43,24 +48,37 @@ RSpec.describe 'Value Stream Analytics', :js do
end
context "when there's value stream analytics data" do
+ # NOTE: in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68595 travel back
+ # 5 days in time before we create data for these specs, to mitigate some flakiness
+ # So setting the date range to be the last 2 days should skip past the existing data
+ from = 2.days.ago.strftime("%Y-%m-%d")
+ to = 1.day.ago.strftime("%Y-%m-%d")
+
+ around do |example|
+ travel_to(5.days.ago) { example.run }
+ end
+
before do
project.add_maintainer(user)
+ create_list(:issue, 2, project: project, created_at: 2.weeks.ago, milestone: milestone)
- @build = create_cycle(user, project, issue, mr, milestone, pipeline)
+ 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.hour)
merge_request = issue.merge_requests_closing_issues.first.merge_request
merge_request.update!(created_at: issue.metrics.first_associated_with_milestone_at + 1.hour)
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
+ latest_build_started_at: merge_request.created_at + 3.hours,
+ latest_build_finished_at: merge_request.created_at + 4.hours,
+ merged_at: merge_request.created_at + 4.hours,
+ first_deployed_to_production_at: merge_request.created_at + 5.hours
)
sign_in(user)
visit project_cycle_analytics_path(project)
+
+ wait_for_requests
end
it 'displays metrics' do
@@ -93,18 +111,20 @@ RSpec.describe 'Value Stream Analytics', :js do
expect_merge_request_to_be_present
end
- context "when I change the time period observed" do
- before do
- _two_weeks_old_issue = create(:issue, project: project, created_at: 2.weeks.ago)
+ it 'can filter the issues by date' do
+ expect(stage_table.all(stage_table_event_selector).length).to eq(3)
- click_button('Last 30 days')
- click_link('Last 7 days')
- wait_for_requests
- end
+ set_daterange(from, to)
- it 'shows only relevant data' do
- expect(new_issue_counter).to have_content('1')
- end
+ expect(stage_table.all(stage_table_event_selector).length).to eq(0)
+ end
+
+ it 'can filter the metrics by date' do
+ expect(metrics_values).to eq(["3.0", "2.0", "1.0", "0.0"])
+
+ set_daterange(from, to)
+
+ expect(metrics_values).to eq(['-'] * 4)
end
end
end
@@ -137,31 +157,6 @@ RSpec.describe 'Value Stream Analytics', :js do
end
end
- def find_metric_tile(sel)
- page.find("#{metrics_selector} #{sel}")
- end
-
- # When now use proper pluralization for the metric names, which affects the id
- def new_issue_counter
- find_metric_tile("#new-issue")
- end
-
- def new_issues_counter
- find_metric_tile("#new-issues")
- end
-
- def commits_counter
- find_metric_tile("#commits")
- end
-
- def deploys_counter
- find_metric_tile("#deploys")
- end
-
- def deployment_frequency_counter
- find_metric_tile("#deployment-frequency")
- end
-
def expect_issue_to_be_present
expect(find(stage_table_selector)).to have_content(issue.title)
expect(find(stage_table_selector)).to have_content(issue.author.name)
diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb
index 19fb8e5f52c..a380edff3a4 100644
--- a/spec/features/global_search_spec.rb
+++ b/spec/features/global_search_spec.rb
@@ -11,40 +11,64 @@ RSpec.describe 'Global search' do
before do
project.add_maintainer(user)
sign_in(user)
-
- visit dashboard_projects_path
end
- it 'increases usage ping searches counter' do
- expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:navbar_searches)
- expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:all_searches)
+ describe 'when new_header_search feature is disabled' do
+ before do
+ # TODO: Remove this along with feature flag #339348
+ stub_feature_flags(new_header_search: false)
+ visit dashboard_projects_path
+ end
- submit_search('foobar')
- end
+ it 'increases usage ping searches counter' do
+ expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:navbar_searches)
+ expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:all_searches)
- describe 'I search through the issues and I see pagination' do
- before do
- allow_next(SearchService).to receive(:per_page).and_return(1)
- create_list(:issue, 2, project: project, title: 'initial')
+ submit_search('foobar')
end
- it "has a pagination" do
- submit_search('initial')
- select_search_scope('Issues')
+ describe 'I search through the issues and I see pagination' do
+ before do
+ allow_next(SearchService).to receive(:per_page).and_return(1)
+ create_list(:issue, 2, project: project, title: 'initial')
+ end
+
+ it "has a pagination" do
+ submit_search('initial')
+ select_search_scope('Issues')
- expect(page).to have_selector('.gl-pagination .next')
+ expect(page).to have_selector('.gl-pagination .next')
+ end
end
- end
- it 'closes the dropdown on blur', :js do
- find('#search').click
- fill_in 'search', with: "a"
+ it 'closes the dropdown on blur', :js do
+ find('#search').click
+ fill_in 'search', with: "a"
+
+ expect(page).to have_selector("div[data-testid='dashboard-search-options'].show")
- expect(page).to have_selector("div[data-testid='dashboard-search-options'].show")
+ find('#search').send_keys(:backspace)
+ find('body').click
- find('#search').send_keys(:backspace)
- find('body').click
+ expect(page).to have_no_selector("div[data-testid='dashboard-search-options'].show")
+ end
+
+ it 'renders legacy search bar' do
+ expect(page).to have_selector('.search-form')
+ expect(page).to have_no_selector('#js-header-search')
+ end
+ end
- expect(page).to have_no_selector("div[data-testid='dashboard-search-options'].show")
+ describe 'when new_header_search feature is enabled' do
+ before do
+ # TODO: Remove this along with feature flag #339348
+ stub_feature_flags(new_header_search: true)
+ visit dashboard_projects_path
+ end
+
+ it 'renders updated search bar' do
+ expect(page).to have_no_selector('.search-form')
+ expect(page).to have_selector('#js-header-search')
+ end
end
end
diff --git a/spec/features/groups/board_sidebar_spec.rb b/spec/features/groups/board_sidebar_spec.rb
index e2dd2fecab7..69a6788e438 100644
--- a/spec/features/groups/board_sidebar_spec.rb
+++ b/spec/features/groups/board_sidebar_spec.rb
@@ -42,30 +42,4 @@ RSpec.describe 'Group Issue Boards', :js do
end
end
end
-
- context 'when graphql_board_lists FF disabled' do
- before do
- stub_feature_flags(graphql_board_lists: false)
- sign_in(user)
-
- visit group_board_path(group, board)
- wait_for_requests
- end
-
- it 'only shows valid labels for the issue project and group' do
- click_card(card)
-
- page.within('.labels') do
- click_link 'Edit'
-
- wait_for_requests
-
- page.within('.selectbox') do
- expect(page).to have_content(project_1_label.title)
- expect(page).to have_content(group_label.title)
- expect(page).not_to have_content(project_2_label.title)
- end
- end
- end
- end
end
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index 21b39d2da46..489beb70ab3 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe 'Group issues page' do
# However,`:js` option forces Capybara to use Selenium that doesn't support`:has`
context "it has an RSS button with current_user's feed token" do
it "shows the RSS button with current_user's feed token" do
- expect(find('[data-testid="rss-feed-link"]')['href']).to have_content(user.feed_token)
+ expect(page).to have_link 'Subscribe to RSS feed', href: /feed_token=#{user.feed_token}/
end
end
end
@@ -46,7 +46,7 @@ RSpec.describe 'Group issues page' do
# Note: please see the above
context "it has an RSS button without a feed token" do
it "shows the RSS button without a feed token" do
- expect(find('[data-testid="rss-feed-link"]')['href']).not_to have_content('feed_token')
+ expect(page).not_to have_link 'Subscribe to RSS feed', href: /feed_token/
end
end
end
@@ -94,6 +94,41 @@ RSpec.describe 'Group issues page' do
expect(page).not_to have_content issue.title[0..80]
end
end
+
+ context 'when cached issues state count is enabled', :clean_gitlab_redis_cache do
+ before do
+ stub_feature_flags(cached_issues_state_count: true)
+ end
+
+ it 'truncates issue counts if over the threshold' do
+ allow(Rails.cache).to receive(:read).and_call_original
+ allow(Rails.cache).to receive(:read).with(
+ ['group', group.id, 'issues'],
+ { expires_in: Gitlab::IssuablesCountForState::CACHE_EXPIRES_IN }
+ ).and_return({ opened: 1050, closed: 500, all: 1550 })
+
+ visit issues_group_path(group)
+
+ expect(page).to have_text('Open 1.1k Closed 500 All 1.6k')
+ end
+ end
+
+ context 'when cached issues state count is disabled', :clean_gitlab_redis_cache do
+ before do
+ stub_feature_flags(cached_issues_state_count: false)
+ end
+
+ it 'does not truncate counts if they are over the threshold' do
+ allow_next_instance_of(IssuesFinder) do |finder|
+ allow(finder).to receive(:count_by_state).and_return(true)
+ .and_return({ opened: 1050, closed: 500, all: 1550 })
+ end
+
+ visit issues_group_path(group)
+
+ expect(page).to have_text('Open 1,050 Closed 500 All 1,550')
+ end
+ end
end
context 'projects with issues disabled' do
diff --git a/spec/features/groups/members/request_access_spec.rb b/spec/features/groups/members/request_access_spec.rb
index 827962fee61..f806c7d3704 100644
--- a/spec/features/groups/members/request_access_spec.rb
+++ b/spec/features/groups/members/request_access_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'Groups > Members > Request access' do
it 'user can request access to a group' do
perform_enqueued_jobs { click_link 'Request Access' }
- expect(ActionMailer::Base.deliveries.last.to).to eq [owner.notification_email]
+ expect(ActionMailer::Base.deliveries.last.to).to eq [owner.notification_email_or_default]
expect(ActionMailer::Base.deliveries.last.subject).to match "Request to join the #{group.name} group"
expect(group.requesters.exists?(user_id: user)).to be_truthy
diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb
index 9a7950266a5..3c2ade6b274 100644
--- a/spec/features/groups/packages_spec.rb
+++ b/spec/features/groups/packages_spec.rb
@@ -44,14 +44,6 @@ RSpec.describe 'Group Packages' do
it_behaves_like 'packages list', check_project_name: true
- context 'when package_details_apollo feature flag is off' do
- before do
- stub_feature_flags(package_details_apollo: false)
- end
-
- it_behaves_like 'package details link'
- end
-
it_behaves_like 'package details link'
it 'allows you to navigate to the project page' do
diff --git a/spec/features/groups/settings/packages_and_registries_spec.rb b/spec/features/groups/settings/packages_and_registries_spec.rb
index 835555480dd..d3141da9160 100644
--- a/spec/features/groups/settings/packages_and_registries_spec.rb
+++ b/spec/features/groups/settings/packages_and_registries_spec.rb
@@ -90,9 +90,10 @@ RSpec.describe 'Group Packages & Registries settings' do
expect(page).to have_content('Do not allow duplicates')
fill_in 'Exceptions', with: ')'
+
+ # simulate blur event
+ find('#maven-duplicated-settings-regex-input').native.send_keys(:tab)
end
- # simulate blur event
- find('body').click
expect(page).to have_content('is an invalid regexp')
end
diff --git a/spec/features/groups/settings/repository_spec.rb b/spec/features/groups/settings/repository_spec.rb
index 7082b2b20bd..d95eaf3c92c 100644
--- a/spec/features/groups/settings/repository_spec.rb
+++ b/spec/features/groups/settings/repository_spec.rb
@@ -18,11 +18,11 @@ RSpec.describe 'Group Repository settings' do
before do
stub_container_registry_config(enabled: true)
- visit group_settings_repository_path(group)
end
it_behaves_like 'a deploy token in settings' do
let(:entity_type) { 'group' }
+ let(:page_path) { group_settings_repository_path(group) }
end
end
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index 79226facad4..eb62b6fa8ee 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -3,25 +3,74 @@
require 'spec_helper'
RSpec.describe 'Group show page' do
- let(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
let(:path) { group_path(group) }
context 'when signed in' do
- let(:user) do
- create(:group_member, :developer, user: create(:user), group: group ).user
- end
+ context 'with non-admin group concerns' do
+ before do
+ group.add_developer(user)
+ sign_in(user)
+ visit path
+ end
- before do
- sign_in(user)
- visit path
+ it_behaves_like "an autodiscoverable RSS feed with current_user's feed token"
+
+ context 'when group does not exist' do
+ let(:path) { group_path('not-exist') }
+
+ it { expect(status_code).to eq(404) }
+ end
end
- it_behaves_like "an autodiscoverable RSS feed with current_user's feed token"
+ context 'when user is an owner' do
+ before do
+ group.add_owner(user)
+ sign_in(user)
+ end
+
+ it 'shows the invite banner and persists dismissal', :js do
+ visit path
+
+ expect(page).to have_content('Collaborate with your team')
- context 'when group does not exist' do
- let(:path) { group_path('not-exist') }
+ page.within(find('[data-testid="invite-members-banner"]')) do
+ find('[data-testid="close-icon"]').click
+ end
+
+ expect(page).not_to have_content('Collaborate with your team')
+
+ visit path
+
+ expect(page).not_to have_content('Collaborate with your team')
+ end
+
+ context 'when group has a project with emoji in description', :js do
+ let!(:project) { create(:project, description: ':smile:', namespace: group) }
+
+ it 'shows the project info', :aggregate_failures do
+ visit path
+
+ expect(page).to have_content(project.title)
+ expect(page).to have_emoji('smile')
+ end
+ end
- it { expect(status_code).to eq(404) }
+ context 'when group has projects' do
+ it 'allows users to sorts projects by most stars', :js do
+ project1 = create(:project, namespace: group, star_count: 2)
+ project2 = create(:project, namespace: group, star_count: 3)
+ project3 = create(:project, namespace: group, star_count: 0)
+
+ visit group_path(group, sort: :stars_desc)
+
+ expect(find('.group-row:nth-child(1) .namespace-title > a')).to have_content(project2.title)
+ expect(find('.group-row:nth-child(2) .namespace-title > a')).to have_content(project1.title)
+ expect(find('.group-row:nth-child(3) .namespace-title > a')).to have_content(project3.title)
+ end
+ end
end
end
@@ -37,7 +86,7 @@ RSpec.describe 'Group show page' do
context 'when group has a public project', :js do
let!(:project) { create(:project, :public, namespace: group) }
- it 'renders public project' do
+ it 'renders public project', :aggregate_failures do
visit path
expect(page).to have_link group.name
@@ -48,7 +97,7 @@ RSpec.describe 'Group show page' do
context 'when group has a private project', :js do
let!(:project) { create(:project, :private, namespace: group) }
- it 'does not render private project' do
+ it 'does not render private project', :aggregate_failures do
visit path
expect(page).to have_link group.name
@@ -58,28 +107,19 @@ RSpec.describe 'Group show page' do
end
context 'subgroup support' do
- let(:restricted_group) do
+ let_it_be(:restricted_group) do
create(:group, subgroup_creation_level: ::Gitlab::Access::OWNER_SUBGROUP_ACCESS)
end
- let(:relaxed_group) do
- create(:group, subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS)
- end
-
- let(:owner) { create(:user) }
- let(:maintainer) { create(:user) }
-
context 'for owners' do
- let(:path) { group_path(restricted_group) }
-
before do
- restricted_group.add_owner(owner)
- sign_in(owner)
+ restricted_group.add_owner(user)
+ sign_in(user)
end
context 'when subgroups are supported' do
it 'allows creating subgroups' do
- visit path
+ visit group_path(restricted_group)
expect(page).to have_link('New subgroup')
end
@@ -88,18 +128,21 @@ RSpec.describe 'Group show page' do
context 'for maintainers' do
before do
- sign_in(maintainer)
+ sign_in(user)
end
context 'when subgroups are supported' do
context 'when subgroup_creation_level is set to maintainers' do
+ let(:relaxed_group) do
+ create(:group, subgroup_creation_level: ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS)
+ end
+
before do
- relaxed_group.add_maintainer(maintainer)
+ relaxed_group.add_maintainer(user)
end
it 'allows creating subgroups' do
- path = group_path(relaxed_group)
- visit path
+ visit group_path(relaxed_group)
expect(page).to have_link('New subgroup')
end
@@ -107,12 +150,11 @@ RSpec.describe 'Group show page' do
context 'when subgroup_creation_level is set to owners' do
before do
- restricted_group.add_maintainer(maintainer)
+ restricted_group.add_maintainer(user)
end
it 'does not allow creating subgroups' do
- path = group_path(restricted_group)
- visit path
+ visit group_path(restricted_group)
expect(page).not_to have_link('New subgroup')
end
@@ -121,50 +163,10 @@ RSpec.describe 'Group show page' do
end
end
- context 'group has a project with emoji in description', :js do
- let(:user) { create(:user) }
- let!(:project) { create(:project, description: ':smile:', namespace: group) }
-
- before do
- group.add_owner(user)
- sign_in(user)
- visit path
- end
-
- it 'shows the project info' do
- expect(page).to have_content(project.title)
- expect(page).to have_emoji('smile')
- end
- end
-
- context 'where group has projects' do
- let(:user) { create(:user) }
-
- before do
- group.add_owner(user)
- sign_in(user)
- end
-
- it 'allows users to sorts projects by most stars', :js do
- project1 = create(:project, namespace: group, star_count: 2)
- project2 = create(:project, namespace: group, star_count: 3)
- project3 = create(:project, namespace: group, star_count: 0)
-
- visit group_path(group, sort: :stars_desc)
-
- expect(find('.group-row:nth-child(1) .namespace-title > a')).to have_content(project2.title)
- expect(find('.group-row:nth-child(2) .namespace-title > a')).to have_content(project1.title)
- expect(find('.group-row:nth-child(3) .namespace-title > a')).to have_content(project3.title)
- end
- end
-
context 'notification button', :js do
- let(:maintainer) { create(:user) }
- let!(:project) { create(:project, namespace: group) }
-
before do
- group.add_maintainer(maintainer)
- sign_in(maintainer)
+ group.add_maintainer(user)
+ sign_in(user)
end
it 'is enabled by default' do
@@ -174,7 +176,8 @@ RSpec.describe 'Group show page' do
end
it 'is disabled if emails are disabled' do
- group.update_attribute(:emails_disabled, true)
+ group.update!(emails_disabled: true)
+
visit path
expect(page).to have_selector('[data-testid="notification-dropdown"] .disabled')
@@ -182,12 +185,10 @@ RSpec.describe 'Group show page' do
end
context 'page og:description' do
- let(:group) { create(:group, description: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)') }
- let(:maintainer) { create(:user) }
-
before do
- group.add_maintainer(maintainer)
- sign_in(maintainer)
+ group.update!(description: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)')
+ group.add_maintainer(user)
+ sign_in(user)
visit path
end
@@ -237,7 +238,7 @@ RSpec.describe 'Group show page' do
end
end
- it 'does not include structured markup in shared projects tab', :js do
+ it 'does not include structured markup in shared projects tab', :aggregate_failures, :js do
other_project = create(:project, :public)
other_project.project_group_links.create!(group: group)
@@ -248,7 +249,7 @@ RSpec.describe 'Group show page' do
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
+ it 'does not include structured markup in archived projects tab', :aggregate_failures, :js do
project.update!(archived: true)
visit group_archived_path(group)
diff --git a/spec/features/ics/dashboard_issues_spec.rb b/spec/features/ics/dashboard_issues_spec.rb
index 4a93a4b490a..1d0ea495757 100644
--- a/spec/features/ics/dashboard_issues_spec.rb
+++ b/spec/features/ics/dashboard_issues_spec.rb
@@ -4,8 +4,20 @@ require 'spec_helper'
RSpec.describe 'Dashboard Issues Calendar Feed' do
describe 'GET /issues' do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
+ let!(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let!(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
let!(:project) { create(:project) }
let(:milestone) { create(:milestone, project_id: project.id, title: 'v1.0') }
diff --git a/spec/features/ics/group_issues_spec.rb b/spec/features/ics/group_issues_spec.rb
index 05caca4b5a8..f29c39ad4ef 100644
--- a/spec/features/ics/group_issues_spec.rb
+++ b/spec/features/ics/group_issues_spec.rb
@@ -4,8 +4,20 @@ require 'spec_helper'
RSpec.describe 'Group Issues Calendar Feed' do
describe 'GET /issues' do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
+ let!(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let!(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
let!(:group) { create(:group) }
let!(:project) { create(:project, group: group) }
diff --git a/spec/features/ics/project_issues_spec.rb b/spec/features/ics/project_issues_spec.rb
index 58a1a32eac2..771748060bb 100644
--- a/spec/features/ics/project_issues_spec.rb
+++ b/spec/features/ics/project_issues_spec.rb
@@ -4,8 +4,20 @@ require 'spec_helper'
RSpec.describe 'Project Issues Calendar Feed' do
describe 'GET /issues' do
- let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
- let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
+ let!(:user) do
+ user = create(:user, email: 'private1@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public1@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
+ let!(:assignee) do
+ user = create(:user, email: 'private2@example.com')
+ public_email = create(:email, :confirmed, user: user, email: 'public2@example.com')
+ user.update!(public_email: public_email.email)
+ user
+ end
+
let!(:project) { create(:project) }
let!(:issue) { create(:issue, author: user, assignees: [assignee], project: project) }
diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb
index b94ce3cd06f..244b66f7a9a 100644
--- a/spec/features/incidents/user_views_incident_spec.rb
+++ b/spec/features/incidents/user_views_incident_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe "User views incident" do
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_link('New incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident', description: "Related to \##{incident.iid}.\n\n" } }))
expect(page).to have_button('Create merge request')
expect(page).to have_button('Close incident')
end
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index d56bedd4852..87fb8955dcc 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -189,6 +189,16 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
context 'email confirmation enabled' do
+ context 'when user is not valid in sign up form' do
+ let(:new_user) { build_stubbed(:user, first_name: '', last_name: '') }
+
+ it 'fails sign up and redirects back to sign up', :aggregate_failures do
+ expect { fill_in_sign_up_form(new_user) }.not_to change { User.count }
+ expect(page).to have_content('prohibited this user from being saved')
+ expect(current_path).to eq(user_registration_path)
+ end
+ end
+
context 'with invite email acceptance', :snowplow do
it 'tracks the accepted invite' do
fill_in_sign_up_form(new_user)
@@ -216,6 +226,20 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
end
+ context 'with invite email acceptance for the invite_email_from experiment', :experiment do
+ let(:extra_params) do
+ { invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_from' }
+ end
+
+ it 'tracks the accepted invite' do
+ expect(experiment(:invite_email_from)).to track(:accepted)
+ .with_context(actor: group_invite)
+ .on_next_instance
+
+ fill_in_sign_up_form(new_user)
+ end
+ end
+
it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
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 077c363f78b..507d427bf0b 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
@@ -27,7 +27,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
it 'shows a button to resolve all threads by creating a new issue' do
within('.line-resolve-all-container') do
- expect(page).to have_selector resolve_all_discussions_link_selector( title: "Resolve all threads in new issue" )
+ expect(page).to have_selector resolve_all_discussions_link_selector( title: "Create issue to resolve all threads" )
end
end
@@ -38,7 +38,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
it 'hides the link for creating a new issue' do
expect(page).not_to have_selector resolve_all_discussions_link_selector
- expect(page).not_to have_content "Resolve all threads in new issue"
+ expect(page).not_to have_content "Create issue to resolve all threads"
end
end
@@ -62,7 +62,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
end
it 'does not show a link to create a new issue' do
- expect(page).not_to have_link 'Resolve all threads in new issue'
+ expect(page).not_to have_link 'Create issue to resolve all threads'
end
end
@@ -77,14 +77,14 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
it 'has a link to resolve all threads by creating an issue' do
page.within '.mr-widget-body' do
- expect(page).to have_link 'Resolve all threads in new issue', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
+ expect(page).to have_link 'Create issue to resolve all threads', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
end
end
context 'creating an issue for threads' do
before do
page.within '.mr-widget-body' do
- page.click_link 'Resolve all threads in new issue', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
+ page.click_link 'Create issue to resolve all threads', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid)
wait_for_all_requests
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 3ff8fc5ecca..0de15d3d304 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
@@ -9,7 +9,7 @@ RSpec.describe 'Resolve an open thread in a merge request by creating an issue',
let!(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
def resolve_discussion_selector
- title = 'Resolve this thread in a new issue'
+ title = 'Create issue to resolve thread'
url = new_project_issue_path(project, discussion_to_resolve: discussion.id, merge_request_to_resolve_discussions_of: merge_request.iid)
"a[title=\"#{title}\"][href=\"#{url}\"]"
end
diff --git a/spec/features/issues/csv_spec.rb b/spec/features/issues/csv_spec.rb
index 51e0d54ca5e..b4c737495b4 100644
--- a/spec/features/issues/csv_spec.rb
+++ b/spec/features/issues/csv_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe 'Issues csv', :js do
request_csv
expect(page).to have_content 'CSV export has started'
- expect(page).to have_content "emailed to #{user.notification_email}"
+ expect(page).to have_content "emailed to #{user.notification_email_or_default}"
end
it 'includes a csv attachment', :sidekiq_might_not_need_inline do
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index 88a7b890daa..edf3df7c16e 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -565,21 +565,18 @@ RSpec.describe 'Filter issues', :js do
end
it 'maintains filter' do
- # Closed
- find('.issues-state-filters [data-state="closed"]').click
+ click_link 'Closed'
wait_for_requests
expect(page).to have_selector('.issues-list .issue', count: 1)
expect(page).to have_link(closed_issue.title)
- # Opened
- find('.issues-state-filters [data-state="opened"]').click
+ click_link 'Open'
wait_for_requests
expect(page).to have_selector('.issues-list .issue', count: 4)
- # All
- find('.issues-state-filters [data-state="all"]').click
+ click_link 'All'
wait_for_requests
expect(page).to have_selector('.issues-list .issue', count: 5)
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 1efcc329e32..60963d95ae5 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -89,7 +89,7 @@ RSpec.describe 'Search bar', :js do
expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: original_size)
end
- it 'resets the dropdown filters', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/9985' do
+ it 'resets the dropdown filters' do
filtered_search.click
hint_offset = get_left_style(find('#js-dropdown-hint')['style'])
@@ -103,7 +103,7 @@ RSpec.describe 'Search bar', :js do
find('.filtered-search-box .clear-search').click
filtered_search.click
- expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 6)
+ expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', minimum: 6)
expect(get_left_style(find('#js-dropdown-hint')['style'])).to eq(hint_offset)
end
end
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index 644d7cc4611..2d8587d886f 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -16,9 +16,6 @@ RSpec.describe 'Visual tokens', :js do
let(:filtered_search) { find('.filtered-search') }
let(:filter_author_dropdown) { find("#js-dropdown-author .filter-dropdown") }
- let(:filter_assignee_dropdown) { find("#js-dropdown-assignee .filter-dropdown") }
- let(:filter_milestone_dropdown) { find("#js-dropdown-milestone .filter-dropdown") }
- let(:filter_label_dropdown) { find("#js-dropdown-label .filter-dropdown") }
def is_input_focused
page.evaluate_script("document.activeElement.classList.contains('filtered-search')")
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index a942a1a44f6..531c3634b5e 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -32,6 +32,21 @@ RSpec.describe 'Issue Detail', :js do
end
end
+ context 'when issue description has emojis' do
+ let(:issue) { create(:issue, project: project, author: user, description: 'hello world :100:') }
+
+ before do
+ sign_in(user)
+ visit project_issue_path(project, issue)
+ end
+
+ it 'renders gl-emoji tag' do
+ page.within('.description') do
+ expect(page).to have_selector('gl-emoji', count: 1)
+ end
+ end
+ end
+
context 'when issue description has xss snippet' do
before do
issue.update!(description: '![xss" onload=alert(1);//](a)')
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index e198d9d4ebb..bd4be755a92 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -117,7 +117,7 @@ RSpec.describe 'Issue Sidebar' do
page.within '.dropdown-menu-user' do
expect(page).to have_link('Invite members')
- expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
expect(page).to have_selector('[data-track-label="edit_assignee"]')
end
diff --git a/spec/features/issues/resource_label_events_spec.rb b/spec/features/issues/resource_label_events_spec.rb
index 33edf2f0b63..e08410efc0b 100644
--- a/spec/features/issues/resource_label_events_spec.rb
+++ b/spec/features/issues/resource_label_events_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'List issue resource label events', :js do
click_on 'Edit'
wait_for_requests
- labels.each { |label| click_link label }
+ labels.each { |label| click_on label }
send_keys(:escape)
wait_for_requests
diff --git a/spec/features/issues/rss_spec.rb b/spec/features/issues/rss_spec.rb
index 6c4498ea711..b20502ecc25 100644
--- a/spec/features/issues/rss_spec.rb
+++ b/spec/features/issues/rss_spec.rb
@@ -3,21 +3,24 @@
require 'spec_helper'
RSpec.describe 'Project Issues RSS' do
- let!(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:project) { create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
- let(:path) { project_issues_path(project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let_it_be(:path) { project_issues_path(project) }
+ let_it_be(:issue) { create(:issue, project: project, assignees: [user]) }
- before do
- create(:issue, project: project, assignees: [user])
+ before_all do
group.add_developer(user)
end
context 'when signed in' do
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
- before do
+ before_all do
project.add_developer(user)
+ end
+
+ before do
sign_in(user)
visit path
end
@@ -36,26 +39,6 @@ RSpec.describe 'Project Issues RSS' do
end
describe 'feeds' do
- shared_examples 'updates atom feed link' do |type|
- it "for #{type}" do
- sign_in(user)
- visit path
-
- link = find_link('Subscribe to RSS feed')
- params = CGI.parse(URI.parse(link[:href]).query)
- auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
- auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
-
- expected = {
- 'feed_token' => [user.feed_token],
- 'assignee_id' => [user.id.to_s]
- }
-
- expect(params).to include(expected)
- expect(auto_discovery_params).to include(expected)
- end
- end
-
it_behaves_like 'updates atom feed link', :project do
let(:path) { project_issues_path(project, assignee_id: user.id) }
end
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index e4bba706453..63c36a20adc 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -15,6 +15,7 @@ RSpec.describe "Issues > User edits issue", :js do
context 'with authorized user' do
before do
+ stub_feature_flags(labels_widget: false)
project.add_developer(user)
project_with_milestones.add_developer(user)
sign_in(user)
diff --git a/spec/features/issues/user_views_issue_spec.rb b/spec/features/issues/user_views_issue_spec.rb
index 8792d76981f..31bf7649470 100644
--- a/spec/features/issues/user_views_issue_spec.rb
+++ b/spec/features/issues/user_views_issue_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe "User views issue" do
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_link('New issue', href: new_project_issue_path(project, { issue: { description: "Related to \##{issue.iid}.\n\n" } }))
expect(page).to have_button('Create merge request')
expect(page).to have_button('Close issue')
end
diff --git a/spec/features/issues/user_views_issues_spec.rb b/spec/features/issues/user_views_issues_spec.rb
index 165f4b10cff..56afa7eb6ba 100644
--- a/spec/features/issues/user_views_issues_spec.rb
+++ b/spec/features/issues/user_views_issues_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe "User views issues" do
.and have_content(open_issue2.title)
.and have_no_content(closed_issue.title)
.and have_content(moved_open_issue.title)
- .and have_no_selector(".js-new-board-list")
+ .and have_no_content('Create list')
end
it "opens issues by label" do
@@ -65,7 +65,7 @@ RSpec.describe "User views issues" do
.and have_no_content(open_issue1.title)
.and have_no_content(open_issue2.title)
.and have_no_content(moved_open_issue.title)
- .and have_no_selector(".js-new-board-list")
+ .and have_no_content('Create list')
end
include_examples "opens issue from list" do
@@ -87,7 +87,7 @@ RSpec.describe "User views issues" do
.and have_content(open_issue2.title)
.and have_content(moved_open_issue.title)
.and have_no_content('CLOSED (MOVED)')
- .and have_no_selector(".js-new-board-list")
+ .and have_no_content('Create list')
end
include_examples "opens issue from list" do
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index fca5e946d0c..25c315f2d16 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe 'Labels Hierarchy', :js do
let!(:project_label_1) { create(:label, project: project_1, title: 'Label_4') }
before do
- stub_feature_flags(board_new_list: false)
+ stub_feature_flags(labels_widget: false)
grandparent.add_owner(user)
sign_in(user)
@@ -215,44 +215,6 @@ RSpec.describe 'Labels Hierarchy', :js do
end
end
- context 'issuable sidebar when graphql_board_lists FF disabled' do
- let!(:issue) { create(:issue, project: project_1) }
-
- before do
- stub_feature_flags(graphql_board_lists: false)
- end
-
- context 'on project board issue sidebar' do
- before do
- project_1.add_developer(user)
- board = create(:board, project: project_1)
-
- visit project_board_path(project_1, board)
-
- wait_for_requests
-
- find('.board-card').click
- end
-
- it_behaves_like 'assigning labels from sidebar'
- end
-
- context 'on group board issue sidebar' do
- before do
- parent.add_developer(user)
- board = create(:board, group: parent)
-
- visit group_board_path(parent, board)
-
- wait_for_requests
-
- find('.board-card').click
- end
-
- it_behaves_like 'assigning labels from sidebar'
- end
- end
-
context 'issuable filtering' do
let!(:labeled_issue) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label, project_label_1]) }
let!(:issue) { create(:issue, project: project_1) }
@@ -307,88 +269,4 @@ RSpec.describe 'Labels Hierarchy', :js do
it_behaves_like 'filtering by ancestor labels for groups', true
end
end
-
- context 'creating boards lists' do
- before do
- stub_feature_flags(board_new_list: false)
- end
-
- context 'on project boards' do
- let(:board) { create(:board, project: project_1) }
-
- before do
- project_1.add_developer(user)
- visit project_board_path(project_1, board)
- find('.js-new-board-list').click
- wait_for_requests
- end
-
- it 'creates lists from all ancestor labels' do
- [grandparent_group_label, parent_group_label, project_label_1].each do |label|
- find('a', text: label.title).click
- end
-
- wait_for_requests
-
- expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
- expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
- expect(page).to have_selector('.board-title-text', text: project_label_1.title)
- end
- end
-
- context 'on group boards' do
- let(:board) { create(:board, group: parent) }
-
- before do
- parent.add_developer(user)
- visit group_board_path(parent, board)
- find('.js-new-board-list').click
- wait_for_requests
- end
-
- context 'when graphql_board_lists FF enabled' do
- it 'creates lists from all ancestor group labels' do
- [grandparent_group_label, parent_group_label].each do |label|
- find('a', text: label.title).click
- end
-
- wait_for_requests
-
- expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
- expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
- end
-
- it 'does not create lists from descendant groups' do
- expect(page).not_to have_selector('a', text: child_group_label.title)
- end
- end
- end
-
- context 'when graphql_board_lists FF disabled' do
- let(:board) { create(:board, group: parent) }
-
- before do
- stub_feature_flags(graphql_board_lists: false)
- parent.add_developer(user)
- visit group_board_path(parent, board)
- find('.js-new-board-list').click
- wait_for_requests
- end
-
- it 'creates lists from all ancestor group labels' do
- [grandparent_group_label, parent_group_label].each do |label|
- find('a', text: label.title).click
- end
-
- wait_for_requests
-
- expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
- expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
- end
-
- it 'does not create lists from descendant groups' do
- expect(page).not_to have_selector('a', text: child_group_label.title)
- end
- end
- end
end
diff --git a/spec/features/merge_request/batch_comments_spec.rb b/spec/features/merge_request/batch_comments_spec.rb
index c646698219b..f695b225915 100644
--- a/spec/features/merge_request/batch_comments_spec.rb
+++ b/spec/features/merge_request/batch_comments_spec.rb
@@ -25,10 +25,6 @@ RSpec.describe 'Merge request > Batch comments', :js do
visit_diffs
end
- it 'has review bar' do
- expect(page).to have_selector('[data-testid="review_bar_component"]', visible: false)
- end
-
it 'adds draft note' do
write_diff_comment
diff --git a/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb b/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
index 45ee914de9d..caf0c609f64 100644
--- a/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
+++ b/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Merge request > User edits reviewers sidebar', :js do
page.within '.dropdown-menu-user' do
expect(page).to have_link('Invite Members')
- expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
expect(page).to have_selector('[data-track-label="edit_reviewer"]')
end
diff --git a/spec/features/merge_requests/rss_spec.rb b/spec/features/merge_requests/rss_spec.rb
new file mode 100644
index 00000000000..9fc3d3d6ae1
--- /dev/null
+++ b/spec/features/merge_requests/rss_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Project Merge Requests RSS' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :repository, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project, assignees: [user]) }
+ let_it_be(:path) { project_merge_requests_path(project) }
+
+ before_all do
+ group.add_developer(user)
+ end
+
+ context 'when signed in' do
+ let_it_be(:user) { create(:user) }
+
+ before_all do
+ project.add_developer(user)
+ end
+
+ before do
+ sign_in(user)
+ visit path
+ end
+
+ it_behaves_like "it has an RSS button with current_user's feed token"
+ it_behaves_like "an autodiscoverable RSS feed with current_user's feed token"
+ end
+
+ context 'when signed out' do
+ before do
+ visit path
+ end
+
+ it_behaves_like "it has an RSS button without a feed token"
+ it_behaves_like "an autodiscoverable RSS feed without a feed token"
+ end
+
+ describe 'feeds' do
+ it_behaves_like 'updates atom feed link', :project do
+ let(:path) { project_merge_requests_path(project, assignee_id: user.id) }
+ end
+ end
+end
diff --git a/spec/features/merge_requests/user_sees_empty_state_spec.rb b/spec/features/merge_requests/user_sees_empty_state_spec.rb
index ac07b31731d..056da53c47b 100644
--- a/spec/features/merge_requests/user_sees_empty_state_spec.rb
+++ b/spec/features/merge_requests/user_sees_empty_state_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Merge request > User sees empty state' do
+ include ProjectForksHelper
+
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
@@ -37,4 +39,23 @@ RSpec.describe 'Merge request > User sees empty state' do
expect(page).to have_content('To widen your search, change or remove filters above')
end
end
+
+ context 'as member of a fork' do
+ let(:fork_user) { create(:user) }
+ let(:forked_project) { fork_project(project, fork_user, namespace: fork_user.namespace, repository: true) }
+
+ before do
+ forked_project.add_maintainer(fork_user)
+ sign_in(fork_user)
+ end
+
+ it 'shows an empty state and a "New merge request" button' do
+ visit project_merge_requests_path(project, search: 'foo')
+
+ expect(page).to have_selector('.empty-state')
+ within('.empty-state') do
+ expect(page).to have_link 'New merge request', href: project_new_merge_request_path(forked_project)
+ end
+ end
+ end
end
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index de511e99182..8025db9f86d 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -56,7 +56,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
click_on "Create personal access token"
expect(active_personal_access_tokens).to have_text(name)
- expect(active_personal_access_tokens).to have_text('In')
+ expect(active_personal_access_tokens).to have_text('in')
expect(active_personal_access_tokens).to have_text('api')
expect(active_personal_access_tokens).to have_text('read_user')
expect(created_personal_access_token).not_to be_empty
@@ -85,6 +85,18 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
expect(active_personal_access_tokens).to have_text(personal_access_token.name)
expect(active_personal_access_tokens).not_to have_text(impersonation_token.name)
end
+
+ context 'when User#time_display_relative is false' do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit profile_personal_access_tokens_path
+
+ expect(active_personal_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %d'))
+ end
+ end
end
describe "inactive tokens" do
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index d941988d12f..af085b63155 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'User edit profile' do
fill_in 'user_skype', with: 'testskype'
fill_in 'user_linkedin', with: 'testlinkedin'
fill_in 'user_twitter', with: 'testtwitter'
- fill_in 'user_website_url', with: 'testurl'
+ fill_in 'user_website_url', with: 'http://testurl.com'
fill_in 'user_location', with: 'Ukraine'
fill_in 'user_bio', with: 'I <3 GitLab :tada:'
fill_in 'user_job_title', with: 'Frontend Engineer'
@@ -43,9 +43,8 @@ RSpec.describe 'User edit profile' do
skype: 'testskype',
linkedin: 'testlinkedin',
twitter: 'testtwitter',
- website_url: 'testurl',
+ website_url: 'http://testurl.com',
bio: 'I <3 GitLab :tada:',
- bio_html: '<p data-sourcepos="1:1-1:18" dir="auto">I &lt;3 GitLab <gl-emoji title="party popper" data-name="tada" data-unicode-version="6.0">šŸŽ‰</gl-emoji></p>',
job_title: 'Frontend Engineer',
organization: 'GitLab'
)
@@ -54,6 +53,19 @@ RSpec.describe 'User edit profile' do
expect(page).to have_content('Profile was successfully updated')
end
+ it 'does not set secondary emails without user input' do
+ fill_in 'user_organization', with: 'GitLab'
+ submit_settings
+
+ user.reload
+ expect(page).to have_field('user_commit_email', with: '')
+ expect(page).to have_field('user_public_email', with: '')
+
+ User::SECONDARY_EMAIL_ATTRIBUTES.each do |attribute|
+ expect(user.read_attribute(attribute)).to be_blank
+ end
+ end
+
it 'shows an error if the full name contains an emoji', :js do
simulate_input('#user_name', 'Martin šŸ˜€')
submit_settings
@@ -65,6 +77,17 @@ RSpec.describe 'User edit profile' do
end
end
+ it 'shows an error if the website url is not valid' do
+ fill_in 'user_website_url', with: 'admin@gitlab.com'
+ submit_settings
+
+ expect(user.reload).to have_attributes(
+ website_url: ''
+ )
+
+ expect(page).to have_content('Website url is not a valid URL')
+ end
+
describe 'when I change my email' do
before do
user.send_reset_password_instructions
diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb
index 192bccd6f6e..7fe1c63f490 100644
--- a/spec/features/projects/ci/editor_spec.rb
+++ b/spec/features/projects/ci/editor_spec.rb
@@ -27,10 +27,6 @@ RSpec.describe 'Pipeline Editor', :js do
end
context 'branch switcher' do
- before do
- stub_feature_flags(pipeline_editor_branch_switcher: true)
- end
-
def switch_to_branch(branch)
find('[data-testid="branch-selector"]').click
diff --git a/spec/features/projects/commits/user_browses_commits_spec.rb b/spec/features/projects/commits/user_browses_commits_spec.rb
index 76162fb800a..863fdbdadaa 100644
--- a/spec/features/projects/commits/user_browses_commits_spec.rb
+++ b/spec/features/projects/commits/user_browses_commits_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe 'User browses commits' do
sign_in(user)
end
- it 'renders commit' do
+ it 'renders commit', :js do
visit project_commit_path(project, sample_commit.id)
expect(page).to have_content(sample_commit.message.gsub(/\s+/, ' '))
@@ -103,7 +103,7 @@ RSpec.describe 'User browses commits' do
context 'when the blob does not exist' do
let(:commit) { create(:commit, project: project) }
- it 'renders successfully' do
+ it 'renders successfully', :js do
allow_next_instance_of(Gitlab::Diff::File) do |instance|
allow(instance).to receive(:blob).and_return(nil)
end
@@ -113,7 +113,9 @@ RSpec.describe 'User browses commits' do
visit(project_commit_path(project, commit))
- expect(find('.diff-file-changes', visible: false)).to have_content('files/ruby/popen.rb')
+ click_button '2 changed files'
+
+ expect(find('[data-testid="diff-stats-dropdown"]')).to have_content('files/ruby/popen.rb')
end
end
diff --git a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
index f6330491886..71c9d89fbde 100644
--- a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
+++ b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
@@ -66,20 +66,4 @@ RSpec.describe 'User updates feature flag', :js do
end
end
end
-
- context 'with a legacy feature flag' do
- let!(:feature_flag) do
- create_flag(project, 'ci_live_trace', true,
- description: 'For live trace feature',
- version: :legacy_flag)
- end
-
- let!(:scope) { create_scope(feature_flag, 'review/*', true) }
-
- it 'shows not found error' do
- visit(edit_project_feature_flag_path(project, feature_flag))
-
- expect(page).to have_text 'Page Not Found'
- end
- end
end
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index 302187917b7..00e85a215b8 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe 'Import/Export - project import integration test', :js do
let(:export_path) { "#{Dir.tmpdir}/import_file_spec" }
before do
+ stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
stub_uploads_object_storage(FileUploader)
allow_next_instance_of(Gitlab::ImportExport) do |instance|
allow(instance).to receive(:storage_path).and_return(export_path)
diff --git a/spec/features/projects/jobs/permissions_spec.rb b/spec/features/projects/jobs/permissions_spec.rb
index 140d5dee270..a904ba770dd 100644
--- a/spec/features/projects/jobs/permissions_spec.rb
+++ b/spec/features/projects/jobs/permissions_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe 'Project Jobs Permissions' do
it_behaves_like 'recent job page details responds with status', 200 do
it 'renders job details', :js do
- expect(page).to have_content "Job ##{job.id}"
+ expect(page).to have_content "Job #{job.name}"
expect(page).to have_css '.log-line'
end
end
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 9b199157d79..060b7ffbfc9 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'User browses a job', :js do
it 'erases the job log', :js do
wait_for_requests
- expect(page).to have_content("Job ##{build.id}")
+ expect(page).to have_content("Job #{build.name}")
expect(page).to have_css('.job-log')
# scroll to the top of the page first
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 94543290050..113ba692497 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'Projects > Members > User requests access', :js do
it 'user can request access to a project' do
perform_enqueued_jobs { click_link 'Request Access' }
- expect(ActionMailer::Base.deliveries.last.to).to eq [maintainer.notification_email]
+ expect(ActionMailer::Base.deliveries.last.to).to eq [maintainer.notification_email_or_default]
expect(ActionMailer::Base.deliveries.last.subject).to eq "Request to join the #{project.full_name} project"
expect(project.requesters.exists?(user_id: user)).to be_truthy
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 0b293970703..39f9d3b331b 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -6,6 +6,10 @@ RSpec.describe 'New project', :js do
include Select2Helper
include Spec::Support::Helpers::Features::TopNavSpecHelpers
+ before do
+ stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
+ end
+
context 'as a user' do
let(:user) { create(:user) }
diff --git a/spec/features/projects/package_files_spec.rb b/spec/features/projects/package_files_spec.rb
index c5c03396d71..6dc0294bb9e 100644
--- a/spec/features/projects/package_files_spec.rb
+++ b/spec/features/projects/package_files_spec.rb
@@ -23,20 +23,6 @@ RSpec.describe 'PackageFiles' do
expect(status_code).to eq(200)
end
- context 'when package_details_apollo feature flag is off' do
- before do
- stub_feature_flags(package_details_apollo: false)
- end
-
- it 'renders the download link with the correct url', :js do
- visit project_package_path(project, package)
-
- download_url = download_project_package_file_path(project, package_file)
-
- expect(page).to have_link(package_file.file_name, href: download_url)
- end
- end
-
it 'does not allow download of package belonging to different project' do
another_package = create(:maven_package)
another_file = another_package.package_files.first
diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb
index 30298f79312..7fcc8200b1c 100644
--- a/spec/features/projects/packages_spec.rb
+++ b/spec/features/projects/packages_spec.rb
@@ -37,14 +37,6 @@ RSpec.describe 'Packages' do
it_behaves_like 'packages list'
- context 'when package_details_apollo feature flag is off' do
- before do
- stub_feature_flags(package_details_apollo: false)
- end
-
- it_behaves_like 'package details link'
- end
-
it_behaves_like 'package details link'
context 'deleting a package' do
diff --git a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
index 4dfd4416eeb..bc84ccaa432 100644
--- a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Slack slash commands', :js do
end
it 'shows a help message' do
- expect(page).to have_content('This service allows users to perform common')
+ expect(page).to have_content('Perform common operations in this project')
end
it 'redirects to the integrations page after saving but not activating' do
@@ -42,6 +42,6 @@ RSpec.describe 'Slack slash commands', :js do
end
it 'shows help content' do
- expect(page).to have_content('This service allows users to perform common operations on this project by entering slash commands in Slack.')
+ expect(page).to have_content('Perform common operations in this project by entering slash commands in Slack.')
end
end
diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb
index 33e2623522e..deeab084c5f 100644
--- a/spec/features/projects/settings/access_tokens_spec.rb
+++ b/spec/features/projects/settings/access_tokens_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
click_on 'Create project access token'
expect(active_project_access_tokens).to have_text(name)
- expect(active_project_access_tokens).to have_text('In')
+ expect(active_project_access_tokens).to have_text('in')
expect(active_project_access_tokens).to have_text('api')
expect(active_project_access_tokens).to have_text('read_api')
expect(active_project_access_tokens).to have_text('Maintainer')
@@ -156,6 +156,18 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
expect(active_project_access_tokens).to have_text(project_access_token.name)
end
+
+ context 'when User#time_display_relative is false' do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit project_settings_access_tokens_path(project)
+
+ expect(active_project_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %d'))
+ end
+ end
end
describe 'inactive tokens' do
diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb
index 2d8c418b7d0..e3d75c30e5e 100644
--- a/spec/features/projects/settings/monitor_settings_spec.rb
+++ b/spec/features/projects/settings/monitor_settings_spec.rb
@@ -150,6 +150,33 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
assert_text('Connection failed. Check Auth Token and try again.')
end
end
+
+ context 'integrated error tracking backend' do
+ it 'successfully fills and submits the form' do
+ visit project_settings_operations_path(project)
+
+ wait_for_requests
+
+ within '.js-error-tracking-settings' do
+ click_button('Expand')
+ end
+
+ expect(page).to have_content('Error tracking backend')
+
+ within '.js-error-tracking-settings' do
+ check('Active')
+ choose('GitLab')
+ end
+
+ expect(page).not_to have_content('Sentry API URL')
+
+ click_button('Save changes')
+
+ wait_for_requests
+
+ assert_text('Your changes have been saved')
+ end
+ end
end
context 'grafana integration settings form' do
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index f420a8a76b9..4e1b55d3d70 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -31,11 +31,11 @@ RSpec.describe 'Projects > Settings > Repository settings' do
before do
stub_container_registry_config(enabled: true)
stub_feature_flags(ajax_new_deploy_token: project)
- visit project_settings_repository_path(project)
end
it_behaves_like 'a deploy token in settings' do
let(:entity_type) { 'project' }
+ let(:page_path) { project_settings_repository_path(project) }
end
end
diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb
index 91355d8f625..0924f8320e1 100644
--- a/spec/features/projects/settings/service_desk_setting_spec.rb
+++ b/spec/features/projects/settings/service_desk_setting_spec.rb
@@ -38,7 +38,6 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache do
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
diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb
index be4b6d6b82d..02a634a0fcc 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -43,10 +43,15 @@ RSpec.describe 'Projects > Settings > User manages project members' do
visit(project_project_members_path(project))
- click_link('Import a project')
+ click_on 'Import from a project'
+ click_on 'Select a project'
+ wait_for_requests
- select2(project2.id, from: '#source_project_id')
- click_button('Import project members')
+ click_button project2.name
+ click_button 'Import project members'
+ wait_for_requests
+
+ page.refresh
expect(find_member_row(user_mike)).to have_content('Reporter')
end
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index 2dc2f168896..9f08759603e 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe 'User creates a project', :js do
let(:user) { create(:user) }
before do
+ stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false)
sign_in(user)
create(:personal_key, user: user)
end
diff --git a/spec/features/registrations/experience_level_spec.rb b/spec/features/registrations/experience_level_spec.rb
deleted file mode 100644
index f432215d4a8..00000000000
--- a/spec/features/registrations/experience_level_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Experience level screen' do
- let_it_be(:user) { create(:user, :unconfirmed) }
- let_it_be(:group) { create(:group) }
-
- before do
- group.add_owner(user)
- gitlab_sign_in(user)
- visit users_sign_up_experience_level_path(namespace_path: group.to_param)
- end
-
- subject { page }
-
- it 'shows the intro content' do
- is_expected.to have_content('Hello there')
- is_expected.to have_content('Welcome to the guided GitLab tour')
- is_expected.to have_content('What describes you best?')
- end
-
- it 'shows the option for novice' do
- is_expected.to have_content('Novice')
- 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 DevOps')
- is_expected.to have_content('Show me advanced features')
- end
-
- it 'does not display any flash messages' do
- is_expected.not_to have_selector('.flash-container')
- is_expected.not_to have_content("Please check your email (#{user.email}) to verify that you own this address and unlock the power of CI/CD")
- end
-
- it 'does not include the footer links' do
- is_expected.not_to have_link('Help')
- is_expected.not_to have_link('About GitLab')
- end
-end
diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb
index 273d3aa346f..6b21412ae3d 100644
--- a/spec/features/users/anonymous_sessions_spec.rb
+++ b/spec/features/users/anonymous_sessions_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
+ include SessionHelpers
+
it 'creates a session with a short TTL when login fails' do
visit new_user_session_path
# The session key only gets created after a post
@@ -12,7 +14,7 @@ RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
expect(page).to have_content('Invalid login or password')
- expect_single_session_with_expiration(Settings.gitlab['unauthenticated_session_expire_delay'])
+ expect_single_session_with_short_ttl
end
it 'increases the TTL when the login succeeds' do
@@ -21,21 +23,17 @@ RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
expect(page).to have_content(user.name)
- expect_single_session_with_expiration(Settings.gitlab['session_expire_delay'] * 60)
+ expect_single_session_with_authenticated_ttl
end
- def expect_single_session_with_expiration(expiration)
- session_keys = get_session_keys
-
- expect(session_keys.size).to eq(1)
- expect(get_ttl(session_keys.first)).to eq expiration
- end
+ context 'with an unauthorized project' do
+ let_it_be(:project) { create(:project, :repository) }
- def get_session_keys
- Gitlab::Redis::SharedState.with { |redis| redis.scan_each(match: 'session:gitlab:*').to_a }
- end
+ it 'creates a session with a short TTL' do
+ visit project_raw_path(project, 'master/README.md')
- def get_ttl(key)
- Gitlab::Redis::SharedState.with { |redis| redis.ttl(key) }
+ expect_single_session_with_short_ttl
+ expect(page).to have_current_path(new_user_session_path)
+ end
end
end
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 6c38d5d8b24..afd750d02eb 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -2,9 +2,10 @@
require 'spec_helper'
-RSpec.describe 'Login' do
+RSpec.describe 'Login', :clean_gitlab_redis_shared_state do
include TermsHelper
include UserLoginHelper
+ include SessionHelpers
before do
stub_authentication_activity_metrics(debug: true)
@@ -59,6 +60,7 @@ RSpec.describe 'Login' do
fill_in 'user_password', with: 'password'
click_button 'Sign in'
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
end
@@ -192,6 +194,7 @@ RSpec.describe 'Login' do
enter_code(user.current_otp)
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
+ expect_single_session_with_authenticated_ttl
end
it 'does not allow sign-in if the user password is updated before entering a one-time code' do
@@ -210,6 +213,7 @@ RSpec.describe 'Login' do
enter_code(user.current_otp)
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
end
@@ -237,6 +241,8 @@ RSpec.describe 'Login' do
expect(page).to have_content('Invalid two-factor code')
enter_code(user.current_otp)
+
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
end
@@ -353,6 +359,7 @@ RSpec.describe 'Login' do
sign_in_using_saml!
+ expect_single_session_with_authenticated_ttl
expect(page).not_to have_content('Two-Factor Authentication')
expect(current_path).to eq root_path
end
@@ -371,6 +378,7 @@ RSpec.describe 'Login' do
enter_code(user.current_otp)
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
end
end
@@ -391,6 +399,7 @@ RSpec.describe 'Login' do
gitlab_sign_in(user)
+ expect_single_session_with_authenticated_ttl
expect(current_path).to eq root_path
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
@@ -402,6 +411,7 @@ RSpec.describe 'Login' do
gitlab_sign_in(user)
visit new_user_session_path
+ expect_single_session_with_authenticated_ttl
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
@@ -443,6 +453,7 @@ RSpec.describe 'Login' do
gitlab_sign_in(user)
+ expect_single_session_with_short_ttl
expect(page).to have_content('Invalid login or password.')
end
end
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index fb2873f1c96..e629d329033 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe 'User page' do
include ExternalAuthorizationServiceHelpers
- let_it_be(:user) { create(:user, bio: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)') }
+ let_it_be(:user) { create(:user, bio: '<b>Lorem</b> <i>ipsum</i> dolor sit <a href="https://example.com">amet</a>') }
subject(:visit_profile) { visit(user_path(user)) }
@@ -186,7 +186,17 @@ RSpec.describe 'User page' do
end
context 'with blocked profile' do
- let_it_be(:user) { create(:user, state: :blocked) }
+ let_it_be(:user) do
+ create(
+ :user,
+ state: :blocked,
+ organization: 'GitLab - work info test',
+ job_title: 'Frontend Engineer',
+ pronunciation: 'pruh-nuhn-see-ay-shn'
+ )
+ end
+
+ let_it_be(:status) { create(:user_status, user: user, message: "Working hard!") }
it 'shows no tab' do
subject
@@ -211,7 +221,10 @@ RSpec.describe 'User page' do
subject
expect(page).not_to have_css(".profile-user-bio")
- expect(page).not_to have_css(".profile-link-holder")
+ expect(page).not_to have_content('GitLab - work info test')
+ expect(page).not_to have_content('Frontend Engineer')
+ expect(page).not_to have_content('Working hard!')
+ expect(page).not_to have_content("Pronounced as: pruh-nuhn-see-ay-shn")
end
it 'shows username' do
@@ -222,7 +235,17 @@ RSpec.describe 'User page' do
end
context 'with unconfirmed user' do
- let_it_be(:user) { create(:user, :unconfirmed) }
+ let_it_be(:user) do
+ create(
+ :user,
+ :unconfirmed,
+ organization: 'GitLab - work info test',
+ job_title: 'Frontend Engineer',
+ pronunciation: 'pruh-nuhn-see-ay-shn'
+ )
+ end
+
+ let_it_be(:status) { create(:user_status, user: user, message: "Working hard!") }
shared_examples 'unconfirmed user profile' do
before do
@@ -240,7 +263,10 @@ RSpec.describe 'User page' do
it 'shows no additional fields' do
expect(page).not_to have_css(".profile-user-bio")
- expect(page).not_to have_css(".profile-link-holder")
+ expect(page).not_to have_content('GitLab - work info test')
+ expect(page).not_to have_content('Frontend Engineer')
+ expect(page).not_to have_content('Working hard!')
+ expect(page).not_to have_content("Pronounced as: pruh-nuhn-see-ay-shn")
end
it 'shows private profile message' do
@@ -403,4 +429,27 @@ RSpec.describe 'User page' do
end
end
end
+
+ context 'GPG keys' do
+ context 'when user has verified GPG keys' do
+ let_it_be(:user) { create(:user, email: GpgHelpers::User1.emails.first) }
+ let_it_be(:gpg_key) { create(:gpg_key, user: user, key: GpgHelpers::User1.public_key) }
+ let_it_be(:gpg_key2) { create(:gpg_key, user: user, key: GpgHelpers::User1.public_key2) }
+
+ it 'shows link to public GPG keys' do
+ subject
+
+ expect(page).to have_link('View public GPG keys', href: user_gpg_keys_path(user))
+ end
+ end
+
+ context 'when user does not have verified GPG keys' do
+ it 'does not show link to public GPG keys' do
+ subject
+
+ expect(page).not_to have_link('View public GPG key', href: user_gpg_keys_path(user))
+ expect(page).not_to have_link('View public GPG keys', href: user_gpg_keys_path(user))
+ end
+ end
+ end
end