diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 14:34:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 14:34:42 +0000 |
commit | 9f46488805e86b1bc341ea1620b866016c2ce5ed (patch) | |
tree | f9748c7e287041e37d6da49e0a29c9511dc34768 /spec/features/projects | |
parent | dfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff) | |
download | gitlab-ce-9f46488805e86b1bc341ea1620b866016c2ce5ed.tar.gz |
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'spec/features/projects')
44 files changed, 827 insertions, 402 deletions
diff --git a/spec/features/projects/activity/user_sees_design_comment_spec.rb b/spec/features/projects/activity/user_sees_design_comment_spec.rb new file mode 100644 index 00000000000..9864e9ce29f --- /dev/null +++ b/spec/features/projects/activity/user_sees_design_comment_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Projects > Activity > User sees design comment', :js do + include DesignManagementTestHelpers + + let_it_be(:project) { create(:project, :repository, :public) } + let_it_be(:user) { project.creator } + let_it_be(:commenter) { create(:user) } + let_it_be(:issue) { create(:closed_issue, project: project) } + let_it_be(:design) { create(:design, issue: issue) } + + let(:design_activity) do + "#{commenter.name} #{commenter.to_reference} commented on design" + end + + let(:issue_activity) do + "#{user.name} #{user.to_reference} closed issue #{issue.to_reference}" + end + + before_all do + project.add_developer(commenter) + create(:event, :for_design, project: project, author: commenter, design: design) + create(:closed_issue_event, project: project, author: user, target: issue) + end + + before do + enable_design_management + end + + it 'shows the design comment action in the activity page' do + visit activity_project_path(project) + + expect(page).to have_content(design_activity) + end + + it 'allows to filter out the design event with the "event_filter=issue" URL param', :aggregate_failures do + visit activity_project_path(project, event_filter: EventFilter::ISSUE) + + expect(page).not_to have_content(design_activity) + expect(page).to have_content(issue_activity) + end + + it 'allows to filter in the event with the "event_filter=comments" URL param', :aggregate_failures do + visit activity_project_path(project, event_filter: EventFilter::COMMENTS) + + expect(page).to have_content(design_activity) + expect(page).not_to have_content(issue_activity) + end +end diff --git a/spec/features/projects/branches/user_creates_branch_spec.rb b/spec/features/projects/branches/user_creates_branch_spec.rb index 156edb973cd..8aac188160b 100644 --- a/spec/features/projects/branches/user_creates_branch_spec.rb +++ b/spec/features/projects/branches/user_creates_branch_spec.rb @@ -16,18 +16,18 @@ describe "User creates branch", :js do end it "creates new branch" do - BRANCH_NAME = "deploy_keys".freeze + branch_name = "deploy_keys".freeze - create_branch(BRANCH_NAME) + create_branch(branch_name) - expect(page).to have_content(BRANCH_NAME) + expect(page).to have_content(branch_name) end context "when branch name is invalid" do it "does not create new branch" do - INVALID_BRANCH_NAME = "1.0 stable".freeze + invalid_branch_name = "1.0 stable".freeze - fill_in("branch_name", with: INVALID_BRANCH_NAME) + fill_in("branch_name", with: invalid_branch_name) page.find("body").click # defocus the branch_name input select_branch("master") diff --git a/spec/features/projects/commit/comments/user_edits_comments_spec.rb b/spec/features/projects/commit/comments/user_edits_comments_spec.rb index 0fa2b2ff232..29132173674 100644 --- a/spec/features/projects/commit/comments/user_edits_comments_spec.rb +++ b/spec/features/projects/commit/comments/user_edits_comments_spec.rb @@ -19,7 +19,7 @@ describe "User edits a comment on a commit", :js do end it "edits comment" do - NEW_COMMENT_TEXT = "+1 Awesome!".freeze + new_comment_text = "+1 Awesome!".freeze page.within(".main-notes-list") do note = find(".note") @@ -31,14 +31,14 @@ describe "User edits a comment on a commit", :js do page.find(".current-note-edit-form textarea") page.within(".current-note-edit-form") do - fill_in("note[note]", with: NEW_COMMENT_TEXT) + fill_in("note[note]", with: new_comment_text) click_button("Save comment") end wait_for_requests page.within(".note") do - expect(page).to have_content(NEW_COMMENT_TEXT) + expect(page).to have_content(new_comment_text) end end end diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb index a51f121bf59..32eaf690950 100644 --- a/spec/features/projects/environments_pod_logs_spec.rb +++ b/spec/features/projects/environments_pod_logs_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe 'Environment > Pod Logs', :js do +describe 'Environment > Pod Logs', :js, :kubeclient do include KubernetesHelpers let(:pod_names) { %w(kube-pod) } diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb index 5c52abaeb62..7e3d8e5c1c5 100644 --- a/spec/features/projects/files/user_browses_files_spec.rb +++ b/spec/features/projects/files/user_browses_files_spec.rb @@ -171,6 +171,18 @@ describe "User browses files" do end end + context 'when commit message has markdown', :js do + before do + project.repository.create_file(user, 'index', 'test', message: ':star: testing', branch_name: 'master') + + visit(project_tree_path(project, "master")) + end + + it 'renders emojis' do + expect(page).to have_selector('gl-emoji', count: 2) + end + end + context "when browsing a `improve/awesome` branch", :js do before do visit(project_tree_path(project, "improve/awesome")) @@ -197,6 +209,33 @@ describe "User browses files" do end end + context "when browsing a `Ääh-test-utf-8` branch", :js do + before do + project.repository.create_branch('Ääh-test-utf-8', project.repository.root_ref) + visit(project_tree_path(project, "Ääh-test-utf-8")) + end + + it "shows files from a repository" do + expect(page).to have_content("VERSION") + .and have_content(".gitignore") + .and have_content("LICENSE") + + click_link("files") + + page.within('.repo-breadcrumb') do + expect(page).to have_link('files') + end + + click_link("html") + + page.within('.repo-breadcrumb') do + expect(page).to have_link('html') + end + + expect(page).to have_link('500.html') + end + end + context "when browsing a `test-#` branch", :js do before do project.repository.create_branch('test-#', project.repository.root_ref) diff --git a/spec/features/projects/graph_spec.rb b/spec/features/projects/graph_spec.rb index 6b2a9a6b852..25efb7b28a7 100644 --- a/spec/features/projects/graph_spec.rb +++ b/spec/features/projects/graph_spec.rb @@ -59,7 +59,7 @@ describe 'Project Graph', :js do it 'HTML escapes branch name' do expect(page.body).to include("Commit statistics for <strong>#{ERB::Util.html_escape(branch_name)}</strong>") - expect(page.body).not_to include(branch_name) + expect(page.find('.dropdown-toggle-text')['innerHTML']).to eq(ERB::Util.html_escape(branch_name)) end end diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index 7ee8f42e6ef..1d6d5ae1b4d 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -52,7 +52,7 @@ describe 'Import/Export - project export integration test', :js do project_json_path = File.join(tmpdir, 'project.json') expect(File).to exist(project_json_path) - project_hash = JSON.parse(IO.read(project_json_path)) + project_hash = Gitlab::Json.parse(IO.read(project_json_path)) sensitive_words.each do |sensitive_word| found = find_sensitive_attributes(sensitive_word, project_hash) @@ -78,7 +78,7 @@ describe 'Import/Export - project export integration test', :js do expect(File).to exist(project_json_path) relations = [] - relations << JSON.parse(IO.read(project_json_path)) + relations << Gitlab::Json.parse(IO.read(project_json_path)) Dir.glob(File.join(tmpdir, 'tree/project', '*.ndjson')) do |rb_filename| File.foreach(rb_filename) do |line| json = ActiveSupport::JSON.decode(line) diff --git a/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb b/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb new file mode 100644 index 00000000000..d9a72f2d5c5 --- /dev/null +++ b/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'User paginates issue designs', :js do + include DesignManagementTestHelpers + + let(:project) { create(:project_empty_repo, :public) } + let(:issue) { create(:issue, project: project) } + + before do + enable_design_management + + create_list(:design, 2, :with_file, issue: issue) + + visit project_issue_path(project, issue) + + click_link 'Designs' + + wait_for_requests + + find('.js-design-list-item', match: :first).click + end + + it 'paginates to next design' do + expect(find('.js-previous-design')[:disabled]).to eq('true') + + page.within(find('.js-design-header')) do + expect(page).to have_content('1 of 2') + end + + find('.js-next-design').click + + expect(find('.js-previous-design')[:disabled]).not_to eq('true') + + page.within(find('.js-design-header')) do + expect(page).to have_content('2 of 2') + end + end +end diff --git a/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb b/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb new file mode 100644 index 00000000000..2238e86a47f --- /dev/null +++ b/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'User design permissions', :js do + include DesignManagementTestHelpers + + let(:project) { create(:project_empty_repo, :public) } + let(:issue) { create(:issue, project: project) } + + before do + enable_design_management + + visit project_issue_path(project, issue) + + click_link 'Designs' + + wait_for_requests + end + + it 'user does not have permissions to upload design' do + expect(page).not_to have_field('design_file') + end +end diff --git a/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb b/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb new file mode 100644 index 00000000000..d160ab95a65 --- /dev/null +++ b/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'User uploads new design', :js do + include DesignManagementTestHelpers + + let_it_be(:project) { create(:project_empty_repo, :public) } + let_it_be(:user) { project.owner } + let_it_be(:issue) { create(:issue, project: project) } + + before do + sign_in(user) + end + + context "when the feature is available" do + before do + enable_design_management + + visit project_issue_path(project, issue) + + click_link 'Designs' + + wait_for_requests + end + + it 'uploads designs' do + attach_file(:design_file, logo_fixture, make_visible: true) + + expect(page).to have_selector('.js-design-list-item', count: 1) + + within first('#designs-tab .js-design-list-item') do + expect(page).to have_content('dk.png') + end + + attach_file(:design_file, gif_fixture, make_visible: true) + + expect(page).to have_selector('.js-design-list-item', count: 2) + end + end + + context 'when the feature is not available' do + before do + visit project_issue_path(project, issue) + + click_link 'Designs' + + wait_for_requests + end + + it 'shows the message about requirements' do + expect(page).to have_content("To enable design management, you'll need to meet the requirements.") + end + end + + def logo_fixture + Rails.root.join('spec', 'fixtures', 'dk.png') + end + + def gif_fixture + Rails.root.join('spec', 'fixtures', 'banana_sample.gif') + end +end diff --git a/spec/features/projects/issues/design_management/user_views_design_images_spec.rb b/spec/features/projects/issues/design_management/user_views_design_images_spec.rb new file mode 100644 index 00000000000..3d0f4df55c4 --- /dev/null +++ b/spec/features/projects/issues/design_management/user_views_design_images_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Users views raw design image files' do + include DesignManagementTestHelpers + + let_it_be(:project) { create(:project, :public) } + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:design) { create(:design, :with_file, issue: issue, versions_count: 2) } + let(:newest_version) { design.versions.ordered.first } + let(:oldest_version) { design.versions.ordered.last } + + before do + enable_design_management + end + + it 'serves the latest design version when no ref is given' do + visit project_design_management_designs_raw_image_path(design.project, design) + + expect(response_headers[Gitlab::Workhorse::SEND_DATA_HEADER]).to eq( + workhorse_data_header_for_version(oldest_version.sha) + ) + end + + it 'serves the correct design version when a ref is given' do + visit project_design_management_designs_raw_image_path(design.project, design, oldest_version.sha) + + expect(response_headers[Gitlab::Workhorse::SEND_DATA_HEADER]).to eq( + workhorse_data_header_for_version(oldest_version.sha) + ) + end + + private + + def workhorse_data_header_for_version(ref) + blob = project.design_repository.blob_at(ref, design.full_path) + + Gitlab::Workhorse.send_git_blob(project.design_repository, blob).last + end +end diff --git a/spec/features/projects/issues/design_management/user_views_design_spec.rb b/spec/features/projects/issues/design_management/user_views_design_spec.rb new file mode 100644 index 00000000000..707049b0068 --- /dev/null +++ b/spec/features/projects/issues/design_management/user_views_design_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'User views issue designs', :js do + include DesignManagementTestHelpers + + let_it_be(:project) { create(:project_empty_repo, :public) } + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:design) { create(:design, :with_file, issue: issue) } + + before do + enable_design_management + + visit project_issue_path(project, issue) + + click_link 'Designs' + end + + it 'opens design detail' do + click_link design.filename + + page.within(find('.js-design-header')) do + expect(page).to have_content(design.filename) + end + + expect(page).to have_selector('.js-design-image') + end +end diff --git a/spec/features/projects/issues/design_management/user_views_designs_spec.rb b/spec/features/projects/issues/design_management/user_views_designs_spec.rb new file mode 100644 index 00000000000..a4fb7456922 --- /dev/null +++ b/spec/features/projects/issues/design_management/user_views_designs_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'User views issue designs', :js do + include DesignManagementTestHelpers + + let_it_be(:project) { create(:project_empty_repo, :public) } + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:design) { create(:design, :with_file, issue: issue) } + + before do + enable_design_management + end + + context 'navigates from the issue view' do + before do + visit project_issue_path(project, issue) + click_link 'Designs' + wait_for_requests + end + + it 'fetches list of designs' do + expect(page).to have_selector('.js-design-list-item', count: 1) + end + end + + context 'navigates directly to the design collection view' do + before do + visit designs_project_issue_path(project, issue) + end + + it 'expands the sidebar' do + expect(page).to have_selector('.layout-page.right-sidebar-expanded') + end + end + + context 'navigates directly to the individual design view' do + before do + visit designs_project_issue_path(project, issue, vueroute: design.filename) + end + + it 'sees the design' do + expect(page).to have_selector('.js-design-detail') + end + end +end diff --git a/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb b/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb new file mode 100644 index 00000000000..a9e4aa899a7 --- /dev/null +++ b/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'User views an SVG design that contains XSS', :js do + include DesignManagementTestHelpers + + let(:project) { create(:project_empty_repo, :public) } + let(:issue) { create(:issue, project: project) } + let(:file) { Rails.root.join('spec', 'fixtures', 'logo_sample.svg') } + let(:design) { create(:design, :with_file, filename: 'xss.svg', file: file, issue: issue) } + + before do + enable_design_management + + visit designs_project_issue_path( + project, + issue, + { vueroute: design.filename } + ) + + wait_for_requests + end + + it 'has XSS within the SVG file' do + file_content = File.read(file) + + expect(file_content).to include("<script>alert('FAIL')</script>") + end + + it 'displays the SVG' do + expect(page).to have_selector("img.design-img[alt='xss.svg']", count: 1, visible: false) + end + + it 'does not execute the JavaScript within the SVG' do + # The expectation is that we can call the capybara `page.dismiss_prompt` + # method to close a JavaScript alert prompt without a `Capybara::ModalNotFound` + # being raised. + run_expectation = -> { + page.dismiss_prompt(wait: 1) + } + + # With the page loaded, there should be no alert modal + expect(run_expectation).to raise_error( + Capybara::ModalNotFound, + 'Unable to find modal dialog' + ) + + # Perform a negative control test of the above expectation. + # With an alert modal displaying, the modal should be dismissable. + execute_script('alert(true)') + + expect(run_expectation).not_to raise_error + end +end diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb index 84000ef73ce..f404699b2f6 100644 --- a/spec/features/projects/members/list_spec.rb +++ b/spec/features/projects/members/list_spec.rb @@ -34,7 +34,7 @@ describe 'Project members list' do expect(second_row).to be_blank end - it 'update user acess level', :js do + it 'update user access level', :js do project.add_developer(user2) visit_members_page @@ -86,6 +86,23 @@ describe 'Project members list' do end end + context 'project bots' do + let(:project_bot) { create(:user, :project_bot, name: 'project_bot') } + + before do + project.add_maintainer(project_bot) + end + + it 'does not show form used to change roles and "Expiration date" or the remove user button' do + project_member = project.project_members.find_by(user_id: project_bot.id) + + visit_members_page + + expect(page).not_to have_selector("#edit_project_member_#{project_member.id}") + expect(page).not_to have_selector("#project_member_#{project_member.id} .btn-remove") + end + end + def add_user(id, role) page.within ".invite-users-form" do select2(id, from: "#user_ids", multiple: true) diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb index 9dfdaf54a2f..1797ca8aa7d 100644 --- a/spec/features/projects/navbar_spec.rb +++ b/spec/features/projects/navbar_spec.rb @@ -12,6 +12,8 @@ describe 'Project navbar' do let_it_be(:project) { create(:project, :repository) } before do + stub_licensed_features(service_desk: false) + project.add_maintainer(user) sign_in(user) end @@ -40,7 +42,7 @@ describe 'Project navbar' do context 'when pages are available' do before do - allow(Gitlab.config.pages).to receive(:enabled).and_return(true) + stub_config(pages: { enabled: true }) insert_after_sub_nav_item( _('Operations'), @@ -53,4 +55,21 @@ describe 'Project navbar' do it_behaves_like 'verified navigation bar' end + + context 'when container registry is available' do + before do + stub_config(registry: { enabled: true }) + + insert_after_nav_item( + _('Operations'), + new_nav_item: { + nav_item: _('Packages & Registries'), + nav_sub_items: [_('Container Registry')] + } + ) + visit project_path(project) + end + + it_behaves_like 'verified navigation bar' + end end diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index e8846b5b617..de81547887b 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -19,32 +19,32 @@ describe 'Pipeline', :js do shared_context 'pipeline builds' do let!(:build_passed) do create(:ci_build, :success, - pipeline: pipeline, stage: 'build', name: 'build') + pipeline: pipeline, stage: 'build', stage_idx: 0, name: 'build') end let!(:build_failed) do create(:ci_build, :failed, - pipeline: pipeline, stage: 'test', name: 'test') + pipeline: pipeline, stage: 'test', stage_idx: 1, name: 'test') end let!(:build_preparing) do create(:ci_build, :preparing, - pipeline: pipeline, stage: 'deploy', name: 'prepare') + pipeline: pipeline, stage: 'deploy', stage_idx: 2, name: 'prepare') end let!(:build_running) do create(:ci_build, :running, - pipeline: pipeline, stage: 'deploy', name: 'deploy') + pipeline: pipeline, stage: 'deploy', stage_idx: 3, name: 'deploy') end let!(:build_manual) do create(:ci_build, :manual, - pipeline: pipeline, stage: 'deploy', name: 'manual-build') + pipeline: pipeline, stage: 'deploy', stage_idx: 3, name: 'manual-build') end let!(:build_scheduled) do create(:ci_build, :scheduled, - pipeline: pipeline, stage: 'deploy', name: 'delayed-job') + pipeline: pipeline, stage: 'deploy', stage_idx: 3, name: 'delayed-job') end let!(:build_external) do @@ -307,9 +307,12 @@ describe 'Pipeline', :js do context 'when the pipeline has manual stage' do before do - create(:ci_build, :manual, pipeline: pipeline, stage: 'publish', name: 'CentOS') - create(:ci_build, :manual, pipeline: pipeline, stage: 'publish', name: 'Debian') - create(:ci_build, :manual, pipeline: pipeline, stage: 'publish', name: 'OpenSUDE') + create(:ci_build, :manual, pipeline: pipeline, stage_idx: 10, stage: 'publish', name: 'CentOS') + create(:ci_build, :manual, pipeline: pipeline, stage_idx: 10, stage: 'publish', name: 'Debian') + create(:ci_build, :manual, pipeline: pipeline, stage_idx: 10, stage: 'publish', name: 'OpenSUDE') + + # force to update stages statuses + Ci::ProcessPipelineService.new(pipeline).execute visit_pipeline end @@ -324,9 +327,10 @@ describe 'Pipeline', :js do visit_pipeline end - it 'shows Pipeline, Jobs and Failed Jobs tabs with link' do + it 'shows Pipeline, Jobs, DAG and Failed Jobs tabs with link' do expect(page).to have_link('Pipeline') expect(page).to have_link('Jobs') + expect(page).to have_link('DAG') expect(page).to have_link('Failed Jobs') end @@ -611,6 +615,20 @@ describe 'Pipeline', :js do end end end + + context 'when FF dag_pipeline_tab is disabled' do + before do + stub_feature_flags(dag_pipeline_tab: false) + visit_pipeline + end + + it 'does not show DAG link' do + expect(page).to have_link('Pipeline') + expect(page).to have_link('Jobs') + expect(page).not_to have_link('DAG') + expect(page).to have_link('Failed Jobs') + end + end end context 'when user does not have access to read jobs' do @@ -862,9 +880,10 @@ describe 'Pipeline', :js do end context 'page tabs' do - it 'shows Pipeline and Jobs tabs with link' do + it 'shows Pipeline, Jobs and DAG tabs with link' do expect(page).to have_link('Pipeline') expect(page).to have_link('Jobs') + expect(page).to have_link('DAG') end it 'shows counter in Jobs tab' do @@ -1054,6 +1073,37 @@ describe 'Pipeline', :js do end end + describe 'GET /:project/pipelines/:id/dag' do + include_context 'pipeline builds' + + let(:project) { create(:project, :repository) } + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } + + before do + visit dag_project_pipeline_path(project, pipeline) + end + + it 'shows DAG tab pane as active' do + expect(page).to have_css('#js-tab-dag.active', visible: false) + end + + context 'page tabs' do + it 'shows Pipeline, Jobs and DAG tabs with link' do + expect(page).to have_link('Pipeline') + expect(page).to have_link('Jobs') + expect(page).to have_link('DAG') + end + + it 'shows counter in Jobs tab' do + expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s) + end + + it 'shows DAG tab as active' do + expect(page).to have_css('li.js-dag-tab-link .active') + end + end + end + context 'when user sees pipeline flags in a pipeline detail page' do let(:project) { create(:project, :repository) } diff --git a/spec/features/projects/serverless/functions_spec.rb b/spec/features/projects/serverless/functions_spec.rb index e494a0e9626..4c89af29339 100644 --- a/spec/features/projects/serverless/functions_spec.rb +++ b/spec/features/projects/serverless/functions_spec.rb @@ -40,7 +40,7 @@ describe 'Functions', :js do it_behaves_like "it's missing knative installation" end - context 'when the user has a cluster and knative installed and visits the serverless page' do + context 'when the user has a cluster and knative installed and visits the serverless page', :kubeclient do let(:cluster) { create(:cluster, :project, :provided_by_gcp, projects: [project]) } let(:service) { cluster.platform_kubernetes } let(:environment) { create(:environment, project: project) } diff --git a/spec/features/projects/services/disable_triggers_spec.rb b/spec/features/projects/services/disable_triggers_spec.rb index 2785f74bee2..d07abb94208 100644 --- a/spec/features/projects/services/disable_triggers_spec.rb +++ b/spec/features/projects/services/disable_triggers_spec.rb @@ -3,16 +3,12 @@ require 'spec_helper' describe 'Disable individual triggers' do - let(:project) { create(:project) } - let(:user) { project.owner } + include_context 'project service activation' + let(:checkbox_selector) { 'input[type=checkbox][id$=_events]' } before do - sign_in(user) - - visit(project_settings_integrations_path(project)) - - click_link(service_name) + visit_project_integration(service_name) end context 'service has multiple supported events' do diff --git a/spec/features/projects/services/prometheus_external_alerts_spec.rb b/spec/features/projects/services/prometheus_external_alerts_spec.rb index e33b2d9a75e..1a706f20352 100644 --- a/spec/features/projects/services/prometheus_external_alerts_spec.rb +++ b/spec/features/projects/services/prometheus_external_alerts_spec.rb @@ -3,26 +3,18 @@ require 'spec_helper' describe 'Prometheus external alerts', :js do - let(:project) { create(:project) } - let(:user) { create(:user) } + include_context 'project service activation' let(:alerts_section_selector) { '.js-prometheus-alerts' } let(:alerts_section) { page.find(alerts_section_selector) } - before do - sign_in(user) - project.add_maintainer(user) - - visit_edit_service - end - context 'with manual configuration' do before do create(:prometheus_service, project: project, api_url: 'http://prometheus.example.com', manual_configuration: '1', active: true) end it 'shows the Alerts section' do - visit_edit_service + visit_project_integration('Prometheus') expect(alerts_section).to have_content('Alerts') expect(alerts_section).to have_content('Receive alerts from manually configured Prometheus servers.') @@ -33,16 +25,10 @@ describe 'Prometheus external alerts', :js do context 'with no configuration' do it 'does not show the Alerts section' do + visit_project_integration('Prometheus') wait_for_requests expect(page).not_to have_css(alerts_section_selector) end end - - private - - def visit_edit_service - visit(project_settings_integrations_path(project)) - click_link('Prometheus') - end end diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb index 4f3fb6ac3bf..3c5005d0c0c 100644 --- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb +++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb @@ -3,29 +3,17 @@ require 'spec_helper' describe 'User activates issue tracker', :js do - let(:user) { create(:user) } - let(:project) { create(:project) } + include_context 'project service activation' let(:url) { 'http://tracker.example.com' } - def fill_short_form(disabled: false) - find('input[name="service[active]"] + button').click if disabled + def fill_form(disable: false, skip_new_issue_url: false) + click_active_toggle if disable fill_in 'service_project_url', with: url fill_in 'service_issues_url', with: "#{url}/:id" - end - - def fill_full_form(disabled: false) - fill_short_form(disabled: disabled) - fill_in 'service_new_issue_url', with: url - end - - before do - project.add_maintainer(user) - sign_in(user) - - visit project_settings_integrations_path(project) + fill_in 'service_new_issue_url', with: url unless skip_new_issue_url end shared_examples 'external issue tracker activation' do |tracker:, skip_new_issue_url: false| @@ -34,16 +22,10 @@ describe 'User activates issue tracker', :js do before do stub_request(:head, url).to_return(headers: { 'Content-Type' => 'application/json' }) - click_link(tracker) - - if skip_new_issue_url - fill_short_form - else - fill_full_form - end + visit_project_integration(tracker) + fill_form(skip_new_issue_url: skip_new_issue_url) - click_button('Test settings and save changes') - wait_for_requests + click_test_integration end it 'activates the service' do @@ -62,22 +44,10 @@ describe 'User activates issue tracker', :js do it 'activates the service' do stub_request(:head, url).to_raise(Gitlab::HTTP::Error) - click_link(tracker) + visit_project_integration(tracker) + fill_form(skip_new_issue_url: skip_new_issue_url) - if skip_new_issue_url - fill_short_form - else - fill_full_form - end - - click_button('Test settings and save changes') - wait_for_requests - - expect(find('.flash-container-page')).to have_content 'Test failed.' - expect(find('.flash-container-page')).to have_content 'Save anyway' - - find('.flash-alert .flash-action').click - wait_for_requests + click_test_then_save_integration expect(page).to have_content("#{tracker} activated.") expect(current_path).to eq(project_settings_integrations_path(project)) @@ -87,13 +57,8 @@ describe 'User activates issue tracker', :js do describe 'user disables the service' do before do - click_link(tracker) - - if skip_new_issue_url - fill_short_form(disabled: true) - else - fill_full_form(disabled: true) - end + visit_project_integration(tracker) + fill_form(disable: true, skip_new_issue_url: skip_new_issue_url) click_button('Save changes') end diff --git a/spec/features/projects/services/user_activates_jira_spec.rb b/spec/features/projects/services/user_activates_jira_spec.rb index fb9628032b2..a14dbf9c14d 100644 --- a/spec/features/projects/services/user_activates_jira_spec.rb +++ b/spec/features/projects/services/user_activates_jira_spec.rb @@ -3,14 +3,13 @@ require 'spec_helper' describe 'User activates Jira', :js do - let(:user) { create(:user) } - let(:project) { create(:project) } + include_context 'project service activation' let(:url) { 'http://jira.example.com' } let(:test_url) { 'http://jira.example.com/rest/api/2/serverInfo' } - def fill_form(disabled: false) - find('input[name="service[active]"] + button').click if disabled + def fill_form(disable: false) + click_active_toggle if disable fill_in 'service_url', with: url fill_in 'service_username', with: 'username' @@ -18,23 +17,15 @@ describe 'User activates Jira', :js do fill_in 'service_jira_issue_transition_id', with: '25' end - before do - project.add_maintainer(user) - sign_in(user) - - visit project_settings_integrations_path(project) - end - describe 'user sets and activates Jira Service' do context 'when Jira connection test succeeds' do before do server_info = { key: 'value' }.to_json - WebMock.stub_request(:get, test_url).with(basic_auth: %w(username password)).to_return(body: server_info) + stub_request(:get, test_url).with(basic_auth: %w(username password)).to_return(body: server_info) - click_link('Jira') + visit_project_integration('Jira') fill_form - click_button('Test settings and save changes') - wait_for_requests + click_test_integration end it 'activates the Jira service' do @@ -51,10 +42,10 @@ describe 'User activates Jira', :js do context 'when Jira connection test fails' do it 'shows errors when some required fields are not filled in' do - click_link('Jira') + visit_project_integration('Jira') fill_in 'service_password', with: 'password' - click_button('Test settings and save changes') + click_test_integration page.within('.service-settings') do expect(page).to have_content('This field is required.') @@ -62,19 +53,12 @@ describe 'User activates Jira', :js do end it 'activates the Jira service' do - WebMock.stub_request(:get, test_url).with(basic_auth: %w(username password)) + stub_request(:get, test_url).with(basic_auth: %w(username password)) .to_raise(JIRA::HTTPError.new(double(message: 'message'))) - click_link('Jira') + visit_project_integration('Jira') fill_form - click_button('Test settings and save changes') - wait_for_requests - - expect(find('.flash-container-page')).to have_content 'Test failed. message' - expect(find('.flash-container-page')).to have_content 'Save anyway' - - find('.flash-alert .flash-action').click - wait_for_requests + click_test_then_save_integration expect(page).to have_content('Jira activated.') expect(current_path).to eq(project_settings_integrations_path(project)) @@ -84,8 +68,8 @@ describe 'User activates Jira', :js do describe 'user disables the Jira Service' do before do - click_link('Jira') - fill_form(disabled: true) + visit_project_integration('Jira') + fill_form(disable: true) click_button('Save changes') end diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb index ac9cb00be84..c6825ee663a 100644 --- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb +++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb @@ -3,158 +3,158 @@ require 'spec_helper' describe 'Set up Mattermost slash commands', :js do - let(:user) { create(:user) } - let(:project) { create(:project) } - let(:mattermost_enabled) { true } - - before do - stub_mattermost_setting(enabled: mattermost_enabled) - project.add_maintainer(user) - sign_in(user) - visit edit_project_service_path(project, :mattermost_slash_commands) - end - describe 'user visits the mattermost slash command config page' do - it 'shows a help message' do - expect(page).to have_content("This service allows users to perform common") + include_context 'project service activation' + + before do + stub_mattermost_setting(enabled: mattermost_enabled) + visit_project_integration('Mattermost slash commands') end - it 'shows a token placeholder' do - token_placeholder = find_field('service_token')['placeholder'] + context 'mattermost service is enabled' do + let(:mattermost_enabled) { true } - expect(token_placeholder).to eq('XXxxXXxxXXxxXXxxXXxxXXxx') - end + it 'shows a help message' do + expect(page).to have_content("This service allows users to perform common") + end - it 'redirects to the integrations page after saving but not activating' do - token = ('a'..'z').to_a.join + it 'shows a token placeholder' do + token_placeholder = find_field('service_token')['placeholder'] - fill_in 'service_token', with: token - find('input[name="service[active]"] + button').click - click_on 'Save changes' + expect(token_placeholder).to eq('XXxxXXxxXXxxXXxxXXxxXXxx') + end - expect(current_path).to eq(project_settings_integrations_path(project)) - expect(page).to have_content('Mattermost slash commands settings saved, but not activated.') - end + it 'redirects to the integrations page after saving but not activating' do + token = ('a'..'z').to_a.join - it 'redirects to the integrations page after activating' do - token = ('a'..'z').to_a.join + fill_in 'service_token', with: token + click_active_toggle + click_on 'Save changes' - fill_in 'service_token', with: token - click_on 'Save changes' + expect(current_path).to eq(project_settings_integrations_path(project)) + expect(page).to have_content('Mattermost slash commands settings saved, but not activated.') + end - expect(current_path).to eq(project_settings_integrations_path(project)) - expect(page).to have_content('Mattermost slash commands activated.') - end + it 'redirects to the integrations page after activating' do + token = ('a'..'z').to_a.join - it 'shows the add to mattermost button' do - expect(page).to have_link('Add to Mattermost') - end + fill_in 'service_token', with: token + click_on 'Save changes' - it 'shows an explanation if user is a member of no teams' do - stub_teams(count: 0) + expect(current_path).to eq(project_settings_integrations_path(project)) + expect(page).to have_content('Mattermost slash commands activated.') + end - click_link 'Add to Mattermost' + it 'shows the add to mattermost button' do + expect(page).to have_link('Add to Mattermost') + end - expect(page).to have_content('You aren’t a member of any team on the Mattermost instance') - expect(page).to have_link('join a team', href: "#{Gitlab.config.mattermost.host}/select_team") - end + it 'shows an explanation if user is a member of no teams' do + stub_teams(count: 0) - it 'shows an explanation if user is a member of 1 team' do - stub_teams(count: 1) + click_link 'Add to Mattermost' - click_link 'Add to Mattermost' + expect(page).to have_content('You aren’t a member of any team on the Mattermost instance') + expect(page).to have_link('join a team', href: "#{Gitlab.config.mattermost.host}/select_team") + end - expect(page).to have_content('The team where the slash commands will be used in') - expect(page).to have_content('This is the only available team that you are a member of.') - end + it 'shows an explanation if user is a member of 1 team' do + stub_teams(count: 1) - it 'shows a disabled prefilled select if user is a member of 1 team' do - teams = stub_teams(count: 1) + click_link 'Add to Mattermost' - click_link 'Add to Mattermost' + expect(page).to have_content('The team where the slash commands will be used in') + expect(page).to have_content('This is the only available team that you are a member of.') + end - team_name = teams.first['display_name'] - select_element = find('#mattermost_team_id') - selected_option = select_element.find('option[selected]') + it 'shows a disabled prefilled select if user is a member of 1 team' do + teams = stub_teams(count: 1) - expect(select_element['disabled']).to eq("true") - expect(selected_option).to have_content(team_name.to_s) - end + click_link 'Add to Mattermost' - it 'has a hidden input for the prefilled value if user is a member of 1 team' do - teams = stub_teams(count: 1) + team_name = teams.first['display_name'] + select_element = find('#mattermost_team_id') + selected_option = select_element.find('option[selected]') - click_link 'Add to Mattermost' + expect(select_element['disabled']).to eq("true") + expect(selected_option).to have_content(team_name.to_s) + end - expect(find('input#mattermost_team_id', visible: false).value).to eq(teams.first['id']) - end + it 'has a hidden input for the prefilled value if user is a member of 1 team' do + teams = stub_teams(count: 1) - it 'shows an explanation user is a member of multiple teams' do - stub_teams(count: 2) + click_link 'Add to Mattermost' - click_link 'Add to Mattermost' + expect(find('input#mattermost_team_id', visible: false).value).to eq(teams.first['id']) + end - expect(page).to have_content('Select the team where the slash commands will be used in') - expect(page).to have_content('The list shows all available teams that you are a member of.') - end + it 'shows an explanation user is a member of multiple teams' do + stub_teams(count: 2) - it 'shows a select with team options user is a member of multiple teams' do - stub_teams(count: 2) + click_link 'Add to Mattermost' - click_link 'Add to Mattermost' + expect(page).to have_content('Select the team where the slash commands will be used in') + expect(page).to have_content('The list shows all available teams that you are a member of.') + end - select_element = find('#mattermost_team_id') + it 'shows a select with team options user is a member of multiple teams' do + stub_teams(count: 2) - expect(select_element['disabled']).to be_falsey - expect(select_element.all('option').count).to eq(3) - end + click_link 'Add to Mattermost' - it 'shows an error alert with the error message if there is an error requesting teams' do - allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [[], 'test mattermost error message'] } + select_element = find('#mattermost_team_id') - click_link 'Add to Mattermost' + expect(select_element['disabled']).to be_falsey + expect(select_element.all('option').count).to eq(3) + end - expect(page).to have_selector('.alert') - expect(page).to have_content('test mattermost error message') - end + it 'shows an error alert with the error message if there is an error requesting teams' do + allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [[], 'test mattermost error message'] } - it 'enables the submit button if the required fields are provided', :js do - stub_teams(count: 1) + click_link 'Add to Mattermost' - click_link 'Add to Mattermost' + expect(page).to have_selector('.alert') + expect(page).to have_content('test mattermost error message') + end - expect(find('input[type="submit"]')['disabled']).not_to eq("true") - end + it 'enables the submit button if the required fields are provided', :js do + stub_teams(count: 1) - it 'disables the submit button if the required fields are not provided', :js do - stub_teams(count: 1) + click_link 'Add to Mattermost' - click_link 'Add to Mattermost' + expect(find('input[type="submit"]')['disabled']).not_to eq("true") + end - fill_in('mattermost_trigger', with: '') + it 'disables the submit button if the required fields are not provided', :js do + stub_teams(count: 1) - expect(find('input[type="submit"]')['disabled']).to eq("true") - end + click_link 'Add to Mattermost' - def stub_teams(count: 0) - teams = create_teams(count) + fill_in('mattermost_trigger', with: '') - allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [teams, nil] } + expect(find('input[type="submit"]')['disabled']).to eq("true") + end - teams - end + def stub_teams(count: 0) + teams = create_teams(count) - def create_teams(count = 0) - teams = [] + allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [teams, nil] } - count.times do |i| - teams.push({ "id" => "x#{i}", "display_name" => "x#{i}-name" }) + teams end - teams + def create_teams(count = 0) + teams = [] + + count.times do |i| + teams.push({ "id" => "x#{i}", "display_name" => "x#{i}-name" }) + end + + teams + end end - describe 'mattermost service is not enabled' do + context 'mattermost service is not enabled' do let(:mattermost_enabled) { false } it 'shows the correct trigger url' 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 4ce1acd9377..05f1a0c6b17 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 @@ -3,13 +3,10 @@ require 'spec_helper' describe 'Slack slash commands' do - let(:user) { create(:user) } - let(:project) { create(:project) } + include_context 'project service activation' before do - project.add_maintainer(user) - sign_in(user) - visit edit_project_service_path(project, :slack_slash_commands) + visit_project_integration('Slack slash commands') end it 'shows a token placeholder' do @@ -24,7 +21,7 @@ describe 'Slack slash commands' do it 'redirects to the integrations page after saving but not activating', :js do fill_in 'service_token', with: 'token' - find('input[name="service[active]"] + button').click + click_active_toggle click_on 'Save' expect(current_path).to eq(project_settings_integrations_path(project)) diff --git a/spec/features/projects/services/user_activates_youtrack_spec.rb b/spec/features/projects/services/user_activates_youtrack_spec.rb deleted file mode 100644 index 26734766ff0..00000000000 --- a/spec/features/projects/services/user_activates_youtrack_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe 'User activates issue tracker', :js do - let(:user) { create(:user) } - let(:project) { create(:project) } - - let(:url) { 'http://tracker.example.com' } - - def fill_form(disabled: false) - find('input[name="service[active]"] + button').click if disabled - - fill_in 'service_project_url', with: url - fill_in 'service_issues_url', with: "#{url}/:id" - end - - before do - project.add_maintainer(user) - sign_in(user) - - visit project_settings_integrations_path(project) - end - - shared_examples 'external issue tracker activation' do |tracker:| - describe 'user sets and activates the Service' do - context 'when the connection test succeeds' do - before do - stub_request(:head, url).to_return(headers: { 'Content-Type' => 'application/json' }) - - click_link(tracker) - fill_form - click_button('Test settings and save changes') - wait_for_requests - end - - it 'activates the service' do - expect(page).to have_content("#{tracker} activated.") - expect(current_path).to eq(project_settings_integrations_path(project)) - end - - it 'shows the link in the menu' do - page.within('.nav-sidebar') do - expect(page).to have_link(tracker, href: url) - end - end - end - - context 'when the connection test fails' do - it 'activates the service' do - stub_request(:head, url).to_raise(Gitlab::HTTP::Error) - - click_link(tracker) - fill_form - click_button('Test settings and save changes') - wait_for_requests - - expect(find('.flash-container-page')).to have_content 'Test failed.' - expect(find('.flash-container-page')).to have_content 'Save anyway' - - find('.flash-alert .flash-action').click - wait_for_requests - - expect(page).to have_content("#{tracker} activated.") - expect(current_path).to eq(project_settings_integrations_path(project)) - end - end - end - - describe 'user disables the service' do - before do - click_link(tracker) - fill_form(disabled: true) - click_button('Save changes') - end - - it 'saves but does not activate the service' do - expect(page).to have_content("#{tracker} settings saved, but not activated.") - expect(current_path).to eq(project_settings_integrations_path(project)) - end - - it 'does not show the external tracker link in the menu' do - page.within('.nav-sidebar') do - expect(page).not_to have_link(tracker, href: url) - end - end - end - end - - it_behaves_like 'external issue tracker activation', tracker: 'YouTrack' -end diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb new file mode 100644 index 00000000000..9a8a8e38164 --- /dev/null +++ b/spec/features/projects/settings/access_tokens_spec.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Project > Settings > Access Tokens', :js do + let_it_be(:user) { create(:user) } + let_it_be(:bot_user) { create(:user, :project_bot) } + let_it_be(:project) { create(:project) } + + before_all do + project.add_maintainer(user) + end + + before do + sign_in(user) + end + + def create_project_access_token + project.add_maintainer(bot_user) + + create(:personal_access_token, user: bot_user) + end + + def active_project_access_tokens + find('.table.active-tokens') + end + + def no_project_access_tokens_message + find('.settings-message') + end + + def created_project_access_token + find('#created-personal-access-token').value + end + + describe 'token creation' do + it 'allows creation of a project access token' do + name = 'My project access token' + + visit project_settings_access_tokens_path(project) + fill_in 'Name', with: name + + # Set date to 1st of next month + find_field('Expires at').click + find('.pika-next').click + click_on '1' + + # Scopes + check 'api' + check 'read_api' + + 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('api') + expect(active_project_access_tokens).to have_text('read_api') + expect(created_project_access_token).not_to be_empty + end + end + + describe 'active tokens' do + let!(:project_access_token) { create_project_access_token } + + it 'shows active project access tokens' do + visit project_settings_access_tokens_path(project) + + expect(active_project_access_tokens).to have_text(project_access_token.name) + end + end + + describe 'inactive tokens' do + let!(:project_access_token) { create_project_access_token } + + no_active_tokens_text = 'This project has no active access tokens.' + + it 'allows revocation of an active token' do + visit project_settings_access_tokens_path(project) + accept_confirm { click_on 'Revoke' } + + expect(page).to have_selector('.settings-message') + expect(no_project_access_tokens_message).to have_text(no_active_tokens_text) + end + + it 'removes expired tokens from active section' do + project_access_token.update(expires_at: 5.days.ago) + visit project_settings_access_tokens_path(project) + + expect(page).to have_selector('.settings-message') + expect(no_project_access_tokens_message).to have_text(no_active_tokens_text) + end + end +end diff --git a/spec/features/projects/settings/operations_settings_spec.rb b/spec/features/projects/settings/operations_settings_spec.rb index 3c9102431e8..752353cf2f5 100644 --- a/spec/features/projects/settings/operations_settings_spec.rb +++ b/spec/features/projects/settings/operations_settings_spec.rb @@ -76,7 +76,7 @@ describe 'Projects > Settings > For a forked project', :js do context 'success path' do let(:projects_sample_response) do Gitlab::Utils.deep_indifferent_access( - JSON.parse(fixture_file('sentry/list_projects_sample_response.json')) + Gitlab::Json.parse(fixture_file('sentry/list_projects_sample_response.json')) ) end diff --git a/spec/features/projects/settings/project_settings_spec.rb b/spec/features/projects/settings/project_settings_spec.rb index 9fc91550667..171c7920878 100644 --- a/spec/features/projects/settings/project_settings_spec.rb +++ b/spec/features/projects/settings/project_settings_spec.rb @@ -54,6 +54,36 @@ describe 'Projects settings' do end end + context 'default award emojis', :js do + it 'shows award emojis by default' do + visit edit_project_path(project) + + default_award_emojis_input = find('input[name="project[project_setting_attributes][show_default_award_emojis]"]', visible: :hidden) + + expect(default_award_emojis_input.value).to eq('true') + end + + it 'disables award emojis when the checkbox is toggled off' do + visit edit_project_path(project) + + default_award_emojis_input = find('input[name="project[project_setting_attributes][show_default_award_emojis]"]', visible: :hidden) + default_award_emojis_checkbox = find('input[name="project[project_setting_attributes][show_default_award_emojis]"][type=checkbox]') + + expect(default_award_emojis_input.value).to eq('true') + + default_award_emojis_checkbox.click + + expect(default_award_emojis_input.value).to eq('false') + + page.within('.sharing-permissions') do + find('input[value="Save changes"]').click + end + wait_for_requests + + expect(default_award_emojis_input.value).to eq('false') + end + end + def expect_toggle_state(state) is_collapsed = state == :collapsed diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb index 74d3544ce92..ba92e8bc516 100644 --- a/spec/features/projects/settings/registry_settings_spec.rb +++ b/spec/features/projects/settings/registry_settings_spec.rb @@ -29,7 +29,7 @@ describe 'Project > Settings > CI/CD > Container registry tag expiration policy' select('7 days until tags are automatically removed', from: 'Expiration interval:') select('Every day', from: 'Expiration schedule:') select('50 tags per image name', from: 'Number of tags to retain:') - fill_in('Docker tags with names matching this regex pattern will expire:', with: '*-production') + fill_in('Tags with names matching this regex pattern will expire:', with: '*-production') end submit_button = find('.card-footer .btn.btn-success') expect(submit_button).not_to be_disabled diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index 2fb6c71384f..b8baaa3e963 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -30,7 +30,7 @@ describe 'Projects > Settings > Repository settings' do before do stub_container_registry_config(enabled: true) - stub_feature_flags(ajax_new_deploy_token: { enabled: false, thing: project }) + stub_feature_flags(ajax_new_deploy_token: project) visit project_settings_repository_path(project) end @@ -222,20 +222,6 @@ describe 'Projects > Settings > Repository settings' do end end - # Removal: https://gitlab.com/gitlab-org/gitlab/-/issues/208828 - context 'with the `keep_divergent_refs` feature flag disabled' do - before do - stub_feature_flags(keep_divergent_refs: { enabled: false, thing: project }) - end - - it 'hides the "Keep divergent refs" option' do - visit project_settings_repository_path(project) - - expect(page).not_to have_selector('#keep_divergent_refs') - expect(page).not_to have_text('Keep divergent refs') - end - end - context 'repository cleanup settings' do let(:object_map_file) { Rails.root.join('spec', 'fixtures', 'bfg_object_map.txt') } diff --git a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb index cd9299150b2..45a16fda2cb 100644 --- a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb +++ b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb @@ -88,18 +88,18 @@ describe "User interacts with deploy keys", :js do end it "adds new key" do - DEPLOY_KEY_TITLE = attributes_for(:key)[:title] - DEPLOY_KEY_BODY = attributes_for(:key)[:key] + deploy_key_title = attributes_for(:key)[:title] + deploy_key_body = attributes_for(:key)[:key] - fill_in("deploy_key_title", with: DEPLOY_KEY_TITLE) - fill_in("deploy_key_key", with: DEPLOY_KEY_BODY) + fill_in("deploy_key_title", with: deploy_key_title) + fill_in("deploy_key_key", with: deploy_key_body) click_button("Add key") expect(current_path).to eq(project_settings_repository_path(project)) page.within(".deploy-keys") do - expect(page).to have_content(DEPLOY_KEY_TITLE) + expect(page).to have_content(deploy_key_title) end end end diff --git a/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb b/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb index a77240c5c33..0abc4b41a2b 100644 --- a/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb +++ b/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb @@ -11,7 +11,7 @@ describe 'Repository Settings > User sees revoke deploy token modal', :js do before do project.add_role(user, role) sign_in(user) - stub_feature_flags(ajax_new_deploy_token: { enabled: false, thing: project }) + stub_feature_flags(ajax_new_deploy_token: project) visit(project_settings_repository_path(project)) click_link('Revoke') end diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb index d883a1fc39c..1e8f9fa0875 100644 --- a/spec/features/projects/snippets/create_snippet_spec.rb +++ b/spec/features/projects/snippets/create_snippet_spec.rb @@ -5,7 +5,6 @@ require 'spec_helper' shared_examples_for 'snippet editor' do before do stub_feature_flags(snippets_edit_vue: false) - stub_feature_flags(monaco_snippets: flag) end def description_field @@ -20,7 +19,7 @@ shared_examples_for 'snippet editor' do fill_in 'project_snippet_description', with: 'My Snippet **Description**' page.within('.file-editor') do - el = flag == true ? find('.inputarea') : find('.ace_text-input', visible: false) + el = find('.inputarea') el.send_keys 'Hello World!' end end @@ -100,7 +99,7 @@ shared_examples_for 'snippet editor' do end context 'when the git operation fails' do - let(:error) { 'This is a git error' } + let(:error) { 'Error creating the snippet' } before do allow_next_instance_of(Snippets::CreateService) do |instance| @@ -145,15 +144,5 @@ describe 'Projects > Snippets > Create Snippet', :js do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :public) } - context 'when using Monaco' do - it_behaves_like "snippet editor" do - let(:flag) { true } - end - end - - context 'when using ACE' do - it_behaves_like "snippet editor" do - let(:flag) { false } - end - end + it_behaves_like "snippet editor" end diff --git a/spec/features/projects/snippets/user_updates_snippet_spec.rb b/spec/features/projects/snippets/user_updates_snippet_spec.rb index cf501e55e23..d19fe9e8d38 100644 --- a/spec/features/projects/snippets/user_updates_snippet_spec.rb +++ b/spec/features/projects/snippets/user_updates_snippet_spec.rb @@ -7,12 +7,9 @@ describe 'Projects > Snippets > User updates a snippet', :js do let_it_be(:project) { create(:project, namespace: user.namespace) } let_it_be(:snippet, reload: true) { create(:project_snippet, :repository, project: project, author: user) } - let(:version_snippet_enabled) { true } - before do stub_feature_flags(snippets_vue: false) stub_feature_flags(snippets_edit_vue: false) - stub_feature_flags(version_snippets: version_snippet_enabled) project.add_maintainer(user) sign_in(user) @@ -35,18 +32,6 @@ describe 'Projects > Snippets > User updates a snippet', :js do end end - context 'when feature flag :version_snippets is disabled' do - let(:version_snippet_enabled) { false } - - it 'displays the snippet file_name and content' do - aggregate_failures do - expect(page.find_field('project_snippet_file_name').value).to eq snippet.file_name - expect(page.find('.file-content')).to have_content(snippet.content) - expect(page.find('.snippet-file-content', visible: false).value).to eq snippet.content - end - end - end - it 'updates a snippet' do fill_in('project_snippet_title', with: 'Snippet new title') click_button('Save') @@ -57,16 +42,17 @@ describe 'Projects > Snippets > User updates a snippet', :js do context 'when the git operation fails' do before do allow_next_instance_of(Snippets::UpdateService) do |instance| - allow(instance).to receive(:create_commit).and_raise(StandardError) + allow(instance).to receive(:create_commit).and_raise(StandardError, 'Error Message') end fill_in('project_snippet_title', with: 'Snippet new title') + fill_in('project_snippet_file_name', with: 'new_file_name') click_button('Save') end it 'renders edit page and displays the error' do - expect(page.find('.flash-container span').text).to eq('Error updating the snippet') + expect(page.find('.flash-container span').text).to eq('Error updating the snippet - Error Message') expect(page).to have_content('Edit Snippet') end end diff --git a/spec/features/projects/user_sees_user_popover_spec.rb b/spec/features/projects/user_sees_user_popover_spec.rb index fafb3773866..6197460776d 100644 --- a/spec/features/projects/user_sees_user_popover_spec.rb +++ b/spec/features/projects/user_sees_user_popover_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe 'User sees user popover', :js do + include Spec::Support::Helpers::Features::NotesHelpers + let_it_be(:project) { create(:project, :repository) } let(:user) { project.creator } let(:merge_request) do @@ -17,13 +19,13 @@ describe 'User sees user popover', :js do subject { page } describe 'hovering over a user link in a merge request' do + let(:popover_selector) { '.user-popover' } + before do visit project_merge_request_path(project, merge_request) end it 'displays user popover' do - popover_selector = '.user-popover' - find('.js-user-link').hover expect(page).to have_css(popover_selector, visible: true) @@ -32,5 +34,17 @@ describe 'User sees user popover', :js do expect(page).to have_content(user.name) end end + + it "displays user popover in system note" do + add_note("/assign @#{user.username}") + + wait_for_requests + + find('.system-note-message .js-user-link').hover + + page.within(popover_selector) do + expect(page).to have_content(user.name) + end + end end end diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb index 7d18c0f7a14..bc567d4db42 100644 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ b/spec/features/projects/wiki/markdown_preview_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' describe 'Projects > Wiki > User previews markdown changes', :js do let_it_be(:user) { create(:user) } let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - let(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: { title: 'home', content: '[some link](other-page)' }) } + let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') } let(:wiki_content) do <<-HEREDOC [regular link](regular) diff --git a/spec/features/projects/wiki/shortcuts_spec.rb b/spec/features/projects/wiki/shortcuts_spec.rb index 806d2f28bb9..c51af2526c9 100644 --- a/spec/features/projects/wiki/shortcuts_spec.rb +++ b/spec/features/projects/wiki/shortcuts_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' describe 'Wiki shortcuts', :js do let(:user) { create(:user) } let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - let(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: { title: 'home', content: 'Home page' }) } + let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: 'Home page') } before do sign_in(user) diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index 67996cc3e5d..5678ebcb72a 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -195,7 +195,7 @@ describe "User creates wiki page" do context "when wiki is not empty", :js do before do - create(:wiki_page, wiki: wiki, attrs: { title: 'home', content: 'Home page' }) + create(:wiki_page, wiki: wiki, title: 'home', content: 'Home page') visit(project_wikis_path(project)) end @@ -304,19 +304,20 @@ describe "User creates wiki page" do describe 'sidebar feature' do context 'when there are some existing pages' do before do - create(:wiki_page, wiki: wiki, attrs: { title: 'home', content: 'home' }) - create(:wiki_page, wiki: wiki, attrs: { title: 'another', content: 'another' }) + create(:wiki_page, wiki: wiki, title: 'home', content: 'home') + create(:wiki_page, wiki: wiki, title: 'another', content: 'another') end it 'renders a default sidebar when there is no customized sidebar' do visit(project_wikis_path(project)) expect(page).to have_content('another') + expect(page).not_to have_link('View All Pages') end context 'when there is a customized sidebar' do before do - create(:wiki_page, wiki: wiki, attrs: { title: '_sidebar', content: 'My customized sidebar' }) + create(:wiki_page, wiki: wiki, title: '_sidebar', content: 'My customized sidebar') end it 'renders my customized sidebar instead of the default one' do @@ -328,17 +329,31 @@ describe "User creates wiki page" do end end - context 'when there are more than 15 existing pages' do + context 'when there are 15 existing pages' do before do - create(:wiki_page, wiki: wiki, attrs: { title: 'home', content: 'home' }) - (1..14).each { |i| create(:wiki_page, wiki: wiki, attrs: { title: "page-#{i}", content: "page #{i}" }) } + (1..5).each { |i| create(:wiki_page, wiki: wiki, title: "my page #{i}") } + (6..10).each { |i| create(:wiki_page, wiki: wiki, title: "parent/my page #{i}") } + (11..15).each { |i| create(:wiki_page, wiki: wiki, title: "grandparent/parent/my page #{i}") } end - it 'renders a default sidebar when there is no customized sidebar' do + it 'shows all pages in the sidebar' do visit(project_wikis_path(project)) - expect(page).to have_content('View All Pages') - expect(page).to have_content('page 1') + (1..15).each { |i| expect(page).to have_content("my page #{i}") } + expect(page).not_to have_link('View All Pages') + end + + context 'when there are more than 15 existing pages' do + before do + create(:wiki_page, wiki: wiki, title: 'my page 16') + end + + it 'shows the first 15 pages in the sidebar' do + visit(project_wikis_path(project)) + + expect(page).to have_text('my page', count: 15) + expect(page).to have_link('View All Pages') + end end end end diff --git a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb index ab3d912dd15..6c6af1c41d2 100644 --- a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' describe 'Projects > Wiki > User views Git access wiki page' do let(:user) { create(:user) } let(:project) { create(:project, :wiki_repo, :public) } - let(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: { title: 'home', content: '[some link](other-page)' }) } + let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') } before do sign_in(user) diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb index 9d9c83331fb..55509ddfa10 100644 --- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb @@ -64,7 +64,7 @@ describe 'User updates wiki page' do context 'when wiki is not empty' do let(:project_wiki) { create(:project_wiki, project: project, user: project.creator) } - let!(:wiki_page) { create(:wiki_page, wiki: project_wiki, attrs: { title: 'home', content: 'Home page' }) } + let!(:wiki_page) { create(:wiki_page, wiki: project_wiki, title: 'home', content: 'Home page') } before do visit(project_wikis_path(project)) @@ -168,7 +168,7 @@ describe 'User updates wiki page' do let(:project_wiki) { create(:project_wiki, project: project, user: project.creator) } let(:page_name) { 'page_name' } let(:page_dir) { "foo/bar/#{page_name}" } - let!(:wiki_page) { create(:wiki_page, wiki: project_wiki, attrs: { title: page_dir, content: 'Home page' }) } + let!(:wiki_page) { create(:wiki_page, wiki: project_wiki, title: page_dir, content: 'Home page') } before do visit(project_wiki_edit_path(project, wiki_page)) diff --git a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb index 471e80b27dc..cb425e8b704 100644 --- a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb @@ -21,7 +21,7 @@ describe 'Projects > Wiki > User views wiki in project page' do context 'when wiki homepage contains a link' do before do - create(:wiki_page, wiki: project.wiki, attrs: { title: 'home', content: '[some link](other-page)' }) + create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') end it 'displays the correct URL for the link' do diff --git a/spec/features/projects/wiki/user_views_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_page_spec.rb index 8a338756323..e379e7466db 100644 --- a/spec/features/projects/wiki/user_views_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_page_spec.rb @@ -11,7 +11,7 @@ describe 'User views a wiki page' do let(:wiki_page) do create(:wiki_page, wiki: project.wiki, - attrs: { title: 'home', content: "Look at this [image](#{path})\n\n ![alt text](#{path})" }) + title: 'home', content: "Look at this [image](#{path})\n\n ![alt text](#{path})") end before do diff --git a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb b/spec/features/projects/wiki/user_views_wiki_pages_spec.rb index 6740df1d4ed..584b2a76143 100644 --- a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_pages_spec.rb @@ -9,13 +9,13 @@ describe 'User views wiki pages' do let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } let!(:wiki_page1) do - create(:wiki_page, wiki: project.wiki, attrs: { title: '3 home', content: '3' }) + create(:wiki_page, wiki: project.wiki, title: '3 home', content: '3') end let!(:wiki_page2) do - create(:wiki_page, wiki: project.wiki, attrs: { title: '1 home', content: '1' }) + create(:wiki_page, wiki: project.wiki, title: '1 home', content: '1') end let!(:wiki_page3) do - create(:wiki_page, wiki: project.wiki, attrs: { title: '2 home', content: '2' }) + create(:wiki_page, wiki: project.wiki, title: '2 home', content: '2') end let(:pages) do diff --git a/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb b/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb index 08eea14c438..014b63fa154 100644 --- a/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb +++ b/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb @@ -16,7 +16,7 @@ describe 'User views AsciiDoc page with includes', :js do format: :asciidoc } - create(:wiki_page, wiki: project.wiki, attrs: attrs) + create(:wiki_page, wiki: project.wiki, **attrs) end before do |