2015-05-01 03:16:19 +00:00
require 'spec_helper'
2017-07-10 14:24:02 +00:00
describe SystemNoteService do
2017-07-07 15:43:37 +00:00
include Gitlab :: Routing
2017-12-28 11:17:31 +00:00
include RepoHelpers
2018-05-22 16:37:35 +00:00
include AssetsHelpers
2016-11-09 21:55:21 +00:00
2017-08-30 10:54:23 +00:00
set ( :group ) { create ( :group ) }
set ( :project ) { create ( :project , :repository , group : group ) }
set ( :author ) { create ( :user ) }
2015-05-01 03:16:19 +00:00
let ( :noteable ) { create ( :issue , project : project ) }
2017-05-04 12:11:15 +00:00
let ( :issue ) { noteable }
2015-05-01 03:16:19 +00:00
shared_examples_for 'a system note' do
2017-03-15 13:19:45 +00:00
let ( :expected_noteable ) { noteable }
let ( :commit_count ) { nil }
2017-08-24 19:40:21 +00:00
it 'has the correct attributes' , :aggregate_failures do
2015-05-11 03:52:46 +00:00
expect ( subject ) . to be_valid
2017-08-24 19:40:21 +00:00
expect ( subject ) . to be_system
2015-05-11 03:52:46 +00:00
2017-03-15 13:19:45 +00:00
expect ( subject . noteable ) . to eq expected_noteable
2015-05-01 03:16:19 +00:00
expect ( subject . project ) . to eq project
expect ( subject . author ) . to eq author
2017-03-15 13:19:45 +00:00
2017-08-24 19:40:21 +00:00
expect ( subject . system_note_metadata . action ) . to eq ( action )
expect ( subject . system_note_metadata . commit_count ) . to eq ( commit_count )
2017-03-15 13:19:45 +00:00
end
2015-05-01 03:16:19 +00:00
end
2015-05-09 22:18:50 +00:00
describe '.add_commits' do
2015-05-11 03:52:46 +00:00
subject { described_class . add_commits ( noteable , project , author , new_commits , old_commits , oldrev ) }
2017-08-30 10:54:23 +00:00
let ( :noteable ) { create ( :merge_request , source_project : project , target_project : project ) }
2015-05-09 22:18:50 +00:00
let ( :new_commits ) { noteable . commits }
let ( :old_commits ) { [ ] }
let ( :oldrev ) { nil }
2015-05-01 03:16:19 +00:00
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :commit_count ) { new_commits . size }
let ( :action ) { 'commit' }
end
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
describe 'note body' do
let ( :note_lines ) { subject . note . split ( " \n " ) . reject ( & :blank? ) }
2015-05-01 03:16:19 +00:00
2016-09-30 01:51:33 +00:00
describe 'comparison diff link line' do
2016-09-30 15:00:03 +00:00
it 'adds the comparison text' do
expect ( note_lines [ 2 ] ) . to match " [Compare with previous version] "
2016-09-30 01:51:33 +00:00
end
end
2015-05-09 22:18:50 +00:00
context 'without existing commits' do
it 'adds a message header' do
2016-11-23 06:55:23 +00:00
expect ( note_lines [ 0 ] ) . to eq " added #{ new_commits . size } commits "
2015-05-09 22:18:50 +00:00
end
2015-05-01 03:16:19 +00:00
2018-02-02 19:16:10 +00:00
it 'adds a message for each commit' do
decoded_note_content = HTMLEntities . new . decode ( subject . note )
new_commits . each do | commit |
expect ( decoded_note_content ) . to include ( " <li> #{ commit . short_id } - #{ commit . title } </li> " )
2015-05-09 22:18:50 +00:00
end
end
2015-05-01 03:16:19 +00:00
end
2015-05-09 22:18:50 +00:00
describe 'summary line for existing commits' do
2016-09-30 15:00:03 +00:00
let ( :summary_line ) { note_lines [ 1 ] }
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
context 'with one existing commit' do
let ( :old_commits ) { [ noteable . commits . last ] }
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
it 'includes the existing commit' do
2018-02-02 19:16:10 +00:00
expect ( summary_line ) . to start_with ( " <ul><li> #{ old_commits . first . short_id } - 1 commit from branch <code>feature</code> " )
2015-05-09 22:18:50 +00:00
end
end
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
context 'with multiple existing commits' do
let ( :old_commits ) { noteable . commits [ 3 .. - 1 ] }
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
context 'with oldrev' do
let ( :oldrev ) { noteable . commits [ 2 ] . id }
2015-05-01 03:16:19 +00:00
2018-02-02 19:16:10 +00:00
it 'includes a commit range and count' do
expect ( summary_line )
. to start_with ( " <ul><li> #{ Commit . truncate_sha ( oldrev ) } ... #{ old_commits . last . short_id } - 26 commits from branch <code>feature</code> " )
2015-05-01 03:16:19 +00:00
end
end
2015-05-09 22:18:50 +00:00
context 'without oldrev' do
2018-02-02 19:16:10 +00:00
it 'includes a commit range and count' do
expect ( summary_line )
. to start_with ( " <ul><li> #{ old_commits [ 0 ] . short_id } .. #{ old_commits [ - 1 ] . short_id } - 26 commits from branch <code>feature</code> " )
2015-05-01 03:16:19 +00:00
end
end
2015-05-09 22:18:50 +00:00
context 'on a fork' do
before do
expect ( noteable ) . to receive ( :for_fork? ) . and_return ( true )
end
it 'includes the project namespace' do
2018-02-02 19:16:10 +00:00
expect ( summary_line ) . to include ( " <code> #{ noteable . target_project_namespace } :feature</code> " )
2015-05-01 03:16:19 +00:00
end
end
end
end
end
end
2015-05-09 22:18:50 +00:00
describe '.change_assignee' do
subject { described_class . change_assignee ( noteable , project , author , assignee ) }
2015-05-11 03:52:46 +00:00
let ( :assignee ) { create ( :user ) }
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'assignee' }
end
2015-05-09 22:18:50 +00:00
context 'when assignee added' do
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " assigned to @ #{ assignee . username } "
2015-05-09 22:18:50 +00:00
end
end
context 'when assignee removed' do
let ( :assignee ) { nil }
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq 'removed assignee'
2015-05-09 22:18:50 +00:00
end
end
end
2017-05-04 12:11:15 +00:00
describe '.change_issue_assignees' do
subject { described_class . change_issue_assignees ( noteable , project , author , [ assignee ] ) }
let ( :assignee ) { create ( :user ) }
let ( :assignee1 ) { create ( :user ) }
let ( :assignee2 ) { create ( :user ) }
let ( :assignee3 ) { create ( :user ) }
2017-05-05 10:41:35 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'assignee' }
end
2017-05-04 12:11:15 +00:00
def build_note ( old_assignees , new_assignees )
issue . assignees = new_assignees
described_class . change_issue_assignees ( issue , project , author , old_assignees ) . note
end
it 'builds a correct phrase when an assignee is added to a non-assigned issue' do
expect ( build_note ( [ ] , [ assignee1 ] ) ) . to eq " assigned to @ #{ assignee1 . username } "
end
it 'builds a correct phrase when assignee removed' do
2018-01-08 22:16:55 +00:00
expect ( build_note ( [ assignee1 ] , [ ] ) ) . to eq " unassigned @ #{ assignee1 . username } "
2017-05-04 12:11:15 +00:00
end
it 'builds a correct phrase when assignees changed' do
expect ( build_note ( [ assignee1 ] , [ assignee2 ] ) ) . to eq \
" assigned to @ #{ assignee2 . username } and unassigned @ #{ assignee1 . username } "
end
it 'builds a correct phrase when three assignees removed and one added' do
expect ( build_note ( [ assignee , assignee1 , assignee2 ] , [ assignee3 ] ) ) . to eq \
" assigned to @ #{ assignee3 . username } and unassigned @ #{ assignee . username } , @ #{ assignee1 . username } , and @ #{ assignee2 . username } "
end
it 'builds a correct phrase when one assignee changed from a set' do
expect ( build_note ( [ assignee , assignee1 ] , [ assignee , assignee2 ] ) ) . to eq \
" assigned to @ #{ assignee2 . username } and unassigned @ #{ assignee1 . username } "
end
it 'builds a correct phrase when one assignee removed from a set' do
expect ( build_note ( [ assignee , assignee1 , assignee2 ] , [ assignee , assignee1 ] ) ) . to eq \
" unassigned @ #{ assignee2 . username } "
end
end
2015-05-09 22:18:50 +00:00
describe '.change_label' do
2015-05-11 03:52:46 +00:00
subject { described_class . change_label ( noteable , project , author , added , removed ) }
2017-08-30 10:54:23 +00:00
let ( :labels ) { create_list ( :label , 2 , project : project ) }
2015-05-01 03:16:19 +00:00
let ( :added ) { [ ] }
let ( :removed ) { [ ] }
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'label' }
end
2015-05-01 03:16:19 +00:00
context 'with added labels' do
let ( :added ) { labels }
let ( :removed ) { [ ] }
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " added ~ #{ labels [ 0 ] . id } ~ #{ labels [ 1 ] . id } labels "
2015-05-01 03:16:19 +00:00
end
end
context 'with removed labels' do
let ( :added ) { [ ] }
let ( :removed ) { labels }
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " removed ~ #{ labels [ 0 ] . id } ~ #{ labels [ 1 ] . id } labels "
2015-05-01 03:16:19 +00:00
end
end
context 'with added and removed labels' do
let ( :added ) { [ labels [ 0 ] ] }
let ( :removed ) { [ labels [ 1 ] ] }
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " added ~ #{ labels [ 0 ] . id } and removed ~ #{ labels [ 1 ] . id } labels "
2015-05-01 03:16:19 +00:00
end
end
end
2015-05-09 22:18:50 +00:00
describe '.change_milestone' do
2017-08-03 17:37:32 +00:00
context 'for a project milestone' do
subject { described_class . change_milestone ( noteable , project , author , milestone ) }
2015-05-01 03:16:19 +00:00
2017-08-03 17:37:32 +00:00
let ( :milestone ) { create ( :milestone , project : project ) }
2015-05-11 03:52:46 +00:00
2017-08-03 17:37:32 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'milestone' }
end
2015-05-01 03:16:19 +00:00
2017-08-03 17:37:32 +00:00
context 'when milestone added' do
it 'sets the note text' do
2017-09-20 09:55:54 +00:00
reference = milestone . to_reference ( format : :iid )
expect ( subject . note ) . to eq " changed milestone to #{ reference } "
2017-08-03 17:37:32 +00:00
end
end
context 'when milestone removed' do
let ( :milestone ) { nil }
it 'sets the note text' do
expect ( subject . note ) . to eq 'removed milestone'
end
2015-05-01 03:16:19 +00:00
end
end
2017-08-03 17:37:32 +00:00
context 'for a group milestone' do
subject { described_class . change_milestone ( noteable , project , author , milestone ) }
2015-05-01 03:16:19 +00:00
2017-08-03 17:37:32 +00:00
let ( :milestone ) { create ( :milestone , group : group ) }
it_behaves_like 'a system note' do
let ( :action ) { 'milestone' }
end
context 'when milestone added' do
it 'sets the note text to use the milestone name' do
expect ( subject . note ) . to eq " changed milestone to #{ milestone . to_reference ( format : :name ) } "
end
end
context 'when milestone removed' do
let ( :milestone ) { nil }
it 'sets the note text' do
expect ( subject . note ) . to eq 'removed milestone'
end
2015-05-01 03:16:19 +00:00
end
end
end
2015-05-09 22:18:50 +00:00
describe '.change_status' do
2015-05-11 03:52:46 +00:00
subject { described_class . change_status ( noteable , project , author , status , source ) }
2017-04-04 10:36:58 +00:00
context 'with status reopened' do
let ( :status ) { 'reopened' }
let ( :source ) { nil }
2015-05-01 03:16:19 +00:00
2017-04-04 10:36:58 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'opened' }
end
2017-03-15 13:19:45 +00:00
end
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
context 'with a source' do
2017-04-04 10:36:58 +00:00
let ( :status ) { 'opened' }
2015-05-09 22:18:50 +00:00
let ( :source ) { double ( 'commit' , gfm_reference : 'commit 123456' ) }
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " #{ status } via commit 123456 "
2015-05-09 22:18:50 +00:00
end
end
end
2015-05-01 03:16:19 +00:00
2017-02-17 13:56:13 +00:00
describe '.merge_when_pipeline_succeeds' do
2016-06-03 14:22:26 +00:00
let ( :pipeline ) { build ( :ci_pipeline_without_jobs ) }
2016-04-26 11:52:18 +00:00
let ( :noteable ) do
create ( :merge_request , source_project : project , target_project : project )
end
2015-11-18 10:17:41 +00:00
2017-02-17 13:56:13 +00:00
subject { described_class . merge_when_pipeline_succeeds ( noteable , project , author , noteable . diff_head_commit ) }
2015-11-18 10:17:41 +00:00
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'merge' }
end
2015-11-18 10:17:41 +00:00
2016-11-21 09:55:54 +00:00
it " posts the 'merge when pipeline succeeds' system note " do
2018-01-27 05:35:53 +00:00
expect ( subject . note ) . to match ( %r{ enabled an automatic merge when the pipeline for ( \ w+/ \ w+@)? \ h { 40 } succeeds } )
2015-11-24 13:59:02 +00:00
end
end
2017-02-17 13:56:13 +00:00
describe '.cancel_merge_when_pipeline_succeeds' do
2016-04-26 11:52:18 +00:00
let ( :noteable ) do
create ( :merge_request , source_project : project , target_project : project )
end
2015-11-24 13:59:02 +00:00
2017-02-17 13:56:13 +00:00
subject { described_class . cancel_merge_when_pipeline_succeeds ( noteable , project , author ) }
2015-11-18 10:17:41 +00:00
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'merge' }
end
2015-11-24 13:59:02 +00:00
2016-11-21 09:55:54 +00:00
it " posts the 'merge when pipeline succeeds' system note " do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " canceled the automatic merge "
2015-11-18 10:17:41 +00:00
end
end
2015-05-27 01:49:04 +00:00
describe '.change_title' do
2017-01-25 23:54:53 +00:00
let ( :noteable ) { create ( :issue , project : project , title : 'Lorem ipsum' ) }
2015-05-27 01:49:04 +00:00
subject { described_class . change_title ( noteable , project , author , 'Old title' ) }
context 'when noteable responds to `title`' do
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'title' }
end
2015-05-27 01:49:04 +00:00
it 'sets the note text' do
2017-06-21 13:48:12 +00:00
expect ( subject . note )
. to eq " changed title from **{-Old title-}** to **{+Lorem ipsum+}** "
2015-05-27 01:49:04 +00:00
end
end
end
2017-04-28 23:54:37 +00:00
describe '.change_description' do
subject { described_class . change_description ( noteable , project , author ) }
context 'when noteable responds to `description`' do
it_behaves_like 'a system note' do
let ( :action ) { 'description' }
end
it 'sets the note text' do
2017-05-05 12:01:50 +00:00
expect ( subject . note ) . to eq ( 'changed the description' )
2017-04-28 23:54:37 +00:00
end
end
end
2016-05-18 17:56:13 +00:00
describe '.change_issue_confidentiality' do
subject { described_class . change_issue_confidentiality ( noteable , project , author ) }
2016-04-20 22:41:11 +00:00
2017-04-04 10:36:58 +00:00
context 'issue has been made confidential' do
before do
noteable . update_attribute ( :confidential , true )
end
it_behaves_like 'a system note' do
let ( :action ) { 'confidential' }
end
it 'sets the note text' do
expect ( subject . note ) . to eq 'made the issue confidential'
end
end
context 'issue has been made visible' do
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
2017-04-04 10:36:58 +00:00
let ( :action ) { 'visible' }
2017-03-15 13:19:45 +00:00
end
2016-04-20 22:41:11 +00:00
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq 'made the issue visible to everyone'
2016-04-20 22:41:11 +00:00
end
end
end
2015-05-29 01:00:37 +00:00
describe '.change_branch' do
2015-10-16 07:25:19 +00:00
subject { described_class . change_branch ( noteable , project , author , 'target' , old_branch , new_branch ) }
2017-03-27 21:14:01 +00:00
2015-05-29 01:00:37 +00:00
let ( :old_branch ) { 'old_branch' }
let ( :new_branch ) { 'new_branch' }
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'branch' }
end
2015-05-29 01:00:37 +00:00
context 'when target branch name changed' do
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " changed target branch from ` #{ old_branch } ` to ` #{ new_branch } ` "
2015-05-29 01:00:37 +00:00
end
end
end
2015-10-15 08:41:46 +00:00
describe '.change_branch_presence' do
2015-10-16 07:25:19 +00:00
subject { described_class . change_branch_presence ( noteable , project , author , :source , 'feature' , :delete ) }
2015-10-15 08:41:46 +00:00
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'branch' }
end
2015-10-15 08:41:46 +00:00
context 'when source branch deleted' do
it 'sets the note text' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " deleted source branch `feature` "
2015-10-15 08:41:46 +00:00
end
end
end
2016-02-17 06:11:48 +00:00
describe '.new_issue_branch' do
subject { described_class . new_issue_branch ( noteable , project , author , " 1-mepmep " ) }
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'branch' }
end
2016-02-17 06:11:48 +00:00
context 'when a branch is created from the new branch button' do
it 'sets the note text' do
2017-03-27 21:14:01 +00:00
expect ( subject . note ) . to start_with ( " created branch [`1-mepmep`] " )
2016-02-17 06:11:48 +00:00
end
end
end
2015-05-09 22:18:50 +00:00
describe '.cross_reference' do
subject { described_class . cross_reference ( noteable , mentioner , author ) }
2015-05-01 03:16:19 +00:00
2015-05-11 03:52:46 +00:00
let ( :mentioner ) { create ( :issue , project : project ) }
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'cross_reference' }
end
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
context 'when cross-reference disallowed' do
before do
expect ( described_class ) . to receive ( :cross_reference_disallowed? ) . and_return ( true )
end
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
it 'returns nil' do
expect ( subject ) . to be_nil
end
2017-03-15 13:19:45 +00:00
it 'does not create a system note metadata record' do
2017-08-09 09:52:22 +00:00
expect { subject } . not_to change { SystemNoteMetadata . count }
2017-03-15 13:19:45 +00:00
end
2015-05-09 22:18:50 +00:00
end
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
context 'when cross-reference allowed' do
before do
expect ( described_class ) . to receive ( :cross_reference_disallowed? ) . and_return ( false )
end
2015-05-01 03:16:19 +00:00
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'cross_reference' }
end
2015-05-09 22:18:50 +00:00
describe 'note_body' do
context 'cross-project' do
2017-08-30 10:54:23 +00:00
let ( :project2 ) { create ( :project , :repository ) }
2015-05-09 22:18:50 +00:00
let ( :mentioner ) { create ( :issue , project : project2 ) }
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
context 'from Commit' do
let ( :mentioner ) { project2 . repository . commit }
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
it 'references the mentioning commit' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " mentioned in commit #{ mentioner . to_reference ( project ) } "
2015-05-01 03:16:19 +00:00
end
end
2015-05-09 22:18:50 +00:00
context 'from non-Commit' do
it 'references the mentioning object' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " mentioned in issue #{ mentioner . to_reference ( project ) } "
2015-05-01 03:16:19 +00:00
end
end
end
2015-05-11 03:52:46 +00:00
context 'within the same project' do
2015-05-09 22:18:50 +00:00
context 'from Commit' do
let ( :mentioner ) { project . repository . commit }
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
it 'references the mentioning commit' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " mentioned in commit #{ mentioner . to_reference } "
2015-05-09 22:18:50 +00:00
end
end
2015-05-01 03:16:19 +00:00
2015-05-09 22:18:50 +00:00
context 'from non-Commit' do
it 'references the mentioning object' do
2016-11-23 06:55:23 +00:00
expect ( subject . note ) . to eq " mentioned in issue #{ mentioner . to_reference } "
2015-05-09 22:18:50 +00:00
end
end
end
2015-05-01 03:16:19 +00:00
end
end
end
2015-05-11 03:51:49 +00:00
describe '.cross_reference_disallowed?' do
context 'when mentioner is not a MergeRequest' do
it 'is falsey' do
mentioner = noteable . dup
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_disallowed? ( noteable , mentioner ) )
. to be_falsey
2015-05-11 03:51:49 +00:00
end
end
context 'when mentioner is a MergeRequest' do
let ( :mentioner ) { create ( :merge_request , :simple , source_project : project ) }
let ( :noteable ) { project . commit }
it 'is truthy when noteable is in commits' do
expect ( mentioner ) . to receive ( :commits ) . and_return ( [ noteable ] )
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_disallowed? ( noteable , mentioner ) )
. to be_truthy
2015-05-11 03:51:49 +00:00
end
it 'is falsey when noteable is not in commits' do
expect ( mentioner ) . to receive ( :commits ) . and_return ( [ ] )
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_disallowed? ( noteable , mentioner ) )
. to be_falsey
2015-05-11 03:51:49 +00:00
end
end
2015-06-14 15:41:11 +00:00
context 'when notable is an ExternalIssue' do
let ( :noteable ) { ExternalIssue . new ( 'EXT-1234' , project ) }
it 'is truthy' do
mentioner = noteable . dup
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_disallowed? ( noteable , mentioner ) )
. to be_truthy
2015-06-14 15:41:11 +00:00
end
end
2015-05-11 03:51:49 +00:00
end
2015-05-01 03:16:19 +00:00
describe '.cross_reference_exists?' do
let ( :commit0 ) { project . commit }
let ( :commit1 ) { project . commit ( 'HEAD~2' ) }
context 'issue from commit' do
before do
# Mention issue (noteable) from commit0
described_class . cross_reference ( noteable , commit0 , author )
end
it 'is truthy when already mentioned' do
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_exists? ( noteable , commit0 ) )
. to be_truthy
2015-05-01 03:16:19 +00:00
end
it 'is falsey when not already mentioned' do
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_exists? ( noteable , commit1 ) )
. to be_falsey
2015-05-01 03:16:19 +00:00
end
2016-11-23 06:55:23 +00:00
context 'legacy capitalized cross reference' do
before do
# Mention issue (noteable) from commit0
system_note = described_class . cross_reference ( noteable , commit0 , author )
system_note . update ( note : system_note . note . capitalize )
end
it 'is truthy when already mentioned' do
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_exists? ( noteable , commit0 ) )
. to be_truthy
2016-11-23 06:55:23 +00:00
end
end
2015-05-01 03:16:19 +00:00
end
context 'commit from commit' do
before do
# Mention commit1 from commit0
described_class . cross_reference ( commit0 , commit1 , author )
end
it 'is truthy when already mentioned' do
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_exists? ( commit0 , commit1 ) )
. to be_truthy
2015-05-01 03:16:19 +00:00
end
it 'is falsey when not already mentioned' do
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_exists? ( commit1 , commit0 ) )
. to be_falsey
2015-05-01 03:16:19 +00:00
end
2016-11-23 06:55:23 +00:00
context 'legacy capitalized cross reference' do
before do
# Mention commit1 from commit0
system_note = described_class . cross_reference ( commit0 , commit1 , author )
system_note . update ( note : system_note . note . capitalize )
end
it 'is truthy when already mentioned' do
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_exists? ( commit0 , commit1 ) )
. to be_truthy
2016-11-23 06:55:23 +00:00
end
end
2015-05-01 03:16:19 +00:00
end
2016-02-04 17:36:16 +00:00
2016-02-12 17:01:47 +00:00
context 'commit with cross-reference from fork' do
2016-09-19 18:28:41 +00:00
let ( :author2 ) { create ( :project_member , :reporter , user : create ( :user ) , project : project ) . user }
2016-02-04 17:36:16 +00:00
let ( :forked_project ) { Projects :: ForkService . new ( project , author2 ) . execute }
let ( :commit2 ) { forked_project . commit }
before do
2016-02-12 17:01:47 +00:00
described_class . cross_reference ( noteable , commit0 , author2 )
2016-02-04 17:36:16 +00:00
end
2016-02-12 17:01:47 +00:00
it 'is true when a fork mentions an external issue' do
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_exists? ( noteable , commit2 ) )
. to be true
2016-02-04 17:36:16 +00:00
end
2016-11-23 06:55:23 +00:00
context 'legacy capitalized cross reference' do
before do
system_note = described_class . cross_reference ( noteable , commit0 , author2 )
system_note . update ( note : system_note . note . capitalize )
end
it 'is true when a fork mentions an external issue' do
2017-06-21 13:48:12 +00:00
expect ( described_class . cross_reference_exists? ( noteable , commit2 ) )
. to be true
2016-11-23 06:55:23 +00:00
end
end
2016-02-04 17:36:16 +00:00
end
2015-05-01 03:16:19 +00:00
end
2015-12-17 22:08:14 +00:00
2016-02-16 10:47:00 +00:00
describe '.noteable_moved' do
2017-08-02 19:55:11 +00:00
let ( :new_project ) { create ( :project ) }
2016-02-16 10:47:00 +00:00
let ( :new_noteable ) { create ( :issue , project : new_project ) }
2016-02-15 14:14:57 +00:00
subject do
2016-03-16 09:24:44 +00:00
described_class . noteable_moved ( noteable , project , new_noteable , author , direction : direction )
2016-02-15 14:14:57 +00:00
end
2016-02-16 10:47:00 +00:00
shared_examples 'cross project mentionable' do
2017-04-03 09:55:15 +00:00
include MarkupHelper
2016-02-16 10:47:00 +00:00
2016-08-01 15:00:44 +00:00
it 'contains cross reference to new noteable' do
2016-02-16 10:47:00 +00:00
expect ( subject . note ) . to include cross_project_reference ( new_project , new_noteable )
end
2016-08-01 15:00:44 +00:00
it 'mentions referenced noteable' do
2016-02-16 10:47:00 +00:00
expect ( subject . note ) . to include new_noteable . to_reference
end
2016-08-01 15:00:44 +00:00
it 'mentions referenced project' do
2017-07-20 09:34:09 +00:00
expect ( subject . note ) . to include new_project . full_path
2016-02-16 10:47:00 +00:00
end
end
context 'moved to' do
let ( :direction ) { :to }
it_behaves_like 'cross project mentionable'
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'moved' }
end
2016-02-15 14:14:57 +00:00
2016-08-01 15:00:44 +00:00
it 'notifies about noteable being moved to' do
2017-03-27 21:14:01 +00:00
expect ( subject . note ) . to match ( 'moved to' )
2016-02-16 10:47:00 +00:00
end
2016-02-15 14:14:57 +00:00
end
2016-02-16 10:47:00 +00:00
context 'moved from' do
let ( :direction ) { :from }
it_behaves_like 'cross project mentionable'
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'moved' }
end
2016-02-16 10:47:00 +00:00
2016-08-01 15:00:44 +00:00
it 'notifies about noteable being moved from' do
2017-03-27 21:14:01 +00:00
expect ( subject . note ) . to match ( 'moved from' )
2016-02-16 10:47:00 +00:00
end
2016-02-15 14:14:57 +00:00
end
2016-02-16 10:47:00 +00:00
context 'invalid direction' do
2016-02-17 14:59:25 +00:00
let ( :direction ) { :invalid }
2016-02-16 10:47:00 +00:00
2016-08-01 15:00:44 +00:00
it 'raises error' do
2016-02-16 10:47:00 +00:00
expect { subject } . to raise_error StandardError , / Invalid direction /
end
2016-02-15 14:14:57 +00:00
end
end
2016-05-07 15:41:10 +00:00
describe '.new_commit_summary' do
it 'escapes HTML titles' do
commit = double ( title : '<pre>This is a test</pre>' , short_id : '12345678' )
2018-02-02 19:16:10 +00:00
escaped = '<pre>This is a test</pre>'
2017-11-14 16:48:40 +00:00
2018-01-27 05:35:53 +00:00
expect ( described_class . new_commit_summary ( [ commit ] ) ) . to all ( match ( / - #{ escaped } / ) )
2016-05-07 15:41:10 +00:00
end
end
2015-12-17 22:08:14 +00:00
describe 'JIRA integration' do
2017-03-27 21:14:01 +00:00
include JiraServiceHelper
2017-08-02 19:55:11 +00:00
let ( :project ) { create ( :jira_project , :repository ) }
2016-09-29 21:11:32 +00:00
let ( :author ) { create ( :user ) }
let ( :issue ) { create ( :issue , project : project ) }
2017-03-27 21:14:01 +00:00
let ( :merge_request ) { create ( :merge_request , :simple , target_project : project , source_project : project ) }
2016-09-29 21:11:32 +00:00
let ( :jira_issue ) { ExternalIssue . new ( " JIRA-1 " , project ) }
let ( :jira_tracker ) { project . jira_service }
let ( :commit ) { project . commit }
let ( :comment_url ) { jira_api_comment_url ( jira_issue . id ) }
let ( :success_message ) { " JiraService SUCCESS: Successfully posted to http://jira.example.net. " }
2016-11-17 20:46:31 +00:00
before do
stub_jira_urls ( jira_issue . id )
jira_service_settings
end
2015-12-17 22:08:14 +00:00
2017-05-18 06:07:48 +00:00
def cross_reference ( type , link_exists = false )
noteable = type == 'commit' ? commit : merge_request
links = [ ]
if link_exists
url = if type == 'commit'
" #{ Settings . gitlab . base_url } / #{ project . namespace . path } / #{ project . path } /commit/ #{ commit . id } "
else
" #{ Settings . gitlab . base_url } / #{ project . namespace . path } / #{ project . path } /merge_requests/ #{ merge_request . iid } "
end
2018-01-11 16:34:01 +00:00
2017-05-18 06:07:48 +00:00
link = double ( object : { 'url' = > url } )
links << link
expect ( link ) . to receive ( :save! )
end
allow ( JIRA :: Resource :: Remotelink ) . to receive ( :all ) . and_return ( links )
described_class . cross_reference ( jira_issue , noteable , author )
end
2017-02-22 17:46:57 +00:00
noteable_types = %w( merge_requests commit )
2016-11-14 21:30:01 +00:00
noteable_types . each do | type |
context " when noteable is a #{ type } " do
it " blocks cross reference when #{ type . underscore } _events is false " do
jira_tracker . update ( " #{ type } _events " = > false )
2017-05-18 06:07:48 +00:00
expect ( cross_reference ( type ) ) . to eq ( " Events for #{ type . pluralize . humanize . downcase } are disabled. " )
2016-11-14 21:30:01 +00:00
end
2018-03-16 19:09:35 +00:00
it " creates cross reference when #{ type . underscore } _events is true " do
2016-11-14 21:30:01 +00:00
jira_tracker . update ( " #{ type } _events " = > true )
2017-05-18 06:07:48 +00:00
expect ( cross_reference ( type ) ) . to eq ( success_message )
end
end
context 'when a new cross reference is created' do
it 'creates a new comment and remote link' do
cross_reference ( type )
2015-12-17 22:08:14 +00:00
2017-05-18 06:07:48 +00:00
expect ( WebMock ) . to have_requested ( :post , jira_api_comment_url ( jira_issue ) )
expect ( WebMock ) . to have_requested ( :post , jira_api_remote_link_url ( jira_issue ) )
end
end
context 'when a link exists' do
it 'updates a link but does not create a new comment' do
expect ( WebMock ) . not_to have_requested ( :post , jira_api_comment_url ( jira_issue ) )
cross_reference ( type , true )
2016-11-14 21:30:01 +00:00
end
end
end
2015-12-17 22:08:14 +00:00
2016-11-17 20:46:31 +00:00
describe " new reference " do
2018-05-22 16:37:35 +00:00
let ( :favicon_path ) { " http://localhost/assets/ #{ find_asset ( 'favicon.png' ) . digest_path } " }
2018-04-13 20:30:08 +00:00
2017-05-18 06:07:48 +00:00
before do
allow ( JIRA :: Resource :: Remotelink ) . to receive ( :all ) . and_return ( [ ] )
end
2016-11-17 20:46:31 +00:00
context 'for commits' do
it " creates comment " do
result = described_class . cross_reference ( jira_issue , commit , author )
2015-12-17 22:08:14 +00:00
2016-11-17 20:46:31 +00:00
expect ( result ) . to eq ( success_message )
end
2016-11-09 21:55:21 +00:00
it " creates remote link " do
2016-11-17 20:46:31 +00:00
described_class . cross_reference ( jira_issue , commit , author )
2016-11-09 21:55:21 +00:00
expect ( WebMock ) . to have_requested ( :post , jira_api_remote_link_url ( jira_issue ) ) . with (
body : hash_including (
GlobalID : " GitLab " ,
object : {
2017-06-29 17:06:35 +00:00
url : project_commit_url ( project , commit ) ,
2016-11-09 21:55:21 +00:00
title : " GitLab: Mentioned on commit - #{ commit . title } " ,
2018-04-13 20:30:08 +00:00
icon : { title : " GitLab " , url16x16 : favicon_path } ,
2016-11-09 21:55:21 +00:00
status : { resolved : false }
}
)
) . once
end
2015-12-17 22:08:14 +00:00
end
2016-11-17 20:46:31 +00:00
context 'for issues' do
let ( :issue ) { create ( :issue , project : project ) }
2015-12-17 22:08:14 +00:00
2016-11-17 20:46:31 +00:00
it " creates comment " do
result = described_class . cross_reference ( jira_issue , issue , author )
2015-12-17 22:08:14 +00:00
2016-11-17 20:46:31 +00:00
expect ( result ) . to eq ( success_message )
end
2016-11-09 21:55:21 +00:00
it " creates remote link " do
2016-11-17 20:46:31 +00:00
described_class . cross_reference ( jira_issue , issue , author )
2016-11-09 21:55:21 +00:00
expect ( WebMock ) . to have_requested ( :post , jira_api_remote_link_url ( jira_issue ) ) . with (
body : hash_including (
GlobalID : " GitLab " ,
object : {
2017-06-29 17:06:35 +00:00
url : project_issue_url ( project , issue ) ,
2016-11-09 21:55:21 +00:00
title : " GitLab: Mentioned on issue - #{ issue . title } " ,
2018-04-13 20:30:08 +00:00
icon : { title : " GitLab " , url16x16 : favicon_path } ,
2016-11-09 21:55:21 +00:00
status : { resolved : false }
}
)
) . once
end
2016-09-29 21:11:32 +00:00
end
2016-11-17 20:46:31 +00:00
context 'for snippets' do
let ( :snippet ) { create ( :snippet , project : project ) }
it " creates comment " do
result = described_class . cross_reference ( jira_issue , snippet , author )
expect ( result ) . to eq ( success_message )
end
it " creates remote link " do
described_class . cross_reference ( jira_issue , snippet , author )
expect ( WebMock ) . to have_requested ( :post , jira_api_remote_link_url ( jira_issue ) ) . with (
body : hash_including (
GlobalID : " GitLab " ,
object : {
2017-06-29 17:06:35 +00:00
url : project_snippet_url ( project , snippet ) ,
2016-11-17 20:46:31 +00:00
title : " GitLab: Mentioned on snippet - #{ snippet . title } " ,
2018-04-13 20:30:08 +00:00
icon : { title : " GitLab " , url16x16 : favicon_path } ,
2016-11-17 20:46:31 +00:00
status : { resolved : false }
}
)
) . once
end
end
2016-09-29 21:11:32 +00:00
end
describe " existing reference " do
before do
2017-05-18 06:07:48 +00:00
allow ( JIRA :: Resource :: Remotelink ) . to receive ( :all ) . and_return ( [ ] )
2017-07-22 00:37:22 +00:00
message = " [ #{ author . name } |http://localhost/ #{ author . username } ] mentioned this issue in [a commit of #{ project . full_path } |http://localhost/ #{ project . full_path } /commit/ #{ commit . id } ]: \n ' #{ commit . title . chomp } ' "
2016-09-29 21:11:32 +00:00
allow_any_instance_of ( JIRA :: Resource :: Issue ) . to receive ( :comments ) . and_return ( [ OpenStruct . new ( body : message ) ] )
2015-12-17 22:08:14 +00:00
end
2016-09-29 21:11:32 +00:00
2016-11-17 20:46:31 +00:00
it " does not return success message " do
result = described_class . cross_reference ( jira_issue , commit , author )
2016-09-29 21:11:32 +00:00
2016-11-17 20:46:31 +00:00
expect ( result ) . not_to eq ( success_message )
end
2016-11-09 21:55:21 +00:00
it 'does not try to create comment and remote link' do
subject
expect ( WebMock ) . not_to have_requested ( :post , jira_api_comment_url ( jira_issue ) )
expect ( WebMock ) . not_to have_requested ( :post , jira_api_remote_link_url ( jira_issue ) )
end
2015-12-17 22:08:14 +00:00
end
end
2016-10-26 21:21:50 +00:00
describe '.discussion_continued_in_issue' do
2017-08-30 10:54:23 +00:00
let ( :discussion ) { create ( :diff_note_on_merge_request , project : project ) . to_discussion }
2016-10-26 21:21:50 +00:00
let ( :merge_request ) { discussion . noteable }
let ( :issue ) { create ( :issue , project : project ) }
def reloaded_merge_request
MergeRequest . find ( merge_request . id )
end
2017-03-15 13:19:45 +00:00
subject { described_class . discussion_continued_in_issue ( discussion , project , author , issue ) }
it_behaves_like 'a system note' do
let ( :expected_noteable ) { discussion . first_note . noteable }
let ( :action ) { 'discussion' }
2016-10-26 21:21:50 +00:00
end
it 'creates a new note in the discussion' do
# we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded.
2017-03-15 13:19:45 +00:00
expect { subject } . to change { reloaded_merge_request . discussions . first . notes . size } . by ( 1 )
2016-10-26 21:21:50 +00:00
end
it 'mentions the created issue in the system note' do
2017-03-15 13:19:45 +00:00
expect ( subject . note ) . to include ( issue . to_reference )
2016-10-26 21:21:50 +00:00
end
end
2016-12-23 05:44:02 +00:00
describe '.change_time_estimate' do
subject { described_class . change_time_estimate ( noteable , project , author ) }
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'time_tracking' }
end
2016-12-23 05:44:02 +00:00
context 'with a time estimate' do
it 'sets the note text' do
noteable . update_attribute ( :time_estimate , 277200 )
2018-04-25 20:56:06 +00:00
expect ( subject . note ) . to eq " changed time estimate to 1w 4d 5h "
2016-12-23 05:44:02 +00:00
end
end
context 'without a time estimate' do
it 'sets the note text' do
2017-02-03 16:57:44 +00:00
expect ( subject . note ) . to eq " removed time estimate "
2016-12-23 05:44:02 +00:00
end
end
end
describe '.change_time_spent' do
# We need a custom noteable in order to the shared examples to be green.
let ( :noteable ) do
mr = create ( :merge_request , source_project : project )
2017-12-14 19:32:55 +00:00
mr . spend_time ( duration : 360000 , user_id : author . id )
2016-12-23 05:44:02 +00:00
mr . save!
mr
end
subject do
described_class . change_time_spent ( noteable , project , author )
end
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'time_tracking' }
end
2016-12-23 05:44:02 +00:00
context 'when time was added' do
it 'sets the note text' do
spend_time! ( 277200 )
2017-02-03 16:57:44 +00:00
expect ( subject . note ) . to eq " added 1w 4d 5h of time spent "
2016-12-23 05:44:02 +00:00
end
end
context 'when time was subtracted' do
it 'sets the note text' do
spend_time! ( - 277200 )
2017-02-03 16:57:44 +00:00
expect ( subject . note ) . to eq " subtracted 1w 4d 5h of time spent "
2016-12-23 05:44:02 +00:00
end
end
context 'when time was removed' do
it 'sets the note text' do
spend_time! ( :reset )
2017-02-03 16:57:44 +00:00
expect ( subject . note ) . to eq " removed time spent "
2016-12-23 05:44:02 +00:00
end
end
def spend_time! ( seconds )
2017-12-14 19:32:55 +00:00
noteable . spend_time ( duration : seconds , user_id : author . id )
2016-12-23 05:44:02 +00:00
noteable . save!
end
end
2016-12-15 20:48:26 +00:00
2017-11-21 19:25:37 +00:00
describe '.handle_merge_request_wip' do
context 'adding wip note' do
let ( :noteable ) { create ( :merge_request , source_project : project , title : 'WIP Lorem ipsum' ) }
2017-03-15 13:19:45 +00:00
2017-11-21 19:25:37 +00:00
subject { described_class . handle_merge_request_wip ( noteable , project , author ) }
2017-03-15 13:19:45 +00:00
2017-11-21 19:25:37 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'title' }
end
2017-03-15 13:19:45 +00:00
2017-11-21 19:25:37 +00:00
it 'sets the note text' do
expect ( subject . note ) . to eq 'marked as a **Work In Progress**'
end
2017-03-15 13:19:45 +00:00
end
2017-11-21 19:25:37 +00:00
context 'removing wip note' do
let ( :noteable ) { create ( :merge_request , source_project : project , title : 'Lorem ipsum' ) }
2017-03-15 13:19:45 +00:00
2017-11-21 19:25:37 +00:00
subject { described_class . handle_merge_request_wip ( noteable , project , author ) }
2017-03-15 13:19:45 +00:00
2017-11-21 19:25:37 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'title' }
end
2017-03-15 13:19:45 +00:00
2017-11-21 19:25:37 +00:00
it 'sets the note text' do
expect ( subject . note ) . to eq 'unmarked as a **Work In Progress**'
end
2017-03-15 13:19:45 +00:00
end
end
2016-12-15 20:48:26 +00:00
describe '.add_merge_request_wip_from_commit' do
let ( :noteable ) do
create ( :merge_request , source_project : project , target_project : project )
end
subject do
described_class . add_merge_request_wip_from_commit (
noteable ,
project ,
author ,
noteable . diff_head_commit
)
end
2017-03-15 13:19:45 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'title' }
end
2016-12-15 20:48:26 +00:00
it " posts the 'marked as a Work In Progress from commit' system note " do
expect ( subject . note ) . to match (
/ marked as a \ * \ *Work In Progress \ * \ * from #{ Commit . reference_pattern } /
)
end
end
2017-03-15 13:19:45 +00:00
describe '.change_task_status' do
let ( :noteable ) { create ( :issue , project : project ) }
let ( :task ) { double ( :task , complete? : true , source : 'task' ) }
subject { described_class . change_task_status ( noteable , project , author , task ) }
it_behaves_like 'a system note' do
let ( :action ) { 'task' }
end
2017-06-08 17:53:38 +00:00
it " posts the 'marked the task as complete' system note " do
2017-03-15 13:19:45 +00:00
expect ( subject . note ) . to eq ( " marked the task **task** as completed " )
end
end
describe '.resolve_all_discussions' do
let ( :noteable ) { create ( :merge_request , source_project : project , target_project : project ) }
subject { described_class . resolve_all_discussions ( noteable , project , author ) }
it_behaves_like 'a system note' do
let ( :action ) { 'discussion' }
end
it 'sets the note text' do
expect ( subject . note ) . to eq 'resolved all discussions'
end
end
2017-05-21 20:38:33 +00:00
describe '.diff_discussion_outdated' do
2017-08-30 10:54:23 +00:00
let ( :discussion ) { create ( :diff_note_on_merge_request , project : project ) . to_discussion }
2017-05-21 20:38:33 +00:00
let ( :merge_request ) { discussion . noteable }
let ( :change_position ) { discussion . position }
def reloaded_merge_request
MergeRequest . find ( merge_request . id )
end
subject { described_class . diff_discussion_outdated ( discussion , project , author , change_position ) }
it_behaves_like 'a system note' do
let ( :expected_noteable ) { discussion . first_note . noteable }
2017-05-24 15:10:10 +00:00
let ( :action ) { 'outdated' }
2017-05-21 20:38:33 +00:00
end
2017-12-28 11:17:31 +00:00
context 'when the change_position is valid for the discussion' do
it 'creates a new note in the discussion' do
# we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded.
expect { subject } . to change { reloaded_merge_request . discussions . first . notes . size } . by ( 1 )
end
it 'links to the diff in the system note' do
expect ( subject . note ) . to include ( 'version 1' )
diff_id = merge_request . merge_request_diff . id
line_code = change_position . line_code ( project . repository )
expect ( subject . note ) . to include ( diffs_project_merge_request_url ( project , merge_request , diff_id : diff_id , anchor : line_code ) )
end
2017-05-21 20:38:33 +00:00
end
2017-12-28 11:17:31 +00:00
context 'when the change_position is invalid for the discussion' do
let ( :change_position ) { project . commit ( sample_commit . id ) }
2017-05-21 20:38:33 +00:00
2017-12-28 11:17:31 +00:00
it 'creates a new note in the discussion' do
# we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded.
expect { subject } . to change { reloaded_merge_request . discussions . first . notes . size } . by ( 1 )
end
it 'does not create a link' do
expect ( subject . note ) . to eq ( 'changed this line in version 1 of the diff' )
end
2017-05-21 20:38:33 +00:00
end
end
2017-03-30 01:39:06 +00:00
describe '.mark_duplicate_issue' do
2017-07-20 14:42:33 +00:00
subject { described_class . mark_duplicate_issue ( noteable , project , author , canonical_issue ) }
2017-03-30 01:39:06 +00:00
context 'within the same project' do
2017-07-20 14:42:33 +00:00
let ( :canonical_issue ) { create ( :issue , project : project ) }
2017-03-30 01:39:06 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'duplicate' }
end
2017-07-20 14:42:33 +00:00
it { expect ( subject . note ) . to eq " marked this issue as a duplicate of #{ canonical_issue . to_reference } " }
2017-03-30 01:39:06 +00:00
end
context 'across different projects' do
2017-08-02 19:55:11 +00:00
let ( :other_project ) { create ( :project ) }
2017-07-20 14:42:33 +00:00
let ( :canonical_issue ) { create ( :issue , project : other_project ) }
2017-03-30 01:39:06 +00:00
it_behaves_like 'a system note' do
let ( :action ) { 'duplicate' }
end
2017-07-20 14:42:33 +00:00
it { expect ( subject . note ) . to eq " marked this issue as a duplicate of #{ canonical_issue . to_reference ( project ) } " }
end
end
describe '.mark_canonical_issue_of_duplicate' do
subject { described_class . mark_canonical_issue_of_duplicate ( noteable , project , author , duplicate_issue ) }
context 'within the same project' do
let ( :duplicate_issue ) { create ( :issue , project : project ) }
it_behaves_like 'a system note' do
let ( :action ) { 'duplicate' }
end
it { expect ( subject . note ) . to eq " marked #{ duplicate_issue . to_reference } as a duplicate of this issue " }
end
context 'across different projects' do
2017-08-02 19:55:11 +00:00
let ( :other_project ) { create ( :project ) }
2017-07-20 14:42:33 +00:00
let ( :duplicate_issue ) { create ( :issue , project : other_project ) }
it_behaves_like 'a system note' do
let ( :action ) { 'duplicate' }
end
it { expect ( subject . note ) . to eq " marked #{ duplicate_issue . to_reference ( project ) } as a duplicate of this issue " }
2017-03-30 01:39:06 +00:00
end
end
2017-10-10 06:35:31 +00:00
describe '.discussion_lock' do
subject { described_class . discussion_lock ( noteable , author ) }
context 'discussion unlocked' do
it_behaves_like 'a system note' do
let ( :action ) { 'unlocked' }
end
it 'creates the note text correctly' do
[ :issue , :merge_request ] . each do | type |
issuable = create ( type )
expect ( described_class . discussion_lock ( issuable , author ) . note )
. to eq ( " unlocked this #{ type . to_s . titleize . downcase } " )
end
end
end
context 'discussion locked' do
before do
noteable . update_attribute ( :discussion_locked , true )
end
it_behaves_like 'a system note' do
let ( :action ) { 'locked' }
end
it 'creates the note text correctly' do
[ :issue , :merge_request ] . each do | type |
issuable = create ( type , discussion_locked : true )
expect ( described_class . discussion_lock ( issuable , author ) . note )
. to eq ( " locked this #{ type . to_s . titleize . downcase } " )
end
end
end
end
2015-05-01 03:16:19 +00:00
end