diff options
32 files changed, 381 insertions, 2317 deletions
diff --git a/spec/features/issues/user_uses_quick_actions_spec.rb b/spec/features/issues/user_uses_quick_actions_spec.rb index 86b15b1d980..8fec92031a9 100644 --- a/spec/features/issues/user_uses_quick_actions_spec.rb +++ b/spec/features/issues/user_uses_quick_actions_spec.rb @@ -2,6 +2,11 @@ require 'rails_helper' +# These are written as feature specs because they cover more specific test scenarios +# than the ones described on spec/services/notes/create_service_spec.rb for quick actions, +# for example, adding quick actions when creating the issue and checking DateTime formats on UI. +# Because this kind of spec takes more time to run there is no need to add new ones +# for each existing quick action unless they test something not tested by existing tests. describe 'Issues > User uses quick actions', :js do include Spec::Support::Helpers::Features::NotesHelpers @@ -15,30 +20,7 @@ describe 'Issues > User uses quick actions', :js do let(:issuable) { create(:issue, project: project) } let(:source_issuable) { create(:issue, project: project, milestone: milestone, labels: [label_bug, label_feature])} - it_behaves_like 'assign quick action', :issue - it_behaves_like 'unassign quick action', :issue it_behaves_like 'close quick action', :issue - it_behaves_like 'reopen quick action', :issue - it_behaves_like 'title quick action', :issue - it_behaves_like 'todo quick action', :issue - it_behaves_like 'done quick action', :issue - it_behaves_like 'subscribe quick action', :issue - it_behaves_like 'unsubscribe quick action', :issue - it_behaves_like 'lock quick action', :issue - it_behaves_like 'unlock quick action', :issue - it_behaves_like 'milestone quick action', :issue - it_behaves_like 'remove_milestone quick action', :issue - it_behaves_like 'label quick action', :issue - it_behaves_like 'unlabel quick action', :issue - it_behaves_like 'relabel quick action', :issue - it_behaves_like 'award quick action', :issue - it_behaves_like 'estimate quick action', :issue - it_behaves_like 'remove_estimate quick action', :issue - it_behaves_like 'spend quick action', :issue - it_behaves_like 'remove_time_spent quick action', :issue - it_behaves_like 'shrug quick action', :issue - it_behaves_like 'tableflip quick action', :issue - it_behaves_like 'copy_metadata quick action', :issue it_behaves_like 'issuable time tracker', :issue end @@ -58,11 +40,7 @@ describe 'Issues > User uses quick actions', :js do wait_for_requests end - it_behaves_like 'confidential quick action' - it_behaves_like 'remove_due_date quick action' - it_behaves_like 'duplicate quick action' it_behaves_like 'create_merge_request quick action' - it_behaves_like 'due quick action' it_behaves_like 'move quick action' end end diff --git a/spec/features/merge_request/user_uses_quick_actions_spec.rb b/spec/features/merge_request/user_uses_quick_actions_spec.rb index 988a8302527..3948c0c5c89 100644 --- a/spec/features/merge_request/user_uses_quick_actions_spec.rb +++ b/spec/features/merge_request/user_uses_quick_actions_spec.rb @@ -2,6 +2,11 @@ require 'rails_helper' +# These are written as feature specs because they cover more specific test scenarios +# than the ones described on spec/services/notes/create_service_spec.rb for quick actions, +# for example, adding quick actions when creating the issue and checking DateTime formats on UI. +# Because this kind of spec takes more time to run there is no need to add new ones +# for each existing quick action unless they test something not tested by existing tests. describe 'Merge request > User uses quick actions', :js do include Spec::Support::Helpers::Features::NotesHelpers @@ -21,30 +26,7 @@ describe 'Merge request > User uses quick actions', :js do let(:issuable) { create(:merge_request, source_project: project) } let(:source_issuable) { create(:issue, project: project, milestone: milestone, labels: [label_bug, label_feature])} - it_behaves_like 'assign quick action', :merge_request - it_behaves_like 'unassign quick action', :merge_request it_behaves_like 'close quick action', :merge_request - it_behaves_like 'reopen quick action', :merge_request - it_behaves_like 'title quick action', :merge_request - it_behaves_like 'todo quick action', :merge_request - it_behaves_like 'done quick action', :merge_request - it_behaves_like 'subscribe quick action', :merge_request - it_behaves_like 'unsubscribe quick action', :merge_request - it_behaves_like 'lock quick action', :merge_request - it_behaves_like 'unlock quick action', :merge_request - it_behaves_like 'milestone quick action', :merge_request - it_behaves_like 'remove_milestone quick action', :merge_request - it_behaves_like 'label quick action', :merge_request - it_behaves_like 'unlabel quick action', :merge_request - it_behaves_like 'relabel quick action', :merge_request - it_behaves_like 'award quick action', :merge_request - it_behaves_like 'estimate quick action', :merge_request - it_behaves_like 'remove_estimate quick action', :merge_request - it_behaves_like 'spend quick action', :merge_request - it_behaves_like 'remove_time_spent quick action', :merge_request - it_behaves_like 'shrug quick action', :merge_request - it_behaves_like 'tableflip quick action', :merge_request - it_behaves_like 'copy_metadata quick action', :merge_request it_behaves_like 'issuable time tracker', :merge_request end @@ -59,7 +41,5 @@ describe 'Merge request > User uses quick actions', :js do end it_behaves_like 'merge quick action' - it_behaves_like 'target_branch quick action' - it_behaves_like 'wip quick action' end end diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb index 494ca95f66d..46abd8f356a 100644 --- a/spec/services/notes/create_service_spec.rb +++ b/spec/services/notes/create_service_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' describe Notes::CreateService do - let(:project) { create(:project) } - let(:issue) { create(:issue, project: project) } - let(:user) { create(:user) } + set(:project) { create(:project, :repository) } + set(:issue) { create(:issue, project: project) } + set(:user) { create(:user) } let(:opts) do { note: 'Awesome comment', noteable_type: 'Issue', noteable_id: issue.id } end @@ -197,64 +197,113 @@ describe Notes::CreateService do end context 'note with commands' do - context 'as a user who can update the target' do - context '/close, /label, /assign & /milestone' do - let(:note_text) { %(HELLO\n/close\n/assign @#{user.username}\nWORLD) } - - it 'saves the note and does not alter the note text' do - service = double(:service) - allow(Issues::UpdateService).to receive(:new).and_return(service) - expect(service).to receive(:execute) - - note = described_class.new(project, user, opts.merge(note: note_text)).execute - - expect(note.note).to eq "HELLO\nWORLD" + context 'all quick actions' do + set(:milestone) { create(:milestone, project: project, title: "sprint") } + set(:bug_label) { create(:label, project: project, title: 'bug') } + set(:to_be_copied_label) { create(:label, project: project, title: 'to be copied') } + set(:feature_label) { create(:label, project: project, title: 'feature') } + set(:issue) { create(:issue, project: project, labels: [bug_label], due_date: '2019-01-01') } + set(:issue_2) { create(:issue, project: project, labels: [bug_label, to_be_copied_label]) } + + context 'for issues' do + let(:issuable) { issue } + let(:note_params) { opts } + let(:issue_quick_actions) do + [ + QuickAction.new( + action_text: '/confidential', + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable).to be_confidential + else + expect(noteable).not_to be_confidential + end + } + ), + QuickAction.new( + action_text: '/due 2016-08-28', + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.due_date == Date.new(2016, 8, 28)).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: '/remove_due_date', + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable.due_date).to be_nil + else + expect(noteable.due_date).not_to be_nil + end + } + ), + QuickAction.new( + action_text: "/duplicate #{issue_2.to_reference}", + before_action: -> { + issuable.reopen + }, + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.closed?).to eq(can_use_quick_action) + } + ) + ] end - end - context '/merge with sha option' do - let(:note_text) { %(HELLO\n/merge\nWORLD) } - let(:params) { opts.merge(note: note_text, merge_request_diff_head_sha: 'sha') } - - it 'saves the note and exectues merge command' do - note = described_class.new(project, user, params).execute - - expect(note.note).to eq "HELLO\nWORLD" + it_behaves_like 'issuable quick actions' do + let(:quick_actions) { issuable_quick_actions + issue_quick_actions } end end - context 'when note only have commands' do - it 'adds commands applied message to note errors' do - note_text = %(/close) - service = double(:service) - allow(Issues::UpdateService).to receive(:new).and_return(service) - expect(service).to receive(:execute) - - note = described_class.new(project, user, opts.merge(note: note_text)).execute + context 'for merge requests' do + set(:merge_request) { create(:merge_request, source_project: project, labels: [bug_label]) } + let(:issuable) { merge_request } + let(:note_params) { opts.merge(noteable_type: 'MergeRequest', noteable_id: merge_request.id) } + let(:merge_request_quick_actions) do + [ + QuickAction.new( + action_text: "/target_branch fix", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.target_branch == "fix").to eq(can_use_quick_action) + } + ), + # Set WIP status + QuickAction.new( + action_text: "/wip", + before_action: -> { + issuable.reload.update(title: "title") + }, + expectation: ->(issuable, can_use_quick_action) { + expect(issuable.work_in_progress?).to eq(can_use_quick_action) + } + ), + # Remove WIP status + QuickAction.new( + action_text: "/wip", + before_action: -> { + issuable.reload.update(title: "WIP: title") + }, + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.work_in_progress?).not_to eq(can_use_quick_action) + } + ) + ] + end - expect(note.errors[:commands_only]).to be_present + it_behaves_like 'issuable quick actions' do + let(:quick_actions) { issuable_quick_actions + merge_request_quick_actions } end end end - context 'as a user who cannot update the target' do - let(:note_text) { "HELLO\n/todo\n/assign #{user.to_reference}\nWORLD" } - let(:note) { described_class.new(project, user, opts.merge(note: note_text)).execute } - - before do - project.team.find_member(user.id).update!(access_level: Gitlab::Access::GUEST) - end - - it 'applies commands the user can execute' do - expect { note }.to change { user.todos_pending_count }.from(0).to(1) - end + context 'when note only have commands' do + it 'adds commands applied message to note errors' do + note_text = %(/close) + service = double(:service) + allow(Issues::UpdateService).to receive(:new).and_return(service) + expect(service).to receive(:execute) - it 'does not apply commands the user cannot execute' do - expect { note }.not_to change { issue.assignees } - end + note = described_class.new(project, user, opts.merge(note: note_text)).execute - it 'saves the note' do - expect(note.note).to eq "HELLO\nWORLD" + expect(note.errors[:commands_only]).to be_present end end end diff --git a/spec/support/shared_examples/quick_actions/issuable/assign_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/assign_quick_action_shared_examples.rb deleted file mode 100644 index d97da6be192..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/assign_quick_action_shared_examples.rb +++ /dev/null @@ -1,110 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'assign quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets assign quick action accordingly" do - assignee = create(:user, username: 'bob') - - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/assign @bob" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable.assignees).to eq [assignee] - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - end - - it "creates the #{issuable_type} and interprets assign quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/assign me" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable.assignees).to eq [maintainer] - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the assign quick action accordingly' do - assignee = create(:user, username: 'bob') - add_note("Awesome!\n\n/assign @bob") - - expect(page).to have_content 'Awesome!' - expect(page).not_to have_content '/assign @bob' - - wait_for_requests - issuable.reload - note = issuable.notes.user.first - - expect(note.note).to eq 'Awesome!' - expect(issuable.assignees).to eq [assignee] - end - - it "assigns the #{issuable_type} to the current user" do - add_note("/assign me") - - expect(page).not_to have_content '/assign me' - expect(page).to have_content 'Commands applied' - - expect(issuable.reload.assignees).to eq [maintainer] - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains assign quick action to bob' do - create(:user, username: 'bob') - - visit public_send("project_#{issuable_type}_path", project, issuable) - - page.within('.js-main-target-form') do - fill_in 'note[note]', with: "Awesome!\n/assign @bob " - click_on 'Preview' - - expect(page).not_to have_content '/assign @bob' - expect(page).to have_content 'Awesome!' - expect(page).to have_content 'Assigns @bob.' - end - end - - it 'explains assign quick action to me' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - page.within('.js-main-target-form') do - fill_in 'note[note]', with: "Awesome!\n/assign me" - click_on 'Preview' - - expect(page).not_to have_content '/assign me' - expect(page).to have_content 'Awesome!' - expect(page).to have_content "Assigns @#{maintainer.username}." - end - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/award_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/award_quick_action_shared_examples.rb deleted file mode 100644 index 74cbfa3f4b4..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/award_quick_action_shared_examples.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'award quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets award quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/award :100:" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.award_emoji).to eq [] - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - expect(issuable.award_emoji).to eq [] - end - - it 'creates the note and interprets the award quick action accordingly' do - add_note("/award :100:") - - wait_for_requests - expect(page).not_to have_content '/award' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.award_emoji.last.name).to eq('100') - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains label quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/award :100:') - - expect(page).not_to have_content '/award' - expect(page).to have_selector "gl-emoji[data-name='100']" - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/copy_metadata_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/copy_metadata_quick_action_shared_examples.rb deleted file mode 100644 index 1e1e3c7bc95..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/copy_metadata_quick_action_shared_examples.rb +++ /dev/null @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'copy_metadata quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets copy_metadata quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/copy_metadata #{source_issuable.to_reference(project)}" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).last - - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - issuable.reload - expect(issuable.description).to eq 'bug description' - expect(issuable.milestone).to eq milestone - expect(issuable.labels).to match_array([label_bug, label_feature]) - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets copy_metadata quick action accordingly' do - add_note("/copy_metadata #{source_issuable.to_reference(project)}") - - wait_for_requests - expect(page).not_to have_content '/copy_metadata' - expect(page).to have_content 'Commands applied' - issuable.reload - expect(issuable.milestone).to eq milestone - expect(issuable.labels).to match_array([label_bug, label_feature]) - end - - context "when current user cannot copy_metadata" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not copy_metadata' do - add_note("/copy_metadata #{source_issuable.to_reference(project)}") - - wait_for_requests - expect(page).not_to have_content '/copy_metadata' - expect(page).not_to have_content 'Commands applied' - issuable.reload - expect(issuable.milestone).not_to eq milestone - expect(issuable.labels).to eq [] - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains copy_metadata quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note("/copy_metadata #{source_issuable.to_reference(project)}") - - expect(page).not_to have_content '/copy_metadata' - expect(page).to have_content "Copy labels and milestone from #{source_issuable.to_reference(project)}." - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/done_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/done_quick_action_shared_examples.rb deleted file mode 100644 index 8a72bbc13bf..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/done_quick_action_shared_examples.rb +++ /dev/null @@ -1,103 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'done quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets done quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/done" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - - todos = TodosFinder.new(maintainer).execute - expect(todos.size).to eq 0 - end - end - - context "post note to existing #{issuable_type}" do - before do - TodoService.new.mark_todo(issuable, maintainer) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the done quick action accordingly' do - todos = TodosFinder.new(maintainer).execute - todo = todos.first - expect(todo.reload).to be_pending - - expect(todos.size).to eq 1 - expect(todo.target).to eq issuable - expect(todo.author).to eq maintainer - expect(todo.user).to eq maintainer - - add_note('/done') - - wait_for_requests - expect(page).not_to have_content '/done' - expect(page).to have_content 'Commands applied' - expect(todo.reload).to be_done - end - - context "when current user cannot mark #{issuable_type} todo as done" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it "does not set the #{issuable_type} todo as done" do - todos = TodosFinder.new(maintainer).execute - todo = todos.first - expect(todo.reload).to be_pending - - expect(todos.size).to eq 1 - expect(todo.target).to eq issuable - expect(todo.author).to eq maintainer - expect(todo.user).to eq maintainer - - add_note('/done') - - expect(page).not_to have_content 'Commands applied' - expect(todo.reload).to be_pending - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains done quick action' do - TodoService.new.mark_todo(issuable, maintainer) - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/done') - - expect(page).not_to have_content '/done' - expect(page).to have_content "Marks todo as done." - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/estimate_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/estimate_quick_action_shared_examples.rb deleted file mode 100644 index 648755d7e55..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/estimate_quick_action_shared_examples.rb +++ /dev/null @@ -1,81 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'estimate quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets estimate quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/estimate 1d 2h 3m" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.time_estimate).to eq 36180 - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the estimate quick action accordingly' do - add_note("/estimate 1d 2h 3m") - - wait_for_requests - expect(page).not_to have_content '/estimate' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.time_estimate).to eq 36180 - end - - context "when current user cannot set estimate to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not set estimate' do - add_note("/estimate ~bug ~feature") - - wait_for_requests - expect(page).not_to have_content '/estimate' - expect(issuable.reload.time_estimate).to eq 0 - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains estimate quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/estimate 1d 2h 3m') - - expect(page).not_to have_content '/estimate' - expect(page).to have_content 'Sets time estimate to 1d 2h 3m.' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb new file mode 100644 index 00000000000..439c068471b --- /dev/null +++ b/spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb @@ -0,0 +1,273 @@ +# frozen_string_literal: true + +shared_examples 'issuable quick actions' do + QuickAction = Struct.new(:action_text, :expectation, :before_action, keyword_init: true) do + # Pass a block as :before_action if + # issuable state needs to be changed before + # the quick action is executed. + def call_before_action + before_action.call if before_action + end + + def skip_access_check + action_text["/todo"] || + action_text["/done"] || + action_text["/subscribe"] || + action_text["/shrug"] || + action_text["/tableflip"] + end + end + + # Quick actions shared by issues and merge requests + let(:issuable_quick_actions) do + [ + QuickAction.new( + action_text: "/subscribe", + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable).to be_subscribed(note_author, issuable.project) + else + expect(noteable).not_to be_subscribed(note_author, issuable.project) + end + } + ), + QuickAction.new( + action_text: "/unsubscribe", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable).not_to be_subscribed(note_author, issuable.project) + } + ), + QuickAction.new( + action_text: "/todo", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.todos.count == 1).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/done", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.todos.last.done?).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/close", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.closed?).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/reopen", + before_action: -> { + issuable.close + }, + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.open?).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/assign @#{user.username}", + expectation: ->(noteable, can_use_quick_action) { + if noteable.allows_multiple_assignees? + expect(noteable.assignees == [old_assignee, user]).to eq(can_use_quick_action) + else + expect(noteable.assignees == [user]).to eq(can_use_quick_action) + end + } + ), + QuickAction.new( + action_text: "/unassign", + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable.assignees).to be_empty + else + expect(noteable.assignees).not_to be_empty + end + } + ), + QuickAction.new( + action_text: "/title new title", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.title == "new title").to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/lock", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.discussion_locked?).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/unlock", + before_action: -> { + issuable.update(discussion_locked: true) + }, + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable).not_to be_discussion_locked + else + expect(noteable).to be_discussion_locked + end + } + ), + QuickAction.new( + action_text: "/milestone %\"sprint\"", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.milestone == milestone).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/remove_milestone", + before_action: -> { + issuable.update(milestone_id: milestone.id) + }, + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable.milestone_id).to be_nil + else + expect(noteable.milestone_id).to eq(milestone.id) + end + } + ), + QuickAction.new( + action_text: "/label ~feature", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.labels&.last&.id == feature_label.id).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/unlabel", + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable.labels).to be_empty + else + expect(noteable.labels).not_to be_empty + end + } + ), + QuickAction.new( + action_text: "/award :100:", + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable.award_emoji.last.name).to eq("100") + else + expect(noteable.award_emoji).to be_empty + end + } + ), + QuickAction.new( + action_text: "/estimate 1d 2h 3m", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.time_estimate == 36180).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/remove_estimate", + before_action: -> { + issuable.update(time_estimate: 30000) + }, + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable.time_estimate).to be_zero + else + expect(noteable.time_estimate).to eq(30000) + end + } + ), + QuickAction.new( + action_text: "/spend 1d 2h 3m", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.total_time_spent == 36180).to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/remove_time_spent", + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable.total_time_spent == 0) + else + expect(noteable.timelogs).to be_empty + end + } + ), + QuickAction.new( + action_text: "/shrug oops", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.notes&.last&.note == "HELLO\noops ¯\\_(ツ)_/¯\nWORLD").to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/tableflip oops", + expectation: ->(noteable, can_use_quick_action) { + expect(noteable.notes&.last&.note == "HELLO\noops (╯°□°)╯︵ ┻━┻\nWORLD").to eq(can_use_quick_action) + } + ), + QuickAction.new( + action_text: "/copy_metadata #{issue_2.to_reference}", + expectation: ->(noteable, can_use_quick_action) { + if can_use_quick_action + expect(noteable.labels).to eq(issue_2.labels) + expect(noteable.milestone).to eq(issue_2.milestone) + else + expect(noteable.labels).not_to eq(issue_2.labels) + expect(noteable.milestone).not_to eq(issue_2.milestone) + end + } + ) + ] + end + + let(:old_assignee) { create(:user) } + + before do + project.add_developer(old_assignee) + issuable.update(assignees: [old_assignee]) + end + + context 'when user can update issuable' do + set(:developer) { create(:user) } + let(:note_author) { developer } + + before do + project.add_developer(developer) + end + + it 'saves the note and updates the issue' do + quick_actions.each do |quick_action| + note_text = %(HELLO\n#{quick_action.action_text}\nWORLD) + quick_action.call_before_action + + note = described_class.new(project, developer, note_params.merge(note: note_text)).execute + noteable = note.noteable + + # shrug and tablefip quick actions modifies the note text + # on these cases we need to skip this assertion + if !quick_action.action_text["shrug"] && !quick_action.action_text["tableflip"] + expect(note.note).to eq "HELLO\nWORLD" + end + + quick_action.expectation.call(noteable, true) + end + end + end + + context 'when user cannot update issuable' do + set(:non_member) { create(:user) } + let(:note_author) { non_member } + + it 'applies commands that user can execute' do + quick_actions.each do |quick_action| + note_text = %(HELLO\n#{quick_action.action_text}\nWORLD) + quick_action.call_before_action + + note = described_class.new(project, non_member, note_params.merge(note: note_text)).execute + noteable = note.noteable + + if quick_action.skip_access_check + quick_action.expectation.call(noteable, true) + else + quick_action.expectation.call(noteable, false) + end + end + end + end +end diff --git a/spec/support/shared_examples/quick_actions/issuable/label_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/label_quick_action_shared_examples.rb deleted file mode 100644 index 9066e382b70..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/label_quick_action_shared_examples.rb +++ /dev/null @@ -1,83 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'label quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets label quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/label ~bug ~feature" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.labels).to match_array([label_bug, label_feature]) - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - expect(issuable.labels).to eq [] - end - - it 'creates the note and interprets the label quick action accordingly' do - add_note("/label ~bug ~feature") - - wait_for_requests - expect(page).not_to have_content '/label' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.labels).to match_array([label_bug, label_feature]) - end - - context "when current user cannot set label to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not set label' do - add_note("/label ~bug ~feature") - - wait_for_requests - expect(page).not_to have_content '/label' - expect(issuable.labels).to eq [] - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains label quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/label ~bug ~feature') - - expect(page).not_to have_content '/label' - expect(page).to have_content 'Adds bug feature labels.' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/lock_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/lock_quick_action_shared_examples.rb deleted file mode 100644 index d3197f2a459..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/lock_quick_action_shared_examples.rb +++ /dev/null @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'lock quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets lock quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/lock" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable).not_to be_discussion_locked - end - end - - context "post note to existing #{issuable_type}" do - before do - issuable.update(discussion_locked: false) - expect(issuable).not_to be_discussion_locked - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the lock quick action accordingly' do - add_note('/lock') - - wait_for_requests - expect(page).not_to have_content '/lock' - expect(page).to have_content 'Commands applied' - expect(issuable.reload).to be_discussion_locked - end - - context "when current user cannot lock to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it "does not lock the #{issuable_type}" do - add_note('/lock') - - wait_for_requests - expect(page).not_to have_content '/lock' - expect(issuable).not_to be_discussion_locked - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains lock quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/lock') - - expect(page).not_to have_content '/lock' - expect(page).to have_content "Locks the discussion" - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/milestone_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/milestone_quick_action_shared_examples.rb deleted file mode 100644 index 7f16ce93b6a..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/milestone_quick_action_shared_examples.rb +++ /dev/null @@ -1,83 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'milestone quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets milestone quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/milestone %\"ASAP\"" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.milestone).to eq milestone - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - expect(issuable.milestone).to be_nil - end - - it 'creates the note and interprets the milestone quick action accordingly' do - add_note("/milestone %\"ASAP\"") - - wait_for_requests - expect(page).not_to have_content '/milestone' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.milestone).to eq milestone - end - - context "when current user cannot set milestone to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not set milestone' do - add_note('/milestone') - - wait_for_requests - expect(page).not_to have_content '/milestone' - expect(issuable.reload.milestone).to be_nil - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains milestone quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note("/milestone %\"ASAP\"") - - expect(page).not_to have_content '/milestone' - expect(page).to have_content 'Sets the milestone to %ASAP' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/relabel_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/relabel_quick_action_shared_examples.rb deleted file mode 100644 index 643ae77516a..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/relabel_quick_action_shared_examples.rb +++ /dev/null @@ -1,95 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'relabel quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets relabel quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/label ~bug /relabel ~feature" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.labels).to eq [label_bug, label_feature] - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - issuable.update(labels: [label_bug]) - end - - it 'creates the note and interprets the relabel quick action accordingly' do - add_note('/relabel ~feature') - - wait_for_requests - expect(page).not_to have_content '/relabel' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.labels).to match_array([label_feature]) - end - - it 'creates the note and interprets the relabel quick action with empty param' do - add_note('/relabel') - - wait_for_requests - expect(page).not_to have_content '/relabel' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.labels).to match_array([label_bug]) - end - - context "when current user cannot relabel to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not relabel' do - add_note('/relabel ~feature') - - wait_for_requests - expect(page).not_to have_content '/relabel' - expect(issuable.labels).to match_array([label_bug]) - end - end - end - - context "preview of note on #{issuable_type}", :js do - before do - issuable.update(labels: [label_bug]) - visit public_send("project_#{issuable_type}_path", project, issuable) - end - - it 'explains relabel all quick action' do - preview_note('/relabel ~feature') - - expect(page).not_to have_content '/relabel' - expect(page).to have_content 'Replaces all labels with feature label.' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/remove_estimate_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/remove_estimate_quick_action_shared_examples.rb deleted file mode 100644 index 24f6f8d5bf4..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/remove_estimate_quick_action_shared_examples.rb +++ /dev/null @@ -1,82 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'remove_estimate quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets estimate quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/remove_estimate" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.time_estimate).to eq 0 - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - issuable.update_attribute(:time_estimate, 36180) - end - - it 'creates the note and interprets the remove_estimate quick action accordingly' do - add_note("/remove_estimate") - - wait_for_requests - expect(page).not_to have_content '/remove_estimate' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.time_estimate).to eq 0 - end - - context "when current user cannot remove_estimate" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not remove_estimate' do - add_note('/remove_estimate') - - wait_for_requests - expect(page).not_to have_content '/remove_estimate' - expect(issuable.reload.time_estimate).to eq 36180 - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains remove_estimate quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/remove_estimate') - - expect(page).not_to have_content '/remove_estimate' - expect(page).to have_content 'Removes time estimate.' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/remove_milestone_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/remove_milestone_quick_action_shared_examples.rb deleted file mode 100644 index edd92d5cdbc..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/remove_milestone_quick_action_shared_examples.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'remove_milestone quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets remove_milestone quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/remove_milestone" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.milestone).to be_nil - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - issuable.update(milestone: milestone) - expect(issuable.milestone).to eq(milestone) - end - - it 'creates the note and interprets the remove_milestone quick action accordingly' do - add_note("/remove_milestone") - - wait_for_requests - expect(page).not_to have_content '/remove_milestone' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.milestone).to be_nil - end - - context "when current user cannot remove milestone to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not remove milestone' do - add_note('/remove_milestone') - - wait_for_requests - expect(page).not_to have_content '/remove_milestone' - expect(issuable.reload.milestone).to eq(milestone) - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains remove_milestone quick action' do - issuable.update(milestone: milestone) - expect(issuable.milestone).to eq(milestone) - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note("/remove_milestone") - - expect(page).not_to have_content '/remove_milestone' - expect(page).to have_content 'Removes %ASAP milestone.' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/remove_time_spent_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/remove_time_spent_quick_action_shared_examples.rb deleted file mode 100644 index 6d5894b2318..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/remove_time_spent_quick_action_shared_examples.rb +++ /dev/null @@ -1,82 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'remove_time_spent quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets remove_time_spent quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/remove_time_spent" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.total_time_spent).to eq 0 - end - end - - context "post note to existing #{issuable_type}" do - before do - issuable.update!(spend_time: { duration: 36180, user_id: maintainer.id }) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the remove_time_spent quick action accordingly' do - add_note("/remove_time_spent") - - wait_for_requests - expect(page).not_to have_content '/remove_time_spent' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.total_time_spent).to eq 0 - end - - context "when current user cannot set remove_time_spent time" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not set remove_time_spent time' do - add_note("/remove_time_spent") - - wait_for_requests - expect(page).not_to have_content '/remove_time_spent' - expect(issuable.reload.total_time_spent).to eq 36180 - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains remove_time_spent quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/remove_time_spent') - - expect(page).not_to have_content '/remove_time_spent' - expect(page).to have_content 'Removes spent time.' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/reopen_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/reopen_quick_action_shared_examples.rb deleted file mode 100644 index af173e93bb5..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/reopen_quick_action_shared_examples.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'reopen quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets reopen quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/reopen" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - end - end - - context "post note to existing #{issuable_type}" do - before do - issuable.close - expect(issuable).to be_closed - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the reopen quick action accordingly' do - add_note('/reopen') - - wait_for_requests - expect(page).not_to have_content '/reopen' - expect(page).to have_content 'Commands applied' - - issuable.reload - expect(issuable).to be_opened - end - - context "when current user cannot reopen #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it "does not reopen the #{issuable_type}" do - add_note('/reopen') - - expect(page).not_to have_content 'Commands applied' - expect(issuable).to be_closed - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains reopen quick action' do - issuable.close - expect(issuable).to be_closed - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/reopen') - - expect(page).not_to have_content '/reopen' - expect(page).to have_content "Reopens this #{issuable_type.to_s.humanize.downcase}." - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/shrug_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/shrug_quick_action_shared_examples.rb deleted file mode 100644 index b592cf16f67..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/shrug_quick_action_shared_examples.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'shrug quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets shrug quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/shrug oops" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq "bug description\noops ¯\\_(ツ)_/¯" - expect(page).to have_content 'bug 345' - expect(page).to have_content "bug description oops ¯\\_(ツ)_/¯" - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets shrug quick action accordingly' do - add_note("/shrug oops") - - wait_for_requests - expect(page).not_to have_content '/shrug oops' - expect(page).to have_content "oops ¯\\_(ツ)_/¯" - expect(issuable.notes.last.note).to eq "oops ¯\\_(ツ)_/¯" - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains shrug quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/shrug oops') - - expect(page).not_to have_content '/shrug' - expect(page).to have_content "oops ¯\\_(ツ)_/¯" - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/spend_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/spend_quick_action_shared_examples.rb deleted file mode 100644 index 97b4885eba0..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/spend_quick_action_shared_examples.rb +++ /dev/null @@ -1,81 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'spend quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets spend quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/spend 1d 2h 3m" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.total_time_spent).to eq 36180 - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the spend quick action accordingly' do - add_note("/spend 1d 2h 3m") - - wait_for_requests - expect(page).not_to have_content '/spend' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.total_time_spent).to eq 36180 - end - - context "when current user cannot set spend time" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not set spend time' do - add_note("/spend 1s 2h 3m") - - wait_for_requests - expect(page).not_to have_content '/spend' - expect(issuable.reload.total_time_spent).to eq 0 - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains spend quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/spend 1d 2h 3m') - - expect(page).not_to have_content '/spend' - expect(page).to have_content 'Adds 1d 2h 3m spent time.' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/subscribe_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/subscribe_quick_action_shared_examples.rb deleted file mode 100644 index 15aefd511a5..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/subscribe_quick_action_shared_examples.rb +++ /dev/null @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'subscribe quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets subscribe quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/subscribe" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.subscribed?(maintainer, project)).to be_truthy - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - expect(issuable.subscribed?(maintainer, project)).to be_falsy - end - - it 'creates the note and interprets the subscribe quick action accordingly' do - add_note('/subscribe') - - wait_for_requests - expect(page).not_to have_content '/subscribe' - expect(page).to have_content 'Commands applied' - expect(issuable.subscribed?(maintainer, project)).to be_truthy - end - - context "when current user cannot subscribe to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it "does not subscribe to the #{issuable_type}" do - add_note('/subscribe') - - wait_for_requests - expect(page).not_to have_content '/subscribe' - expect(page).to have_content 'Commands applied' - expect(issuable.subscribed?(maintainer, project)).to be_falsy - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains subscribe quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/subscribe') - - expect(page).not_to have_content '/subscribe' - expect(page).to have_content "Subscribes to this #{issuable_type.to_s.humanize.downcase}" - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/tableflip_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/tableflip_quick_action_shared_examples.rb deleted file mode 100644 index c174127c4ff..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/tableflip_quick_action_shared_examples.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'tableflip quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets tableflip quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/tableflip oops" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq "bug description\noops (╯°□°)╯︵ ┻━┻" - expect(page).to have_content 'bug 345' - expect(page).to have_content "bug description oops (╯°□°)╯︵ ┻━┻" - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets tableflip quick action accordingly' do - add_note("/tableflip oops") - - wait_for_requests - expect(page).not_to have_content '/tableflip oops' - expect(page).to have_content "oops (╯°□°)╯︵ ┻━┻" - expect(issuable.notes.last.note).to eq "oops (╯°□°)╯︵ ┻━┻" - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains tableflip quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/tableflip oops') - - expect(page).not_to have_content '/tableflip' - expect(page).to have_content "oops (╯°□°)╯︵ ┻━┻" - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/title_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/title_quick_action_shared_examples.rb deleted file mode 100644 index 93a69093dde..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/title_quick_action_shared_examples.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'title quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets title quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/title new title" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(issuable.title).to eq 'bug 345' - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the title quick action accordingly' do - add_note('/title New title') - - wait_for_requests - expect(page).not_to have_content '/title new title' - expect(page).to have_content 'Commands applied' - expect(page).to have_content 'New title' - - issuable.reload - expect(issuable.title).to eq 'New title' - end - - context "when current user cannot set title #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it "does not set title to the #{issuable_type}" do - add_note('/title New title') - - expect(page).not_to have_content 'Commands applied' - expect(issuable.title).not_to eq 'New title' - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains title quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/title New title') - wait_for_requests - - expect(page).not_to have_content '/title New title' - expect(page).to have_content 'Changes the title to "New title".' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/todo_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/todo_quick_action_shared_examples.rb deleted file mode 100644 index cccc28127ce..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/todo_quick_action_shared_examples.rb +++ /dev/null @@ -1,92 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'todo quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets todo quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/todo" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - - todos = TodosFinder.new(maintainer).execute - expect(todos.size).to eq 0 - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the todo quick action accordingly' do - add_note('/todo') - - wait_for_requests - expect(page).not_to have_content '/todo' - expect(page).to have_content 'Commands applied' - - todos = TodosFinder.new(maintainer).execute - todo = todos.first - - expect(todos.size).to eq 1 - expect(todo).to be_pending - expect(todo.target).to eq issuable - expect(todo.author).to eq maintainer - expect(todo.user).to eq maintainer - end - - context "when current user cannot add todo #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it "does not add todo the #{issuable_type}" do - add_note('/todo') - - expect(page).not_to have_content 'Commands applied' - todos = TodosFinder.new(maintainer).execute - expect(todos.size).to eq 0 - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains todo quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/todo') - - expect(page).not_to have_content '/todo' - expect(page).to have_content "Adds a todo." - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/unassign_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/unassign_quick_action_shared_examples.rb deleted file mode 100644 index 0b1a52bc860..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/unassign_quick_action_shared_examples.rb +++ /dev/null @@ -1,120 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'unassign quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets unassign quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/unassign @bob" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable.assignees).to eq [] - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - end - - it "creates the #{issuable_type} and interprets unassign quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/unassign me" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable.assignees).to eq [] - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the unassign quick action accordingly' do - assignee = create(:user, username: 'bob') - issuable.update(assignee_ids: [assignee.id]) - expect(issuable.assignees).to eq [assignee] - - add_note("Awesome!\n\n/unassign @bob") - - expect(page).to have_content 'Awesome!' - expect(page).not_to have_content '/unassign @bob' - - wait_for_requests - issuable.reload - note = issuable.notes.user.first - - expect(note.note).to eq 'Awesome!' - expect(issuable.assignees).to eq [] - end - - it "unassigns the #{issuable_type} from current user" do - issuable.update(assignee_ids: [maintainer.id]) - expect(issuable.reload.assignees).to eq [maintainer] - expect(issuable.assignees).to eq [maintainer] - - add_note("/unassign me") - - expect(page).not_to have_content '/unassign me' - expect(page).to have_content 'Commands applied' - - expect(issuable.reload.assignees).to eq [] - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains unassign quick action: from bob' do - assignee = create(:user, username: 'bob') - issuable.update(assignee_ids: [assignee.id]) - expect(issuable.assignees).to eq [assignee] - - visit public_send("project_#{issuable_type}_path", project, issuable) - - page.within('.js-main-target-form') do - fill_in 'note[note]', with: "Awesome!\n/unassign @bob " - click_on 'Preview' - - expect(page).not_to have_content '/unassign @bob' - expect(page).to have_content 'Awesome!' - expect(page).to have_content 'Removes assignee @bob.' - end - end - - it 'explains unassign quick action: from me' do - issuable.update(assignee_ids: [maintainer.id]) - expect(issuable.assignees).to eq [maintainer] - - visit public_send("project_#{issuable_type}_path", project, issuable) - - page.within('.js-main-target-form') do - fill_in 'note[note]', with: "Awesome!\n/unassign me" - click_on 'Preview' - - expect(page).not_to have_content '/unassign me' - expect(page).to have_content 'Awesome!' - expect(page).to have_content "Removes assignee @#{maintainer.username}." - end - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/unlabel_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/unlabel_quick_action_shared_examples.rb deleted file mode 100644 index 1a1ee05841f..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/unlabel_quick_action_shared_examples.rb +++ /dev/null @@ -1,102 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'unlabel quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets unlabel quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/label ~bug /unlabel" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.labels).to eq [label_bug] - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - issuable.update(labels: [label_bug, label_feature]) - end - - it 'creates the note and interprets the unlabel all quick action accordingly' do - add_note("/unlabel") - - wait_for_requests - expect(page).not_to have_content '/unlabel' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.labels).to eq [] - end - - it 'creates the note and interprets the unlabel some quick action accordingly' do - add_note("/unlabel ~bug") - - wait_for_requests - expect(page).not_to have_content '/unlabel' - expect(page).to have_content 'Commands applied' - expect(issuable.reload.labels).to match_array([label_feature]) - end - - context "when current user cannot unlabel to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'does not unlabel' do - add_note("/unlabel") - - wait_for_requests - expect(page).not_to have_content '/unlabel' - expect(issuable.labels).to match_array([label_bug, label_feature]) - end - end - end - - context "preview of note on #{issuable_type}", :js do - before do - issuable.update(labels: [label_bug, label_feature]) - visit public_send("project_#{issuable_type}_path", project, issuable) - end - - it 'explains unlabel all quick action' do - preview_note('/unlabel') - - expect(page).not_to have_content '/unlabel' - expect(page).to have_content 'Removes all labels.' - end - - it 'explains unlabel some quick action' do - preview_note('/unlabel ~bug') - - expect(page).not_to have_content '/unlabel' - expect(page).to have_content 'Removes bug label.' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/unlock_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/unlock_quick_action_shared_examples.rb deleted file mode 100644 index 998ff99b32e..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/unlock_quick_action_shared_examples.rb +++ /dev/null @@ -1,87 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'unlock quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets unlock quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/unlock" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable).not_to be_discussion_locked - end - end - - context "post note to existing #{issuable_type}" do - before do - issuable.update(discussion_locked: true) - expect(issuable).to be_discussion_locked - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it 'creates the note and interprets the unlock quick action accordingly' do - add_note('/unlock') - - wait_for_requests - expect(page).not_to have_content '/unlock' - expect(page).to have_content 'Commands applied' - expect(issuable.reload).not_to be_discussion_locked - end - - context "when current user cannot unlock to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it "does not lock the #{issuable_type}" do - add_note('/unlock') - - wait_for_requests - expect(page).not_to have_content '/unlock' - expect(issuable).to be_discussion_locked - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains unlock quick action' do - issuable.update(discussion_locked: true) - expect(issuable).to be_discussion_locked - - visit public_send("project_#{issuable_type}_path", project, issuable) - - preview_note('/unlock') - - expect(page).not_to have_content '/unlock' - expect(page).to have_content 'Unlocks the discussion' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issuable/unsubscribe_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/unsubscribe_quick_action_shared_examples.rb deleted file mode 100644 index bd92f133889..00000000000 --- a/spec/support/shared_examples/quick_actions/issuable/unsubscribe_quick_action_shared_examples.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'unsubscribe quick action' do |issuable_type| - before do - project.add_maintainer(maintainer) - gitlab_sign_in(maintainer) - end - - context "new #{issuable_type}", :js do - before do - case issuable_type - when :merge_request - visit public_send('namespace_project_new_merge_request_path', project.namespace, project, new_url_opts) - wait_for_all_requests - when :issue - visit public_send('new_namespace_project_issue_path', project.namespace, project, new_url_opts) - wait_for_all_requests - end - end - - it "creates the #{issuable_type} and interprets unsubscribe quick action accordingly" do - fill_in "#{issuable_type}_title", with: 'bug 345' - fill_in "#{issuable_type}_description", with: "bug description\n/unsubscribe" - click_button "Submit #{issuable_type}".humanize - - issuable = project.public_send(issuable_type.to_s.pluralize).first - - expect(issuable.description).to eq 'bug description' - expect(issuable).to be_opened - expect(page).to have_content 'bug 345' - expect(page).to have_content 'bug description' - expect(issuable.subscribed?(maintainer, project)).to be_truthy - end - end - - context "post note to existing #{issuable_type}" do - before do - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - issuable.subscribe(maintainer, project) - expect(issuable.subscribed?(maintainer, project)).to be_truthy - end - - it 'creates the note and interprets the unsubscribe quick action accordingly' do - add_note('/unsubscribe') - - wait_for_requests - expect(page).not_to have_content '/unsubscribe' - expect(page).to have_content 'Commands applied' - expect(issuable.subscribed?(maintainer, project)).to be_falsey - end - - context "when current user cannot unsubscribe to #{issuable_type}" do - before do - guest = create(:user) - project.add_guest(guest) - - gitlab_sign_out - gitlab_sign_in(guest) - visit public_send("project_#{issuable_type}_path", project, issuable) - wait_for_all_requests - end - - it "does not unsubscribe to the #{issuable_type}" do - add_note('/unsubscribe') - - wait_for_requests - expect(page).not_to have_content '/unsubscribe' - expect(issuable.subscribed?(maintainer, project)).to be_truthy - end - end - end - - context "preview of note on #{issuable_type}", :js do - it 'explains unsubscribe quick action' do - visit public_send("project_#{issuable_type}_path", project, issuable) - issuable.subscribe(maintainer, project) - expect(issuable.subscribed?(maintainer, project)).to be_truthy - - preview_note('/unsubscribe') - - expect(page).not_to have_content '/unsubscribe' - expect(page).to have_content "Unsubscribes from this #{issuable_type.to_s.humanize.downcase}." - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issue/confidential_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issue/confidential_quick_action_shared_examples.rb deleted file mode 100644 index 336500487fe..00000000000 --- a/spec/support/shared_examples/quick_actions/issue/confidential_quick_action_shared_examples.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'confidential quick action' do - context 'when the current user can update issues' do - it 'does not create a note, and marks the issue as confidential' do - add_note('/confidential') - - expect(page).not_to have_content '/confidential' - expect(page).to have_content 'Commands applied' - expect(page).to have_content 'made the issue confidential' - - expect(issue.reload).to be_confidential - end - end - - context 'when the current user cannot update the issue' do - let(:guest) { create(:user) } - - before do - project.add_guest(guest) - gitlab_sign_out - sign_in(guest) - visit project_issue_path(project, issue) - end - - it 'does not create a note, and does not mark the issue as confidential' do - add_note('/confidential') - - expect(page).not_to have_content 'Commands applied' - expect(page).not_to have_content 'made the issue confidential' - - expect(issue.reload).not_to be_confidential - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issue/due_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issue/due_quick_action_shared_examples.rb deleted file mode 100644 index ae78cd86cd5..00000000000 --- a/spec/support/shared_examples/quick_actions/issue/due_quick_action_shared_examples.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'due quick action' do - context 'due quick action available and date can be added' do - it 'sets the due date accordingly' do - add_note('/due 2016-08-28') - - expect(page).not_to have_content '/due 2016-08-28' - expect(page).to have_content 'Commands applied' - - visit project_issue_path(project, issue) - - page.within '.due_date' do - expect(page).to have_content 'Aug 28, 2016' - end - end - end - - context 'due quick action not available' do - let(:guest) { create(:user) } - before do - project.add_guest(guest) - gitlab_sign_out - sign_in(guest) - visit project_issue_path(project, issue) - end - - it 'does not set the due date' do - add_note('/due 2016-08-28') - - expect(page).not_to have_content 'Commands applied' - expect(page).not_to have_content '/due 2016-08-28' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/issue/remove_due_date_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issue/remove_due_date_quick_action_shared_examples.rb deleted file mode 100644 index 657c2a60d24..00000000000 --- a/spec/support/shared_examples/quick_actions/issue/remove_due_date_quick_action_shared_examples.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'remove_due_date quick action' do - context 'remove_due_date action available and due date can be removed' do - it 'removes the due date accordingly' do - add_note('/remove_due_date') - - expect(page).not_to have_content '/remove_due_date' - expect(page).to have_content 'Commands applied' - - visit project_issue_path(project, issue) - - page.within '.due_date' do - expect(page).to have_content 'None' - end - end - end - - context 'remove_due_date action not available' do - let(:guest) { create(:user) } - before do - project.add_guest(guest) - gitlab_sign_out - sign_in(guest) - visit project_issue_path(project, issue) - end - - it 'does not remove the due date' do - add_note("/remove_due_date") - - expect(page).not_to have_content 'Commands applied' - expect(page).not_to have_content '/remove_due_date' - end - end -end diff --git a/spec/support/shared_examples/quick_actions/merge_request/target_branch_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/merge_request/target_branch_quick_action_shared_examples.rb deleted file mode 100644 index cf2bdb1dd68..00000000000 --- a/spec/support/shared_examples/quick_actions/merge_request/target_branch_quick_action_shared_examples.rb +++ /dev/null @@ -1,81 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'target_branch quick action' do - describe '/target_branch command in merge request' do - let(:another_project) { create(:project, :public, :repository) } - let(:new_url_opts) { { merge_request: { source_branch: 'feature' } } } - - before do - another_project.add_maintainer(user) - sign_in(user) - end - - it 'changes target_branch in new merge_request' do - visit project_new_merge_request_path(another_project, new_url_opts) - - fill_in "merge_request_title", with: 'My brand new feature' - fill_in "merge_request_description", with: "le feature \n/target_branch fix\nFeature description:" - click_button "Submit merge request" - - merge_request = another_project.merge_requests.first - expect(merge_request.description).to eq "le feature \nFeature description:" - expect(merge_request.target_branch).to eq 'fix' - end - - it 'does not change target branch when merge request is edited' do - new_merge_request = create(:merge_request, source_project: another_project) - - visit edit_project_merge_request_path(another_project, new_merge_request) - fill_in "merge_request_description", with: "Want to update target branch\n/target_branch fix\n" - click_button "Save changes" - - new_merge_request = another_project.merge_requests.first - expect(new_merge_request.description).to include('/target_branch') - expect(new_merge_request.target_branch).not_to eq('fix') - end - end - - describe '/target_branch command from note' do - context 'when the current user can change target branch' do - before do - sign_in(user) - visit project_merge_request_path(project, merge_request) - end - - it 'changes target branch from a note' do - add_note("message start \n/target_branch merge-test\n message end.") - - wait_for_requests - expect(page).not_to have_content('/target_branch') - expect(page).to have_content('message start') - expect(page).to have_content('message end.') - - expect(merge_request.reload.target_branch).to eq 'merge-test' - end - - it 'does not fail when target branch does not exists' do - add_note('/target_branch totally_not_existing_branch') - - expect(page).not_to have_content('/target_branch') - - expect(merge_request.target_branch).to eq 'feature' - end - end - - context 'when current user can not change target branch' do - before do - project.add_guest(guest) - sign_in(guest) - visit project_merge_request_path(project, merge_request) - end - - it 'does not change target branch' do - add_note('/target_branch merge-test') - - expect(page).not_to have_content '/target_branch merge-test' - - expect(merge_request.target_branch).to eq 'feature' - end - end - end -end diff --git a/spec/support/shared_examples/quick_actions/merge_request/wip_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/merge_request/wip_quick_action_shared_examples.rb deleted file mode 100644 index 60d6e53e74f..00000000000 --- a/spec/support/shared_examples/quick_actions/merge_request/wip_quick_action_shared_examples.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'wip quick action' do - context 'when the current user can toggle the WIP prefix' do - before do - sign_in(user) - visit project_merge_request_path(project, merge_request) - wait_for_requests - end - - it 'adds the WIP: prefix to the title' do - add_note('/wip') - - expect(page).not_to have_content '/wip' - expect(page).to have_content 'Commands applied' - - expect(merge_request.reload.work_in_progress?).to eq true - end - - it 'removes the WIP: prefix from the title' do - merge_request.update!(title: merge_request.wip_title) - add_note('/wip') - - expect(page).not_to have_content '/wip' - expect(page).to have_content 'Commands applied' - - expect(merge_request.reload.work_in_progress?).to eq false - end - end - - context 'when the current user cannot toggle the WIP prefix' do - before do - project.add_guest(guest) - sign_in(guest) - visit project_merge_request_path(project, merge_request) - end - - it 'does not change the WIP prefix' do - add_note('/wip') - - expect(page).not_to have_content '/wip' - expect(page).not_to have_content 'Commands applied' - - expect(merge_request.reload.work_in_progress?).to eq false - end - end -end |