Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/project_services/jira_service_spec.rb')
-rw-r--r--spec/models/project_services/jira_service_spec.rb186
1 files changed, 130 insertions, 56 deletions
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index 78bd0e91208..ef0bc930152 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -82,11 +82,8 @@ RSpec.describe JiraService do
subject(:fields) { service.fields }
- it 'includes transition help link' do
- transition_id_field = fields.find { |field| field[:name] == 'jira_issue_transition_id' }
-
- expect(transition_id_field[:title]).to eq('Jira workflow transition IDs')
- expect(transition_id_field[:help]).to include('/help/user/project/integrations/jira')
+ it 'returns custom fields' do
+ expect(fields.pluck(:name)).to eq(%w[url api_url username password])
end
end
@@ -460,10 +457,10 @@ RSpec.describe JiraService do
end
context 'with options' do
- let(:issue_url) { "#{url}/rest/api/2/issue/#{issue_key}?expand=renderedFields" }
+ let(:issue_url) { "#{url}/rest/api/2/issue/#{issue_key}?expand=renderedFields,transitions" }
it 'calls the Jira API with the options to get the issue' do
- jira_service.find_issue(issue_key, rendered_fields: true)
+ jira_service.find_issue(issue_key, rendered_fields: true, transitions: true)
expect(WebMock).to have_requested(:get, issue_url)
end
@@ -474,52 +471,56 @@ RSpec.describe JiraService do
let(:custom_base_url) { 'http://custom_url' }
shared_examples 'close_issue' do
+ let(:issue_key) { 'JIRA-123' }
+ let(:issue_url) { "#{url}/rest/api/2/issue/#{issue_key}" }
+ let(:transitions_url) { "#{issue_url}/transitions" }
+ let(:comment_url) { "#{issue_url}/comment" }
+ let(:remote_link_url) { "#{issue_url}/remotelink" }
+ let(:transitions) { nil }
+
+ let(:issue_fields) do
+ {
+ id: issue_key,
+ self: issue_url,
+ transitions: transitions
+ }
+ end
+
+ subject(:close_issue) do
+ jira_service.close_issue(resource, ExternalIssue.new(issue_key, project))
+ end
+
before do
- @jira_service = described_class.new
- allow(@jira_service).to receive_messages(
- project_id: project.id,
- project: project,
- url: 'http://jira.example.com',
- username: 'gitlab_jira_username',
- password: 'gitlab_jira_password',
- jira_issue_transition_id: '999'
- )
+ allow(jira_service).to receive_messages(jira_issue_transition_id: '999')
# These stubs are needed to test JiraService#close_issue.
# 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' })
+ open_issue = JIRA::Resource::Issue.new(jira_service.client, attrs: issue_fields.deep_stringify_keys)
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)
- allow_any_instance_of(JIRA::Resource::Issue).to receive(:key).and_return('JIRA-123')
+ allow_any_instance_of(JIRA::Resource::Issue).to receive(:key).and_return(issue_key)
allow(JIRA::Resource::Remotelink).to receive(:all).and_return([])
- @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))
+ WebMock.stub_request(:get, issue_url).with(basic_auth: %w(jira-username jira-password))
+ WebMock.stub_request(:post, transitions_url).with(basic_auth: %w(jira-username jira-password))
+ WebMock.stub_request(:post, comment_url).with(basic_auth: %w(jira-username jira-password))
+ WebMock.stub_request(:post, remote_link_url).with(basic_auth: %w(jira-username jira-password))
end
let(:external_issue) { ExternalIssue.new('JIRA-123', project) }
def close_issue
- @jira_service.close_issue(resource, external_issue, current_user)
+ jira_service.close_issue(resource, external_issue, current_user)
end
it 'calls Jira API' do
close_issue
- expect(WebMock).to have_requested(:post, @comment_url).with(
+ expect(WebMock).to have_requested(:post, comment_url).with(
body: /Issue solved with/
).once
end
@@ -546,9 +547,9 @@ RSpec.describe JiraService do
favicon_path = "http://localhost/assets/#{find_asset('favicon.png').digest_path}"
# Creates comment
- expect(WebMock).to have_requested(:post, @comment_url)
+ 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(
+ expect(WebMock).to have_requested(:post, remote_link_url).with(
body: hash_including(
GlobalID: 'GitLab',
relationship: 'mentioned on',
@@ -564,11 +565,11 @@ RSpec.describe JiraService do
context 'when "comment_on_event_enabled" is set to false' do
it 'creates Remote Link reference but does not create comment' do
- allow(@jira_service).to receive_messages(comment_on_event_enabled: false)
+ allow(jira_service).to receive_messages(comment_on_event_enabled: false)
close_issue
- expect(WebMock).not_to have_requested(:post, @comment_url)
- expect(WebMock).to have_requested(:post, @remote_link_url)
+ expect(WebMock).not_to have_requested(:post, comment_url)
+ expect(WebMock).to have_requested(:post, remote_link_url)
end
end
@@ -589,7 +590,7 @@ RSpec.describe JiraService do
close_issue
- expect(WebMock).not_to have_requested(:post, @comment_url)
+ expect(WebMock).not_to have_requested(:post, comment_url)
end
end
@@ -598,8 +599,8 @@ RSpec.describe JiraService do
close_issue
- expect(WebMock).not_to have_requested(:post, @comment_url)
- expect(WebMock).not_to have_requested(:post, @remote_link_url)
+ expect(WebMock).not_to have_requested(:post, comment_url)
+ expect(WebMock).not_to have_requested(:post, remote_link_url)
end
it 'does not send comment or remote links to issues with unknown resolution' do
@@ -607,8 +608,8 @@ RSpec.describe JiraService do
close_issue
- expect(WebMock).not_to have_requested(:post, @comment_url)
- expect(WebMock).not_to have_requested(:post, @remote_link_url)
+ expect(WebMock).not_to have_requested(:post, comment_url)
+ expect(WebMock).not_to have_requested(:post, remote_link_url)
end
it 'references the GitLab commit' do
@@ -616,7 +617,7 @@ RSpec.describe JiraService do
close_issue
- expect(WebMock).to have_requested(:post, @comment_url).with(
+ expect(WebMock).to have_requested(:post, comment_url).with(
body: %r{#{custom_base_url}/#{project.full_path}/-/commit/#{commit_id}}
).once
end
@@ -631,18 +632,18 @@ RSpec.describe JiraService do
close_issue
- expect(WebMock).to have_requested(:post, @comment_url).with(
+ expect(WebMock).to have_requested(:post, comment_url).with(
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(@jira_service).to receive(:log_error)
- WebMock.stub_request(:post, @transitions_url).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).and_raise("Bad Request")
+ allow(jira_service).to receive(:log_error)
+ WebMock.stub_request(:post, transitions_url).with(basic_auth: %w(jira-username jira-password)).and_raise("Bad Request")
close_issue
- expect(@jira_service).to have_received(:log_error).with(
+ expect(jira_service).to have_received(:log_error).with(
"Issue transition failed",
error: hash_including(
exception_class: 'StandardError',
@@ -655,34 +656,107 @@ RSpec.describe JiraService do
it 'calls the api with jira_issue_transition_id' do
close_issue
- expect(WebMock).to have_requested(:post, @transitions_url).with(
- body: /999/
+ expect(WebMock).to have_requested(:post, transitions_url).with(
+ body: /"id":"999"/
).once
end
- context 'when have multiple transition ids' 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')
+ context 'when using automatic issue transitions' do
+ let(:transitions) do
+ [
+ { id: '1' },
+ { id: '2', to: { statusCategory: { key: 'new' } } },
+ { id: '3', to: { statusCategory: { key: 'done' } } },
+ { id: '4', to: { statusCategory: { key: 'done' } } }
+ ]
+ end
+
+ before do
+ allow(jira_service).to receive_messages(jira_issue_transition_id: '')
close_issue
+ end
+
+ it 'uses the next transition with a status category of done' do
+ expect(WebMock).to have_requested(:post, transitions_url).with(
+ body: /"id":"3"/
+ ).once
+ end
+
+ context 'when no done transition is available' do
+ let(:transitions) do
+ [
+ { id: '1', to: { statusCategory: { key: 'new' } } }
+ ]
+ end
+
+ it 'does not attempt to transition' do
+ expect(WebMock).not_to have_requested(:post, transitions_url)
+ end
+ end
+
+ context 'when no valid transitions are returned' do
+ let(:transitions) { 'foo' }
+
+ it 'does not attempt to transition' do
+ expect(WebMock).not_to have_requested(:post, transitions_url)
+ end
+ end
+ end
+
+ context 'when using multiple transition ids' do
+ before do
+ allow(jira_service).to receive_messages(jira_issue_transition_id: '1,2,3')
+ end
+
+ it 'calls the api with transition ids separated by comma' do
+ close_issue
1.upto(3) do |transition_id|
- expect(WebMock).to have_requested(:post, @transitions_url).with(
- body: /#{transition_id}/
+ expect(WebMock).to have_requested(:post, transitions_url).with(
+ body: /"id":"#{transition_id}"/
).once
end
+
+ expect(WebMock).to have_requested(:post, comment_url)
end
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')
close_issue
1.upto(3) do |transition_id|
- expect(WebMock).to have_requested(:post, @transitions_url).with(
- body: /#{transition_id}/
+ expect(WebMock).to have_requested(:post, transitions_url).with(
+ body: /"id":"#{transition_id}"/
).once
end
+
+ expect(WebMock).to have_requested(:post, comment_url)
+ end
+
+ context 'when a transition fails' do
+ before do
+ WebMock.stub_request(:post, transitions_url).with(basic_auth: %w(jira-username jira-password)).to_return do |request|
+ { status: request.body.include?('"id":"2"') ? 500 : 200 }
+ end
+ end
+
+ it 'stops the sequence' do
+ close_issue
+
+ 1.upto(2) do |transition_id|
+ expect(WebMock).to have_requested(:post, transitions_url).with(
+ body: /"id":"#{transition_id}"/
+ )
+ end
+
+ expect(WebMock).not_to have_requested(:post, transitions_url).with(
+ body: /"id":"3"/
+ )
+
+ expect(WebMock).not_to have_requested(:post, comment_url)
+ end
end
end
end