Commit 29883453 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'issue_60515' into 'master'

Move some quick actions feature specs to unit tests

Closes #60515

See merge request gitlab-org/gitlab-ce!28795
parents 53036a5b 61bca622
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
require 'rails_helper' 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 describe 'Issues > User uses quick actions', :js do
include Spec::Support::Helpers::Features::NotesHelpers include Spec::Support::Helpers::Features::NotesHelpers
...@@ -15,30 +20,7 @@ describe 'Issues > User uses quick actions', :js do ...@@ -15,30 +20,7 @@ describe 'Issues > User uses quick actions', :js do
let(:issuable) { create(:issue, project: project) } let(:issuable) { create(:issue, project: project) }
let(:source_issuable) { create(:issue, project: project, milestone: milestone, labels: [label_bug, label_feature])} 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 '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 it_behaves_like 'issuable time tracker', :issue
end end
...@@ -58,11 +40,7 @@ describe 'Issues > User uses quick actions', :js do ...@@ -58,11 +40,7 @@ describe 'Issues > User uses quick actions', :js do
wait_for_requests wait_for_requests
end 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 'create_merge_request quick action'
it_behaves_like 'due quick action'
it_behaves_like 'move quick action' it_behaves_like 'move quick action'
end end
end end
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
require 'rails_helper' 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 describe 'Merge request > User uses quick actions', :js do
include Spec::Support::Helpers::Features::NotesHelpers include Spec::Support::Helpers::Features::NotesHelpers
...@@ -21,30 +26,7 @@ describe 'Merge request > User uses quick actions', :js do ...@@ -21,30 +26,7 @@ describe 'Merge request > User uses quick actions', :js do
let(:issuable) { create(:merge_request, source_project: project) } let(:issuable) { create(:merge_request, source_project: project) }
let(:source_issuable) { create(:issue, project: project, milestone: milestone, labels: [label_bug, label_feature])} 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 '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 it_behaves_like 'issuable time tracker', :merge_request
end end
...@@ -59,7 +41,5 @@ describe 'Merge request > User uses quick actions', :js do ...@@ -59,7 +41,5 @@ describe 'Merge request > User uses quick actions', :js do
end end
it_behaves_like 'merge quick action' it_behaves_like 'merge quick action'
it_behaves_like 'target_branch quick action'
it_behaves_like 'wip quick action'
end end
end end
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
require 'spec_helper' require 'spec_helper'
describe Notes::CreateService do describe Notes::CreateService do
let(:project) { create(:project) } set(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project) } set(:issue) { create(:issue, project: project) }
let(:user) { create(:user) } set(:user) { create(:user) }
let(:opts) do let(:opts) do
{ note: 'Awesome comment', noteable_type: 'Issue', noteable_id: issue.id } { note: 'Awesome comment', noteable_type: 'Issue', noteable_id: issue.id }
end end
...@@ -197,64 +197,113 @@ describe Notes::CreateService do ...@@ -197,64 +197,113 @@ describe Notes::CreateService do
end end
context 'note with commands' do context 'note with commands' do
context 'as a user who can update the target' do context 'all quick actions' do
context '/close, /label, /assign & /milestone' do set(:milestone) { create(:milestone, project: project, title: "sprint") }
let(:note_text) { %(HELLO\n/close\n/assign @#{user.username}\nWORLD) } set(:bug_label) { create(:label, project: project, title: 'bug') }
set(:to_be_copied_label) { create(:label, project: project, title: 'to be copied') }
it 'saves the note and does not alter the note text' do set(:feature_label) { create(:label, project: project, title: 'feature') }
service = double(:service) set(:issue) { create(:issue, project: project, labels: [bug_label], due_date: '2019-01-01') }
allow(Issues::UpdateService).to receive(:new).and_return(service) set(:issue_2) { create(:issue, project: project, labels: [bug_label, to_be_copied_label]) }
expect(service).to receive(:execute)
context 'for issues' do
note = described_class.new(project, user, opts.merge(note: note_text)).execute let(:issuable) { issue }
let(:note_params) { opts }
expect(note.note).to eq "HELLO\nWORLD" 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
end
context '/merge with sha option' do it_behaves_like 'issuable quick actions' do
let(:note_text) { %(HELLO\n/merge\nWORLD) } let(:quick_actions) { issuable_quick_actions + issue_quick_actions }
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"
end end
end end
context 'when note only have commands' do context 'for merge requests' do
it 'adds commands applied message to note errors' do set(:merge_request) { create(:merge_request, source_project: project, labels: [bug_label]) }
note_text = %(/close) let(:issuable) { merge_request }
service = double(:service) let(:note_params) { opts.merge(noteable_type: 'MergeRequest', noteable_id: merge_request.id) }
allow(Issues::UpdateService).to receive(:new).and_return(service) let(:merge_request_quick_actions) do
expect(service).to receive(:execute) [
QuickAction.new(
note = described_class.new(project, user, opts.merge(note: note_text)).execute 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 end
end end
context 'as a user who cannot update the target' do context 'when note only have commands' do
let(:note_text) { "HELLO\n/todo\n/assign #{user.to_reference}\nWORLD" } it 'adds commands applied message to note errors' do
let(:note) { described_class.new(project, user, opts.merge(note: note_text)).execute } note_text = %(/close)
service = double(:service)
before do allow(Issues::UpdateService).to receive(:new).and_return(service)
project.team.find_member(user.id).update!(access_level: Gitlab::Access::GUEST) expect(service).to receive(:execute)
end
it 'applies commands the user can execute' do
expect { note }.to change { user.todos_pending_count }.from(0).to(1)
end
it 'does not apply commands the user cannot execute' do note = described_class.new(project, user, opts.merge(note: note_text)).execute
expect { note }.not_to change { issue.assignees }
end
it 'saves the note' do expect(note.errors[:commands_only]).to be_present
expect(note.note).to eq "HELLO\nWORLD"
end end
end end
end end
......
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment