2019-07-31 22:56:46 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
require 'spec_helper'
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2023-05-27 22:25:52 +05:30
|
|
|
RSpec.describe Issues::BuildService, feature_category: :team_planning do
|
2021-11-11 11:23:49 +05:30
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
let_it_be(:project) { create(:project, :repository) }
|
|
|
|
let_it_be(:developer) { create(:user) }
|
2021-12-11 22:18:48 +05:30
|
|
|
let_it_be(:reporter) { create(:user) }
|
2021-01-03 14:25:43 +05:30
|
|
|
let_it_be(:guest) { create(:user) }
|
2021-04-29 21:17:54 +05:30
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
let(:user) { developer }
|
|
|
|
|
|
|
|
before_all do
|
|
|
|
project.add_developer(developer)
|
2021-12-11 22:18:48 +05:30
|
|
|
project.add_reporter(reporter)
|
2021-01-03 14:25:43 +05:30
|
|
|
project.add_guest(guest)
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
def build_issue(issue_params = {})
|
2023-04-23 21:23:45 +05:30
|
|
|
described_class.new(container: project, current_user: user, params: issue_params).execute
|
2019-03-13 22:55:13 +05:30
|
|
|
end
|
|
|
|
|
2017-08-17 22:00:37 +05:30
|
|
|
context 'for a single discussion' do
|
|
|
|
describe '#execute' do
|
|
|
|
let(:merge_request) { create(:merge_request, title: "Hello world", source_project: project) }
|
|
|
|
let(:discussion) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, note: "Almost done").to_discussion }
|
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
subject { build_issue(merge_request_to_resolve_discussions_of: merge_request.iid, discussion_to_resolve: discussion.id) }
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
it 'references the noteable title in the issue title' do
|
|
|
|
expect(subject.title).to include('Hello world')
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'adds the note content to the description' do
|
2019-03-13 22:55:13 +05:30
|
|
|
expect(subject.description).to include('Almost done')
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'for discussions in a merge request' do
|
|
|
|
let(:merge_request) { create(:merge_request_with_diff_notes, source_project: project) }
|
|
|
|
|
|
|
|
describe '#items_for_discussions' do
|
|
|
|
it 'has an item for each discussion' do
|
|
|
|
create(:diff_note_on_merge_request, noteable: merge_request, project: merge_request.source_project, line_number: 13)
|
2023-04-23 21:23:45 +05:30
|
|
|
service = described_class.new(container: project, current_user: user, params: { merge_request_to_resolve_discussions_of: merge_request.iid })
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
service.execute
|
|
|
|
|
|
|
|
expect(service.items_for_discussions.size).to eq(2)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#item_for_discussion' do
|
2023-04-23 21:23:45 +05:30
|
|
|
let(:service) { described_class.new(container: project, current_user: user, params: { merge_request_to_resolve_discussions_of: merge_request.iid }) }
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
it 'mentions the author of the note' do
|
|
|
|
discussion = create(:diff_note_on_merge_request, author: create(:user, username: 'author')).to_discussion
|
|
|
|
expect(service.item_for_discussion(discussion)).to include('@author')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'wraps the note in a blockquote' do
|
|
|
|
note_text = "This is a string\n"\
|
2022-10-11 01:57:18 +05:30
|
|
|
"\n"\
|
2017-08-17 22:00:37 +05:30
|
|
|
">>>\n"\
|
|
|
|
"with a blockquote\n"\
|
|
|
|
"> That has a quote\n"\
|
|
|
|
">>>\n"
|
|
|
|
note_result = " > This is a string\n"\
|
2022-10-11 01:57:18 +05:30
|
|
|
" > \n"\
|
2019-07-07 11:18:12 +05:30
|
|
|
" > \n"\
|
2017-08-17 22:00:37 +05:30
|
|
|
" > > with a blockquote\n"\
|
2019-07-07 11:18:12 +05:30
|
|
|
" > > > That has a quote\n"\
|
|
|
|
" > \n"
|
2017-08-17 22:00:37 +05:30
|
|
|
discussion = create(:diff_note_on_merge_request, note: note_text).to_discussion
|
|
|
|
expect(service.item_for_discussion(discussion)).to include(note_result)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#execute' do
|
2019-03-13 22:55:13 +05:30
|
|
|
let(:base_params) { { merge_request_to_resolve_discussions_of: merge_request.iid } }
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
context 'without additional params' do
|
|
|
|
subject { build_issue(base_params) }
|
|
|
|
|
|
|
|
it 'has the merge request reference in the title' do
|
|
|
|
expect(subject.title).to include(merge_request.title)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'has the reference of the merge request in the description' do
|
|
|
|
expect(subject.description).to include(merge_request.to_reference)
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
it 'uses provided title if title param given' do
|
|
|
|
issue = build_issue(base_params.merge(title: 'What an issue'))
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
expect(issue.title).to eq('What an issue')
|
|
|
|
end
|
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
it 'uses provided description if description param given' do
|
|
|
|
issue = build_issue(base_params.merge(description: 'Fix at your earliest convenience'))
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
expect(issue.description).to eq('Fix at your earliest convenience')
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
describe 'with multiple discussions' do
|
|
|
|
let!(:diff_note) { create(:diff_note_on_merge_request, noteable: merge_request, project: merge_request.target_project, line_number: 15) }
|
|
|
|
|
|
|
|
it 'mentions all the authors in the description' do
|
|
|
|
authors = merge_request.resolvable_discussions.map(&:author)
|
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
expect(build_issue(base_params).description).to include(*authors.map(&:to_reference))
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'has a link for each unresolved discussion in the description' do
|
|
|
|
notes = merge_request.resolvable_discussions.map(&:first_note)
|
|
|
|
links = notes.map { |note| Gitlab::UrlBuilder.build(note) }
|
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
expect(build_issue(base_params).description).to include(*links)
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'mentions additional notes' do
|
|
|
|
create_list(:diff_note_on_merge_request, 2, noteable: merge_request, project: merge_request.target_project, in_reply_to: diff_note)
|
|
|
|
|
2019-03-13 22:55:13 +05:30
|
|
|
expect(build_issue(base_params).description).to include('(+2 comments)')
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'For a merge request without discussions' do
|
|
|
|
let(:merge_request) { create(:merge_request, source_project: project) }
|
|
|
|
|
|
|
|
describe '#execute' do
|
|
|
|
it 'mentions the merge request in the description' do
|
2019-03-13 22:55:13 +05:30
|
|
|
issue = build_issue(merge_request_to_resolve_discussions_of: merge_request.iid)
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
expect(issue.description).to include("Review the conversation in #{merge_request.to_reference}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#execute' do
|
2021-12-11 22:18:48 +05:30
|
|
|
describe 'setting milestone' do
|
|
|
|
context 'when developer' do
|
|
|
|
it 'builds a new issues with given params' do
|
|
|
|
milestone = create(:milestone, project: project)
|
|
|
|
issue = build_issue(milestone_id: milestone.id)
|
|
|
|
|
|
|
|
expect(issue.milestone).to eq(milestone)
|
|
|
|
end
|
2019-03-13 22:55:13 +05:30
|
|
|
|
2021-12-11 22:18:48 +05:30
|
|
|
it 'sets milestone to nil if it is not available for the project' do
|
|
|
|
milestone = create(:milestone, project: create(:project))
|
|
|
|
issue = build_issue(milestone_id: milestone.id)
|
2019-03-13 22:55:13 +05:30
|
|
|
|
2021-12-11 22:18:48 +05:30
|
|
|
expect(issue.milestone).to be_nil
|
|
|
|
end
|
2021-01-03 14:25:43 +05:30
|
|
|
end
|
2021-11-11 11:23:49 +05:30
|
|
|
|
2023-06-20 00:43:36 +05:30
|
|
|
context 'when user is not a project member' do
|
|
|
|
let(:user) { create(:user) }
|
2021-11-11 11:23:49 +05:30
|
|
|
|
2021-12-11 22:18:48 +05:30
|
|
|
it 'cannot set milestone' do
|
|
|
|
milestone = create(:milestone, project: project)
|
|
|
|
issue = build_issue(milestone_id: milestone.id)
|
|
|
|
|
|
|
|
expect(issue.milestone).to be_nil
|
2021-11-11 11:23:49 +05:30
|
|
|
end
|
|
|
|
end
|
2019-03-13 22:55:13 +05:30
|
|
|
end
|
2023-07-09 08:55:56 +05:30
|
|
|
|
|
|
|
describe 'setting issue type' do
|
|
|
|
context 'with a corresponding WorkItems::Type' do
|
|
|
|
let_it_be(:type_task) { WorkItems::Type.default_by_type(:task) }
|
|
|
|
let_it_be(:type_task_id) { type_task.id }
|
|
|
|
let_it_be(:type_issue_id) { WorkItems::Type.default_issue_type.id }
|
|
|
|
let_it_be(:type_incident_id) { WorkItems::Type.default_by_type(:incident).id }
|
|
|
|
let(:combined_params) { { work_item_type: type_task, issue_type: 'issue' } }
|
|
|
|
let(:work_item_params) { { work_item_type_id: type_task_id } }
|
|
|
|
|
|
|
|
where(:issue_params, :current_user, :work_item_type_id, :resulting_issue_type) do
|
|
|
|
{ issue_type: nil } | ref(:guest) | ref(:type_issue_id) | 'issue'
|
|
|
|
{ issue_type: 'issue' } | ref(:guest) | ref(:type_issue_id) | 'issue'
|
|
|
|
{ issue_type: 'incident' } | ref(:guest) | ref(:type_issue_id) | 'issue'
|
|
|
|
{ issue_type: 'incident' } | ref(:reporter) | ref(:type_incident_id) | 'incident'
|
|
|
|
ref(:combined_params) | ref(:reporter) | ref(:type_task_id) | 'task'
|
|
|
|
ref(:work_item_params) | ref(:reporter) | ref(:type_task_id) | 'task'
|
|
|
|
# update once support for test_case is enabled
|
|
|
|
{ issue_type: 'test_case' } | ref(:guest) | ref(:type_issue_id) | 'issue'
|
|
|
|
# update once support for requirement is enabled
|
|
|
|
{ issue_type: 'requirement' } | ref(:guest) | ref(:type_issue_id) | 'issue'
|
|
|
|
{ issue_type: 'invalid' } | ref(:guest) | ref(:type_issue_id) | 'issue'
|
|
|
|
# ensure that we don't set a value which has a permission check but is an invalid issue type
|
|
|
|
{ issue_type: 'project' } | ref(:guest) | ref(:type_issue_id) | 'issue'
|
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
let(:user) { current_user }
|
|
|
|
|
|
|
|
it 'builds an issue' do
|
|
|
|
issue = build_issue(**issue_params)
|
|
|
|
|
|
|
|
expect(issue.work_item_type_id).to eq(work_item_type_id)
|
|
|
|
expect(issue.attributes['issue_type']).to eq(resulting_issue_type)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
end
|