Commit 9276b10d authored by Sean McGivern's avatar Sean McGivern

Merge branch 'fa-add_jira_specs' into 'master'

Add JIRA service specs to commit object

See merge request gitlab-org/gitlab-ce!21116
parents 638209e1 2125d648
...@@ -27,13 +27,13 @@ describe JiraService do ...@@ -27,13 +27,13 @@ describe JiraService do
end end
end end
describe "Associations" do describe 'Associations' do
it { is_expected.to belong_to :project } it { is_expected.to belong_to :project }
it { is_expected.to have_one :service_hook } it { is_expected.to have_one :service_hook }
it { is_expected.to allow_value(nil).for(:jira_issue_transition_id) } it { is_expected.to allow_value(nil).for(:jira_issue_transition_id) }
it { is_expected.to allow_value("1,2,3").for(:jira_issue_transition_id) } it { is_expected.to allow_value('1,2,3').for(:jira_issue_transition_id) }
it { is_expected.to allow_value("1;2;3").for(:jira_issue_transition_id) } it { is_expected.to allow_value('1;2;3').for(:jira_issue_transition_id) }
it { is_expected.not_to allow_value("a,b,cd").for(:jira_issue_transition_id) } it { is_expected.not_to allow_value('a,b,cd').for(:jira_issue_transition_id) }
end end
describe 'Validations' do describe 'Validations' do
...@@ -116,143 +116,142 @@ describe JiraService do ...@@ -116,143 +116,142 @@ describe JiraService do
describe '#close_issue' do describe '#close_issue' do
let(:custom_base_url) { 'http://custom_url' } let(:custom_base_url) { 'http://custom_url' }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project) } let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request) }
before do
@jira_service = described_class.new
allow(@jira_service).to receive_messages(
project_id: project.id,
project: project,
service_hook: true,
url: 'http://jira.example.com',
username: 'gitlab_jira_username',
password: 'gitlab_jira_password',
jira_issue_transition_id: "999"
)
# These stubs are needed to test JiraService#close_issue. shared_examples 'close_issue' do
# We close the issue then do another request to API to check if it got closed. before do
# Here is stubbed the API return with a closed and an opened issues. @jira_service = described_class.new
open_issue = JIRA::Resource::Issue.new(@jira_service.client, attrs: { "id" => "JIRA-123" }) allow(@jira_service).to receive_messages(
closed_issue = open_issue.dup project_id: project.id,
allow(open_issue).to receive(:resolution).and_return(false) project: project,
allow(closed_issue).to receive(:resolution).and_return(true) service_hook: true,
allow(JIRA::Resource::Issue).to receive(:find).and_return(open_issue, closed_issue) url: 'http://jira.example.com',
username: 'gitlab_jira_username',
allow_any_instance_of(JIRA::Resource::Issue).to receive(:key).and_return("JIRA-123") password: 'gitlab_jira_password',
allow(JIRA::Resource::Remotelink).to receive(:all).and_return([]) jira_issue_transition_id: '999'
)
@jira_service.save
project_issues_url = 'http://jira.example.com/rest/api/2/issue/JIRA-123'
@transitions_url = 'http://jira.example.com/rest/api/2/issue/JIRA-123/transitions'
@comment_url = 'http://jira.example.com/rest/api/2/issue/JIRA-123/comment'
@remote_link_url = 'http://jira.example.com/rest/api/2/issue/JIRA-123/remotelink'
WebMock.stub_request(:get, project_issues_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password))
WebMock.stub_request(:post, @transitions_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password))
WebMock.stub_request(:post, @comment_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password))
WebMock.stub_request(:post, @remote_link_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password))
end
it "calls JIRA API" do # These stubs are needed to test JiraService#close_issue.
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) # We close the issue then do another request to API to check if it got closed.
# Here is stubbed the API return with a closed and an opened issues.
open_issue = JIRA::Resource::Issue.new(@jira_service.client, attrs: { 'id' => 'JIRA-123' })
closed_issue = open_issue.dup
allow(open_issue).to receive(:resolution).and_return(false)
allow(closed_issue).to receive(:resolution).and_return(true)
allow(JIRA::Resource::Issue).to receive(:find).and_return(open_issue, closed_issue)
expect(WebMock).to have_requested(:post, @comment_url).with( allow_any_instance_of(JIRA::Resource::Issue).to receive(:key).and_return('JIRA-123')
body: /Issue solved with/ allow(JIRA::Resource::Remotelink).to receive(:all).and_return([])
).once
end
# Check https://developer.atlassian.com/jiradev/jira-platform/guides/other/guide-jira-remote-issue-links/fields-in-remote-issue-links @jira_service.save
# for more information
it "creates Remote Link reference in JIRA for comment" do
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project))
favicon_path = "http://localhost/assets/#{find_asset('favicon.png').digest_path}"
# Creates comment
expect(WebMock).to have_requested(:post, @comment_url)
# Creates Remote Link in JIRA issue fields
expect(WebMock).to have_requested(:post, @remote_link_url).with(
body: hash_including(
GlobalID: "GitLab",
object: {
url: "#{Gitlab.config.gitlab.url}/#{project.full_path}/commit/#{merge_request.diff_head_sha}",
title: "GitLab: Solved by commit #{merge_request.diff_head_sha}.",
icon: { title: "GitLab", url16x16: favicon_path },
status: { resolved: true }
}
)
).once
end
it "does not send comment or remote links to issues already closed" do project_issues_url = 'http://jira.example.com/rest/api/2/issue/JIRA-123'
allow_any_instance_of(JIRA::Resource::Issue).to receive(:resolution).and_return(true) @transitions_url = 'http://jira.example.com/rest/api/2/issue/JIRA-123/transitions'
@comment_url = 'http://jira.example.com/rest/api/2/issue/JIRA-123/comment'
@remote_link_url = 'http://jira.example.com/rest/api/2/issue/JIRA-123/remotelink'
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) WebMock.stub_request(:get, project_issues_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password))
WebMock.stub_request(:post, @transitions_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password))
WebMock.stub_request(:post, @comment_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password))
WebMock.stub_request(:post, @remote_link_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password))
end
expect(WebMock).not_to have_requested(:post, @comment_url) it 'calls JIRA API' do
expect(WebMock).not_to have_requested(:post, @remote_link_url) @jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
end
it "does not send comment or remote links to issues with unknown resolution" do expect(WebMock).to have_requested(:post, @comment_url).with(
allow_any_instance_of(JIRA::Resource::Issue).to receive(:respond_to?).with(:resolution).and_return(false) body: /Issue solved with/
).once
end
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) # Check https://developer.atlassian.com/jiradev/jira-platform/guides/other/guide-jira-remote-issue-links/fields-in-remote-issue-links
# for more information
it 'creates Remote Link reference in JIRA for comment' do
@jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
favicon_path = "http://localhost/assets/#{find_asset('favicon.png').digest_path}"
# Creates comment
expect(WebMock).to have_requested(:post, @comment_url)
# Creates Remote Link in JIRA issue fields
expect(WebMock).to have_requested(:post, @remote_link_url).with(
body: hash_including(
GlobalID: 'GitLab',
object: {
url: "#{Gitlab.config.gitlab.url}/#{project.full_path}/commit/#{commit_id}",
title: "GitLab: Solved by commit #{commit_id}.",
icon: { title: 'GitLab', url16x16: favicon_path },
status: { resolved: true }
}
)
).once
end
expect(WebMock).not_to have_requested(:post, @comment_url) it 'does not send comment or remote links to issues already closed' do
expect(WebMock).not_to have_requested(:post, @remote_link_url) allow_any_instance_of(JIRA::Resource::Issue).to receive(:resolution).and_return(true)
end
it "references the GitLab commit/merge request" do @jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
stub_config_setting(base_url: custom_base_url)
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) expect(WebMock).not_to have_requested(:post, @comment_url)
expect(WebMock).not_to have_requested(:post, @remote_link_url)
end
expect(WebMock).to have_requested(:post, @comment_url).with( it 'does not send comment or remote links to issues with unknown resolution' do
body: %r{#{custom_base_url}/#{project.full_path}/commit/#{merge_request.diff_head_sha}} allow_any_instance_of(JIRA::Resource::Issue).to receive(:respond_to?).with(:resolution).and_return(false)
).once
end
it "references the GitLab commit/merge request (relative URL)" do @jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
stub_config_setting(relative_url_root: '/gitlab')
stub_config_setting(url: Settings.send(:build_gitlab_url))
allow(described_class).to receive(:default_url_options) do expect(WebMock).not_to have_requested(:post, @comment_url)
{ script_name: '/gitlab' } expect(WebMock).not_to have_requested(:post, @remote_link_url)
end end
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) it 'references the GitLab commit' do
stub_config_setting(base_url: custom_base_url)
expect(WebMock).to have_requested(:post, @comment_url).with( @jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
body: %r{#{Gitlab.config.gitlab.url}/#{project.full_path}/commit/#{merge_request.diff_head_sha}}
).once expect(WebMock).to have_requested(:post, @comment_url).with(
end body: %r{#{custom_base_url}/#{project.full_path}/commit/#{commit_id}}
).once
end
it 'references the GitLab commit' do
stub_config_setting(relative_url_root: '/gitlab')
stub_config_setting(url: Settings.send(:build_gitlab_url))
allow(described_class).to receive(:default_url_options) do
{ script_name: '/gitlab' }
end
@jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
context '#close_issue' do expect(WebMock).to have_requested(:post, @comment_url).with(
it "logs exception when transition id is not valid" do body: %r{#{Gitlab.config.gitlab.url}/#{project.full_path}/commit/#{commit_id}}
).once
end
it 'logs exception when transition id is not valid' do
allow(Rails.logger).to receive(:info) allow(Rails.logger).to receive(:info)
WebMock.stub_request(:post, @transitions_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).and_raise("Bad Request") WebMock.stub_request(:post, @transitions_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).and_raise('Bad Request')
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) @jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
expect(Rails.logger).to have_received(:info).with("JiraService Issue Transition failed message ERROR: http://jira.example.com - Bad Request") expect(Rails.logger).to have_received(:info).with('JiraService Issue Transition failed message ERROR: http://jira.example.com - Bad Request')
end end
it "calls the api with jira_issue_transition_id" do it 'calls the api with jira_issue_transition_id' do
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) @jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
expect(WebMock).to have_requested(:post, @transitions_url).with( expect(WebMock).to have_requested(:post, @transitions_url).with(
body: /999/ body: /999/
).once ).once
end end
context "when have multiple transition ids" do context 'when have multiple transition ids' do
it "calls the api with transition ids separated by comma" do it 'calls the api with transition ids separated by comma' do
allow(@jira_service).to receive_messages(jira_issue_transition_id: "1,2,3") allow(@jira_service).to receive_messages(jira_issue_transition_id: '1,2,3')
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) @jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
1.upto(3) do |transition_id| 1.upto(3) do |transition_id|
expect(WebMock).to have_requested(:post, @transitions_url).with( expect(WebMock).to have_requested(:post, @transitions_url).with(
...@@ -261,10 +260,10 @@ describe JiraService do ...@@ -261,10 +260,10 @@ describe JiraService do
end end
end end
it "calls the api with transition ids separated by semicolon" do it 'calls the api with transition ids separated by semicolon' do
allow(@jira_service).to receive_messages(jira_issue_transition_id: "1;2;3") allow(@jira_service).to receive_messages(jira_issue_transition_id: '1;2;3')
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project)) @jira_service.close_issue(resource, ExternalIssue.new('JIRA-123', project))
1.upto(3) do |transition_id| 1.upto(3) do |transition_id|
expect(WebMock).to have_requested(:post, @transitions_url).with( expect(WebMock).to have_requested(:post, @transitions_url).with(
...@@ -274,6 +273,20 @@ describe JiraService do ...@@ -274,6 +273,20 @@ describe JiraService do
end end
end end
end end
context 'when resource is a merge request' do
let(:resource) { create(:merge_request) }
let(:commit_id) { resource.diff_head_sha }
it_behaves_like 'close_issue'
end
context 'when resource is a commit' do
let(:resource) { project.commit('master') }
let(:commit_id) { resource.id }
it_behaves_like 'close_issue'
end
end end
describe '#test_settings' do describe '#test_settings' do
...@@ -321,17 +334,17 @@ describe JiraService do ...@@ -321,17 +334,17 @@ describe JiraService do
end end
end end
describe "Stored password invalidation" do describe 'Stored password invalidation' do
let(:project) { create(:project) } let(:project) { create(:project) }
context "when a password was previously set" do context 'when a password was previously set' do
before do before do
@jira_service = described_class.create!( @jira_service = described_class.create!(
project: project, project: project,
properties: { properties: {
url: 'http://jira.example.com/web', url: 'http://jira.example.com/web',
username: 'mic', username: 'mic',
password: "password" password: 'password'
} }
) )
end end
...@@ -370,10 +383,10 @@ describe JiraService do ...@@ -370,10 +383,10 @@ describe JiraService do
@jira_service.url = 'http://jira_edited.example.com/rweb' @jira_service.url = 'http://jira_edited.example.com/rweb'
@jira_service.save @jira_service.save
expect(@jira_service.password).to eq("password") expect(@jira_service.password).to eq('password')
end end
it 'reset password if api url set to ""' do it 'reset password if api url set to empty' do
@jira_service.api_url = '' @jira_service.api_url = ''
@jira_service.save @jira_service.save
...@@ -440,7 +453,7 @@ describe JiraService do ...@@ -440,7 +453,7 @@ describe JiraService do
it 'is initialized' do it 'is initialized' do
expect(@service.title).to eq('JIRA') expect(@service.title).to eq('JIRA')
expect(@service.description).to eq("Jira issue tracker") expect(@service.description).to eq('Jira issue tracker')
end end
end end
...@@ -454,7 +467,7 @@ describe JiraService do ...@@ -454,7 +467,7 @@ describe JiraService do
@service.destroy! @service.destroy!
end end
it "is correct" do it 'is correct' do
expect(@service.title).to eq('Jira One') expect(@service.title).to eq('Jira One')
expect(@service.description).to eq('Jira One issue tracker') expect(@service.description).to eq('Jira One issue tracker')
end end
...@@ -476,7 +489,7 @@ describe JiraService do ...@@ -476,7 +489,7 @@ describe JiraService do
it 'is initialized' do it 'is initialized' do
expect(@service.options[:use_cookies]).to eq(true) expect(@service.options[:use_cookies]).to eq(true)
expect(@service.options[:additional_cookies]).to eq(["OBBasicAuth=fromDialog"]) expect(@service.options[:additional_cookies]).to eq(['OBBasicAuth=fromDialog'])
end end
end 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