2019-03-30 03:23:56 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2014-10-29 09:46:42 -04:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
RSpec.describe Mentionable do
|
2020-05-19 11:08:04 -04:00
|
|
|
before do
|
|
|
|
stub_const('Example', Class.new)
|
|
|
|
Example.class_eval do
|
|
|
|
include Mentionable
|
2015-12-17 17:08:14 -05:00
|
|
|
|
2020-05-19 11:08:04 -04:00
|
|
|
attr_accessor :project, :message
|
2022-02-28 13:14:03 -05:00
|
|
|
|
2020-05-19 11:08:04 -04:00
|
|
|
attr_mentionable :message
|
2016-09-29 10:28:45 -04:00
|
|
|
|
2020-05-19 11:08:04 -04:00
|
|
|
def author
|
|
|
|
nil
|
|
|
|
end
|
2016-09-29 10:28:45 -04:00
|
|
|
end
|
2015-12-24 14:34:13 -05:00
|
|
|
end
|
|
|
|
|
2016-07-11 18:12:31 -04:00
|
|
|
describe 'references' do
|
2017-08-02 15:55:11 -04:00
|
|
|
let(:project) { create(:project) }
|
2016-09-29 10:28:45 -04:00
|
|
|
let(:mentionable) { Example.new }
|
2015-12-17 17:08:14 -05:00
|
|
|
|
2019-06-28 09:25:56 -04:00
|
|
|
it 'excludes Jira references' do
|
2015-12-17 17:08:14 -05:00
|
|
|
allow(project).to receive_messages(jira_tracker?: true)
|
2016-09-29 10:28:45 -04:00
|
|
|
|
|
|
|
mentionable.project = project
|
|
|
|
mentionable.message = 'JIRA-123'
|
|
|
|
expect(mentionable.referenced_mentionables).to be_empty
|
2015-12-17 17:08:14 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
RSpec.describe Issue, "Mentionable" do
|
2015-06-08 18:13:14 -04:00
|
|
|
describe '#mentioned_users' do
|
2014-10-29 09:46:42 -04:00
|
|
|
let!(:user) { create(:user, username: 'stranger') }
|
|
|
|
let!(:user2) { create(:user, username: 'john') }
|
2017-01-18 18:37:55 -05:00
|
|
|
let!(:user3) { create(:user, username: 'jim') }
|
|
|
|
let(:issue) { create(:issue, description: "#{user.to_reference} mentioned") }
|
2014-10-29 09:46:42 -04:00
|
|
|
|
|
|
|
subject { issue.mentioned_users }
|
|
|
|
|
2017-01-20 05:28:40 -05:00
|
|
|
it { expect(subject).to contain_exactly(user) }
|
2017-01-18 18:37:55 -05:00
|
|
|
|
|
|
|
context 'when a note on personal snippet' do
|
|
|
|
let!(:note) { create(:note_on_personal_snippet, note: "#{user.to_reference} mentioned #{user3.to_reference}") }
|
|
|
|
|
|
|
|
subject { note.mentioned_users }
|
|
|
|
|
2017-01-20 05:28:40 -05:00
|
|
|
it { expect(subject).to contain_exactly(user, user3) }
|
2017-01-18 18:37:55 -05:00
|
|
|
end
|
2014-10-29 09:46:42 -04:00
|
|
|
end
|
2015-06-08 18:13:14 -04:00
|
|
|
|
2016-06-27 08:24:08 -04:00
|
|
|
describe '#referenced_mentionables' do
|
|
|
|
context 'with an issue on a private project' do
|
2017-08-02 15:55:11 -04:00
|
|
|
let(:project) { create(:project, :public) }
|
2016-06-27 08:24:08 -04:00
|
|
|
let(:issue) { create(:issue, project: project) }
|
|
|
|
let(:public_issue) { create(:issue, project: project) }
|
2017-08-02 15:55:11 -04:00
|
|
|
let(:private_project) { create(:project, :private) }
|
2016-06-27 08:24:08 -04:00
|
|
|
let(:private_issue) { create(:issue, project: private_project) }
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
|
|
|
def referenced_issues(current_user)
|
2016-09-29 10:28:45 -04:00
|
|
|
issue.title = "#{private_issue.to_reference(project)} and #{public_issue.to_reference}"
|
|
|
|
issue.referenced_mentionables(current_user)
|
2016-06-27 08:24:08 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the current user can see the issue' do
|
2017-06-14 14:18:56 -04:00
|
|
|
before do
|
2017-12-22 03:18:28 -05:00
|
|
|
private_project.add_developer(user)
|
2017-06-14 14:18:56 -04:00
|
|
|
end
|
2016-06-27 08:24:08 -04:00
|
|
|
|
|
|
|
it 'includes the reference' do
|
|
|
|
expect(referenced_issues(user)).to contain_exactly(private_issue, public_issue)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the current user cannot see the issue' do
|
|
|
|
it 'does not include the reference' do
|
|
|
|
expect(referenced_issues(user)).to contain_exactly(public_issue)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when there is no current user' do
|
|
|
|
it 'does not include the reference' do
|
|
|
|
expect(referenced_issues(nil)).to contain_exactly(public_issue)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-06-08 18:13:14 -04:00
|
|
|
describe '#create_cross_references!' do
|
2017-01-26 17:44:58 -05:00
|
|
|
let(:project) { create(:project, :repository) }
|
2016-07-20 14:13:02 -04:00
|
|
|
let(:author) { build(:user) }
|
2015-06-08 18:13:14 -04:00
|
|
|
let(:commit) { project.commit }
|
|
|
|
let(:commit2) { project.commit }
|
|
|
|
|
|
|
|
let!(:issue) do
|
2017-01-26 17:44:58 -05:00
|
|
|
create(:issue, project: project, description: "See #{commit.to_reference}")
|
2015-06-08 18:13:14 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'correctly removes already-mentioned Commits' do
|
2015-06-17 20:59:19 -04:00
|
|
|
expect(SystemNoteService).not_to receive(:cross_reference)
|
2015-06-08 18:13:14 -04:00
|
|
|
|
2015-10-12 05:54:46 -04:00
|
|
|
issue.create_cross_references!(author, [commit2])
|
2015-06-08 18:13:14 -04:00
|
|
|
end
|
|
|
|
end
|
2015-07-13 18:28:10 -04:00
|
|
|
|
2015-07-13 18:33:50 -04:00
|
|
|
describe '#create_new_cross_references!' do
|
2017-08-02 15:55:11 -04:00
|
|
|
let(:project) { create(:project) }
|
2016-03-17 16:39:50 -04:00
|
|
|
let(:author) { create(:author) }
|
|
|
|
let(:issues) { create_list(:issue, 2, project: project, author: author) }
|
2015-07-13 18:28:10 -04:00
|
|
|
|
2016-07-20 14:13:02 -04:00
|
|
|
before do
|
2017-12-22 03:18:28 -05:00
|
|
|
project.add_developer(author)
|
2016-07-20 14:13:02 -04:00
|
|
|
end
|
|
|
|
|
2015-07-13 18:28:10 -04:00
|
|
|
context 'before changes are persisted' do
|
|
|
|
it 'ignores pre-existing references' do
|
|
|
|
issue = create_issue(description: issues[0].to_reference)
|
|
|
|
|
|
|
|
expect(SystemNoteService).not_to receive(:cross_reference)
|
|
|
|
|
|
|
|
issue.description = 'New description'
|
2015-07-13 18:33:50 -04:00
|
|
|
issue.create_new_cross_references!
|
2015-07-13 18:28:10 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'notifies new references' do
|
|
|
|
issue = create_issue(description: issues[0].to_reference)
|
|
|
|
|
|
|
|
expect(SystemNoteService).to receive(:cross_reference).with(issues[1], any_args)
|
|
|
|
|
|
|
|
issue.description = issues[1].to_reference
|
2015-07-13 18:33:50 -04:00
|
|
|
issue.create_new_cross_references!
|
2015-07-13 18:28:10 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'after changes are persisted' do
|
|
|
|
it 'ignores pre-existing references' do
|
|
|
|
issue = create_issue(description: issues[0].to_reference)
|
|
|
|
|
|
|
|
expect(SystemNoteService).not_to receive(:cross_reference)
|
|
|
|
|
2020-09-22 14:09:54 -04:00
|
|
|
issue.update!(description: 'New description')
|
2015-07-13 18:33:50 -04:00
|
|
|
issue.create_new_cross_references!
|
2015-07-13 18:28:10 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'notifies new references' do
|
|
|
|
issue = create_issue(description: issues[0].to_reference)
|
|
|
|
|
|
|
|
expect(SystemNoteService).to receive(:cross_reference).with(issues[1], any_args)
|
|
|
|
|
2020-09-22 14:09:54 -04:00
|
|
|
issue.update!(description: issues[1].to_reference)
|
2015-07-13 18:33:50 -04:00
|
|
|
issue.create_new_cross_references!
|
2015-07-13 18:28:10 -04:00
|
|
|
end
|
2017-01-05 08:36:06 -05:00
|
|
|
|
|
|
|
it 'notifies new references from project snippet note' do
|
|
|
|
snippet = create(:snippet, project: project)
|
|
|
|
note = create(:note, note: issues[0].to_reference, noteable: snippet, project: project, author: author)
|
|
|
|
|
|
|
|
expect(SystemNoteService).to receive(:cross_reference).with(issues[1], any_args)
|
|
|
|
|
2020-09-22 14:09:54 -04:00
|
|
|
note.update!(note: issues[1].to_reference)
|
2017-01-05 08:36:06 -05:00
|
|
|
note.create_new_cross_references!
|
|
|
|
end
|
2015-07-13 18:28:10 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def create_issue(description:)
|
2016-03-17 16:39:50 -04:00
|
|
|
create(:issue, project: project, description: description, author: author)
|
2015-07-13 18:28:10 -04:00
|
|
|
end
|
|
|
|
end
|
2019-12-10 10:07:52 -05:00
|
|
|
|
|
|
|
describe '#store_mentions!' do
|
|
|
|
it_behaves_like 'mentions in description', :issue
|
|
|
|
it_behaves_like 'mentions in notes', :issue do
|
|
|
|
let(:note) { create(:note_on_issue) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'load mentions' do
|
|
|
|
it_behaves_like 'load mentions from DB', :issue do
|
|
|
|
let(:note) { create(:note_on_issue) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
2014-10-29 09:46:42 -04:00
|
|
|
end
|
2017-04-21 22:26:58 -04:00
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
RSpec.describe Commit, 'Mentionable' do
|
2017-04-21 22:26:58 -04:00
|
|
|
let(:project) { create(:project, :public, :repository) }
|
|
|
|
let(:commit) { project.commit }
|
|
|
|
|
|
|
|
describe '#matches_cross_reference_regex?' do
|
|
|
|
it "is false when message doesn't reference anything" do
|
|
|
|
allow(commit.raw).to receive(:message).and_return "WIP: Do something"
|
|
|
|
|
2017-07-10 03:38:42 -04:00
|
|
|
expect(commit.matches_cross_reference_regex?).to be_falsey
|
2017-04-21 22:26:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'is true if issue #number mentioned in title' do
|
|
|
|
allow(commit.raw).to receive(:message).and_return "#1"
|
|
|
|
|
2017-07-10 03:38:42 -04:00
|
|
|
expect(commit.matches_cross_reference_regex?).to be_truthy
|
2017-04-21 22:26:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'is true if references an MR' do
|
|
|
|
allow(commit.raw).to receive(:message).and_return "See merge request !12"
|
|
|
|
|
2017-07-10 03:38:42 -04:00
|
|
|
expect(commit.matches_cross_reference_regex?).to be_truthy
|
2017-04-21 22:26:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'is true if references a commit' do
|
|
|
|
allow(commit.raw).to receive(:message).and_return "a1b2c3d4"
|
|
|
|
|
2017-07-10 03:38:42 -04:00
|
|
|
expect(commit.matches_cross_reference_regex?).to be_truthy
|
2017-04-21 22:26:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'is true if issue referenced by url' do
|
|
|
|
issue = create(:issue, project: project)
|
|
|
|
|
|
|
|
allow(commit.raw).to receive(:message).and_return Gitlab::UrlBuilder.build(issue)
|
|
|
|
|
2017-07-10 03:38:42 -04:00
|
|
|
expect(commit.matches_cross_reference_regex?).to be_truthy
|
2017-04-21 22:26:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'with external issue tracker' do
|
2017-08-02 15:55:11 -04:00
|
|
|
let(:project) { create(:jira_project, :repository) }
|
2017-04-21 22:26:58 -04:00
|
|
|
|
|
|
|
it 'is true if external issues referenced' do
|
|
|
|
allow(commit.raw).to receive(:message).and_return 'JIRA-123'
|
|
|
|
|
2017-07-10 03:38:42 -04:00
|
|
|
expect(commit.matches_cross_reference_regex?).to be_truthy
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is true if internal issues referenced' do
|
|
|
|
allow(commit.raw).to receive(:message).and_return '#123'
|
|
|
|
|
|
|
|
expect(commit.matches_cross_reference_regex?).to be_truthy
|
2017-04-21 22:26:58 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-12-10 10:07:52 -05:00
|
|
|
|
|
|
|
describe '#store_mentions!' do
|
|
|
|
it_behaves_like 'mentions in notes', :commit do
|
|
|
|
let(:note) { create(:note_on_commit) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'load mentions' do
|
|
|
|
it_behaves_like 'load mentions from DB', :commit do
|
|
|
|
let(:note) { create(:note_on_commit) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
RSpec.describe MergeRequest, 'Mentionable' do
|
2019-12-10 10:07:52 -05:00
|
|
|
describe '#store_mentions!' do
|
|
|
|
it_behaves_like 'mentions in description', :merge_request
|
|
|
|
it_behaves_like 'mentions in notes', :merge_request do
|
|
|
|
let(:project) { create(:project) }
|
|
|
|
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
|
|
|
|
let(:note) { create(:note_on_merge_request, noteable: merge_request, project: merge_request.project) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'load mentions' do
|
|
|
|
it_behaves_like 'load mentions from DB', :merge_request do
|
|
|
|
let(:project) { create(:project) }
|
|
|
|
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
|
|
|
|
let(:note) { create(:note_on_merge_request, noteable: merge_request, project: merge_request.project) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
RSpec.describe Snippet, 'Mentionable' do
|
2019-12-10 10:07:52 -05:00
|
|
|
describe '#store_mentions!' do
|
|
|
|
it_behaves_like 'mentions in description', :project_snippet
|
|
|
|
it_behaves_like 'mentions in notes', :project_snippet do
|
|
|
|
let(:note) { create(:note_on_project_snippet) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'load mentions' do
|
|
|
|
it_behaves_like 'load mentions from DB', :project_snippet do
|
|
|
|
let(:note) { create(:note_on_project_snippet) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
2017-04-21 22:26:58 -04:00
|
|
|
end
|
2020-04-22 08:09:29 -04:00
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
RSpec.describe PersonalSnippet, 'Mentionable' do
|
2020-04-22 08:09:29 -04:00
|
|
|
describe '#store_mentions!' do
|
|
|
|
it_behaves_like 'mentions in description', :personal_snippet
|
|
|
|
it_behaves_like 'mentions in notes', :personal_snippet do
|
|
|
|
let(:note) { create(:note_on_personal_snippet) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'load mentions' do
|
|
|
|
it_behaves_like 'load mentions from DB', :personal_snippet do
|
|
|
|
let(:note) { create(:note_on_personal_snippet) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-05-14 05:07:53 -04:00
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
RSpec.describe DesignManagement::Design do
|
2020-05-14 05:07:53 -04:00
|
|
|
describe '#store_mentions!' do
|
|
|
|
it_behaves_like 'mentions in notes', :design do
|
|
|
|
let(:note) { create(:diff_note_on_design) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'load mentions' do
|
|
|
|
it_behaves_like 'load mentions from DB', :design do
|
|
|
|
let(:note) { create(:diff_note_on_design) }
|
|
|
|
let(:mentionable) { note.noteable }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|