Commit d3236af1 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'issue_24303' into 'master'

Allow JIRA references for project snippets

closes #24303

See merge request !7541
parents 80eaed16 9c740133
# == Mentionable concern # == Mentionable concern
# #
# Contains functionality related to objects that can mention Users, Issues, MergeRequests, or Commits by # Contains functionality related to objects that can mention Users, Issues, MergeRequests, Commits or Snippets by
# GFM references. # GFM references.
# #
# Used by Issue, Note, MergeRequest, and Commit. # Used by Issue, Note, MergeRequest, and Commit.
......
...@@ -128,15 +128,9 @@ class JiraService < IssueTrackerService ...@@ -128,15 +128,9 @@ class JiraService < IssueTrackerService
return unless jira_issue.present? return unless jira_issue.present?
project = self.project noteable_id = noteable.respond_to?(:iid) ? noteable.iid : noteable.id
noteable_name = noteable.model_name.singular noteable_type = noteable_name(noteable)
noteable_id = if noteable.is_a?(Commit) entity_url = build_entity_url(noteable_type, noteable_id)
noteable.id
else
noteable.iid
end
entity_url = build_entity_url(noteable_name.to_sym, noteable_id)
data = { data = {
user: { user: {
...@@ -144,11 +138,11 @@ class JiraService < IssueTrackerService ...@@ -144,11 +138,11 @@ class JiraService < IssueTrackerService
url: resource_url(user_path(author)), url: resource_url(user_path(author)),
}, },
project: { project: {
name: project.path_with_namespace, name: self.project.path_with_namespace,
url: resource_url(namespace_project_path(project.namespace, project)) url: resource_url(namespace_project_path(project.namespace, self.project))
}, },
entity: { entity: {
name: noteable_name.humanize.downcase, name: noteable_type.humanize.downcase,
url: entity_url, url: entity_url,
title: noteable.title title: noteable.title
} }
...@@ -285,18 +279,26 @@ class JiraService < IssueTrackerService ...@@ -285,18 +279,26 @@ class JiraService < IssueTrackerService
"#{Settings.gitlab.base_url.chomp("/")}#{resource}" "#{Settings.gitlab.base_url.chomp("/")}#{resource}"
end end
def build_entity_url(entity_name, entity_id) def build_entity_url(noteable_type, entity_id)
polymorphic_url( polymorphic_url(
[ [
self.project.namespace.becomes(Namespace), self.project.namespace.becomes(Namespace),
self.project, self.project,
entity_name noteable_type.to_sym
], ],
id: entity_id, id: entity_id,
host: Settings.gitlab.base_url host: Settings.gitlab.base_url
) )
end end
def noteable_name(noteable)
name = noteable.model_name.singular
# ProjectSnippet inherits from Snippet class so it causes
# routing error building the URL.
name == "project_snippet" ? "snippet" : name
end
# Handle errors when doing JIRA API calls # Handle errors when doing JIRA API calls
def jira_request def jira_request
yield yield
......
...@@ -6,6 +6,7 @@ class Snippet < ActiveRecord::Base ...@@ -6,6 +6,7 @@ class Snippet < ActiveRecord::Base
include Referable include Referable
include Sortable include Sortable
include Awardable include Awardable
include Mentionable
cache_markdown_field :title, pipeline: :single_line cache_markdown_field :title, pipeline: :single_line
cache_markdown_field :content cache_markdown_field :content
......
---
title: Fix JIRA references for project snippets
merge_request:
author:
...@@ -543,7 +543,10 @@ describe SystemNoteService, services: true do ...@@ -543,7 +543,10 @@ describe SystemNoteService, services: true do
let(:comment_url) { jira_api_comment_url(jira_issue.id) } let(:comment_url) { jira_api_comment_url(jira_issue.id) }
let(:success_message) { "JiraService SUCCESS: Successfully posted to http://jira.example.net." } let(:success_message) { "JiraService SUCCESS: Successfully posted to http://jira.example.net." }
before { stub_jira_urls(jira_issue.id) } before do
stub_jira_urls(jira_issue.id)
jira_service_settings
end
noteable_types = ["merge_requests", "commit"] noteable_types = ["merge_requests", "commit"]
...@@ -569,16 +572,16 @@ describe SystemNoteService, services: true do ...@@ -569,16 +572,16 @@ describe SystemNoteService, services: true do
end end
end end
context 'in JIRA issue tracker' do
before { jira_service_settings }
describe "new reference" do describe "new reference" do
subject { described_class.cross_reference(jira_issue, commit, author) } context 'for commits' do
it "creates comment" do
result = described_class.cross_reference(jira_issue, commit, author)
it { is_expected.to eq(success_message) } expect(result).to eq(success_message)
end
it "creates remote link" do it "creates remote link" do
subject described_class.cross_reference(jira_issue, commit, author)
expect(WebMock).to have_requested(:post, jira_api_remote_link_url(jira_issue)).with( expect(WebMock).to have_requested(:post, jira_api_remote_link_url(jira_issue)).with(
body: hash_including( body: hash_including(
...@@ -593,18 +596,18 @@ describe SystemNoteService, services: true do ...@@ -593,18 +596,18 @@ describe SystemNoteService, services: true do
).once ).once
end end
end end
end
context 'in commit' do context 'for issues' do
context 'in JIRA issue tracker' do let(:issue) { create(:issue, project: project) }
before { jira_service_settings }
subject { described_class.cross_reference(jira_issue, issue, author) } it "creates comment" do
result = described_class.cross_reference(jira_issue, issue, author)
it { is_expected.to eq(success_message) } expect(result).to eq(success_message)
end
it "creates remote link" do it "creates remote link" do
subject described_class.cross_reference(jira_issue, issue, author)
expect(WebMock).to have_requested(:post, jira_api_remote_link_url(jira_issue)).with( expect(WebMock).to have_requested(:post, jira_api_remote_link_url(jira_issue)).with(
body: hash_including( body: hash_including(
...@@ -619,6 +622,32 @@ describe SystemNoteService, services: true do ...@@ -619,6 +622,32 @@ describe SystemNoteService, services: true do
).once ).once
end end
end end
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: {
url: namespace_project_snippet_url(project.namespace, project, snippet),
title: "GitLab: Mentioned on snippet - #{snippet.title}",
icon: { title: "GitLab", url16x16: "https://gitlab.com/favicon.ico" },
status: { resolved: false }
}
)
).once
end
end
end end
describe "existing reference" do describe "existing reference" do
...@@ -627,9 +656,11 @@ describe SystemNoteService, services: true do ...@@ -627,9 +656,11 @@ describe SystemNoteService, services: true do
allow_any_instance_of(JIRA::Resource::Issue).to receive(:comments).and_return([OpenStruct.new(body: message)]) allow_any_instance_of(JIRA::Resource::Issue).to receive(:comments).and_return([OpenStruct.new(body: message)])
end end
subject { described_class.cross_reference(jira_issue, commit, author) } it "does not return success message" do
result = described_class.cross_reference(jira_issue, commit, author)
it { is_expected.not_to eq(success_message) } expect(result).not_to eq(success_message)
end
it 'does not try to create comment and remote link' do it 'does not try to create comment and remote link' do
subject subject
......
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