2019-07-07 11:18:12 +05:30
# frozen_string_literal: true
2015-04-26 12:48:37 +05:30
require 'spec_helper'
2021-09-04 01:27:46 +05:30
RSpec . describe Integrations :: Jira do
2018-11-08 19:23:39 +05:30
include AssetsHelpers
2017-08-17 22:00:37 +05:30
2021-03-08 18:12:59 +05:30
let_it_be ( :project ) { create ( :project , :repository ) }
2021-03-11 19:13:27 +05:30
let ( :current_user ) { build_stubbed ( :user ) }
2019-12-04 20:38:33 +05:30
let ( :url ) { 'http://jira.example.com' }
let ( :api_url ) { 'http://api-jira.example.com' }
let ( :username ) { 'jira-username' }
let ( :password ) { 'jira-password' }
2022-07-29 17:44:30 +05:30
let ( :project_key ) { nil }
2019-12-04 20:38:33 +05:30
let ( :transition_id ) { 'test27' }
2020-11-24 15:15:51 +05:30
let ( :server_info_results ) { { 'deploymentType' = > 'Cloud' } }
2021-09-30 23:02:18 +05:30
let ( :jira_integration ) do
2021-03-08 18:12:59 +05:30
described_class . new (
project : project ,
url : url ,
username : username ,
2022-07-29 17:44:30 +05:30
password : password ,
project_key : project_key
2021-03-08 18:12:59 +05:30
)
end
2020-11-24 15:15:51 +05:30
before do
WebMock . stub_request ( :get , / serverInfo / ) . to_return ( body : server_info_results . to_json )
end
2019-12-04 20:38:33 +05:30
2022-07-16 23:28:13 +05:30
it_behaves_like Integrations :: ResetSecretFields do
let ( :integration ) { jira_integration }
end
2022-07-23 23:45:48 +05:30
describe 'validations' do
subject { jira_integration }
context 'when integration is active' do
before do
jira_integration . active = true
# Don't auto-fill URLs from gitlab.yml
stub_config ( issues_tracker : { } )
end
it { is_expected . to be_valid }
it { is_expected . to validate_presence_of ( :url ) }
it { is_expected . to validate_presence_of ( :username ) }
it { is_expected . to validate_presence_of ( :password ) }
it_behaves_like 'issue tracker integration URL attribute' , :url
it_behaves_like 'issue tracker integration URL attribute' , :api_url
end
context 'when integration is inactive' do
before do
jira_integration . active = false
end
it { is_expected . to be_valid }
it { is_expected . not_to validate_presence_of ( :url ) }
it { is_expected . not_to validate_presence_of ( :username ) }
it { is_expected . not_to validate_presence_of ( :password ) }
end
describe 'jira_issue_transition_id' do
it 'accepts a blank value' do
jira_integration . jira_issue_transition_id = ' '
expect ( jira_integration ) . to be_valid
end
it 'accepts any string containing numbers' do
jira_integration . jira_issue_transition_id = 'foo 23 bar'
expect ( jira_integration ) . to be_valid
end
it 'does not accept a string without numbers' do
jira_integration . jira_issue_transition_id = 'foo bar'
expect ( jira_integration ) . not_to be_valid
2022-11-25 23:54:43 +05:30
expect ( jira_integration . errors . full_messages ) . to eq (
[
'Jira issue transition IDs must be a list of numbers that can be split with , or ;'
] )
2022-07-23 23:45:48 +05:30
end
end
end
2018-03-17 18:26:18 +05:30
describe '#options' do
2019-12-21 20:55:43 +05:30
let ( :options ) do
{
2021-03-08 18:12:59 +05:30
project : project ,
2018-03-17 18:26:18 +05:30
active : true ,
username : 'username' ,
password : 'test' ,
jira_issue_transition_id : 24 ,
2021-09-04 01:27:46 +05:30
url : 'http://jira.test.com:1234/path/'
2019-12-21 20:55:43 +05:30
}
2018-03-17 18:26:18 +05:30
end
2021-09-04 01:27:46 +05:30
let ( :integration ) { described_class . create! ( options ) }
2019-12-21 20:55:43 +05:30
2018-03-17 18:26:18 +05:30
it 'sets the URL properly' do
2019-12-21 20:55:43 +05:30
# jira-ruby gem parses the URI and handles trailing slashes fine:
# https://github.com/sumoheavy/jira-ruby/blob/v1.7.0/lib/jira/http_client.rb#L62
2021-09-04 01:27:46 +05:30
expect ( integration . options [ :site ] ) . to eq ( 'http://jira.test.com:1234' )
2018-03-17 18:26:18 +05:30
end
it 'leaves out trailing slashes in context' do
2021-09-04 01:27:46 +05:30
expect ( integration . options [ :context_path ] ) . to eq ( '/path' )
end
context 'URL without a path' do
before do
integration . url = 'http://jira.test.com/'
end
it 'leaves out trailing slashes in context' do
expect ( integration . options [ :site ] ) . to eq ( 'http://jira.test.com' )
expect ( integration . options [ :context_path ] ) . to eq ( '' )
end
end
context 'URL with query string parameters' do
before do
integration . url << '?nosso&foo=bar'
end
it 'removes query string parameters' do
expect ( integration . options [ :site ] ) . to eq ( 'http://jira.test.com:1234' )
expect ( integration . options [ :context_path ] ) . to eq ( '/path' )
end
2018-03-17 18:26:18 +05:30
end
2019-12-21 20:55:43 +05:30
context 'username with trailing whitespaces' do
before do
options . merge! ( username : 'username ' )
end
it 'leaves out trailing whitespaces in username' do
2021-09-04 01:27:46 +05:30
expect ( integration . options [ :username ] ) . to eq ( 'username' )
2019-12-21 20:55:43 +05:30
end
end
it 'provides additional cookies to allow basic auth with oracle webgate' do
2021-09-04 01:27:46 +05:30
expect ( integration . options [ :use_cookies ] ) . to eq ( true )
expect ( integration . options [ :additional_cookies ] ) . to eq ( [ 'OBBasicAuth=fromDialog' ] )
2019-12-21 20:55:43 +05:30
end
context 'using api URL' do
before do
options . merge! ( api_url : 'http://jira.test.com/api_path/' )
end
it 'leaves out trailing slashes in context' do
2021-09-04 01:27:46 +05:30
expect ( integration . options [ :context_path ] ) . to eq ( '/api_path' )
2019-12-21 20:55:43 +05:30
end
end
2018-03-17 18:26:18 +05:30
end
2021-02-22 17:27:13 +05:30
describe '#fields' do
2021-09-30 23:02:18 +05:30
let ( :integration ) { create ( :jira_integration ) }
2021-02-22 17:27:13 +05:30
2021-09-30 23:02:18 +05:30
subject ( :fields ) { integration . fields }
2021-02-22 17:27:13 +05:30
2021-04-29 21:17:54 +05:30
it 'returns custom fields' do
2022-08-13 15:12:31 +05:30
expect ( fields . pluck ( :name ) ) . to eq ( %w[ url api_url username password jira_issue_transition_id ] )
2021-02-22 17:27:13 +05:30
end
2022-05-07 20:08:51 +05:30
end
describe '#sections' do
let ( :integration ) { create ( :jira_integration ) }
subject ( :sections ) { integration . sections . map { | s | s [ :type ] } }
context 'when project_level? is true' do
before do
allow ( integration ) . to receive ( :project_level? ) . and_return ( true )
end
it 'includes SECTION_TYPE_JIRA_ISSUES' do
expect ( sections ) . to include ( described_class :: SECTION_TYPE_JIRA_ISSUES )
end
2022-07-16 23:28:13 +05:30
it 'section SECTION_TYPE_JIRA_ISSUES has `plan` attribute' do
jira_issues_section = integration . sections . find { | s | s [ :type ] == described_class :: SECTION_TYPE_JIRA_ISSUES }
expect ( jira_issues_section [ :plan ] ) . to eq ( 'premium' )
end
2022-05-07 20:08:51 +05:30
end
context 'when project_level? is false' do
before do
allow ( integration ) . to receive ( :project_level? ) . and_return ( false )
end
it 'does not include SECTION_TYPE_JIRA_ISSUES' do
expect ( sections ) . not_to include ( described_class :: SECTION_TYPE_JIRA_ISSUES )
end
end
2021-02-22 17:27:13 +05:30
end
2017-08-17 22:00:37 +05:30
describe '.reference_pattern' do
2020-05-24 23:13:21 +05:30
using RSpec :: Parameterized :: TableSyntax
where ( :key , :result ) do
'#123' | ''
'1#23#12' | ''
'JIRA-1234A' | 'JIRA-1234'
'JIRA-1234-some_tag' | 'JIRA-1234'
'JIRA-1234_some_tag' | 'JIRA-1234'
'EXT_EXT-1234' | 'EXT_EXT-1234'
'EXT3_EXT-1234' | 'EXT3_EXT-1234'
'3EXT_EXT-1234' | ''
2022-11-25 23:54:43 +05:30
'CVE-2022-123' | ''
'CVE-123' | 'CVE-123'
2020-05-24 23:13:21 +05:30
end
2016-11-03 12:29:30 +05:30
2020-05-24 23:13:21 +05:30
with_them do
specify do
expect ( described_class . reference_pattern . match ( key ) . to_s ) . to eq ( result )
end
2016-11-03 12:29:30 +05:30
end
end
2022-02-05 19:09:49 +05:30
describe '.valid_jira_cloud_url?' do
using RSpec :: Parameterized :: TableSyntax
where ( :url , :result ) do
'https://abc.atlassian.net' | true
2023-01-10 11:22:00 +05:30
'http://abc.atlassian.net' | false
2022-02-05 19:09:49 +05:30
'abc.atlassian.net' | false # This is how it behaves currently, but we may need to consider adding scheme if missing
'https://somethingelse.com' | false
2023-01-10 11:22:00 +05:30
'javascript://test.atlassian.net/%250dalert(document.domain)' | false
'https://example.com".atlassian.net' | false
nil | false
2022-02-05 19:09:49 +05:30
end
with_them do
specify do
expect ( described_class . valid_jira_cloud_url? ( url ) ) . to eq ( result )
end
end
end
2019-09-30 21:07:59 +05:30
describe '#create' do
let ( :params ) do
{
2021-03-08 18:12:59 +05:30
project : project ,
2021-09-04 01:27:46 +05:30
url : url ,
api_url : api_url ,
2019-12-04 20:38:33 +05:30
username : username , password : password ,
jira_issue_transition_id : transition_id
2019-09-30 21:07:59 +05:30
}
end
2021-09-30 23:02:18 +05:30
subject ( :integration ) { described_class . create! ( params ) }
2019-09-30 21:07:59 +05:30
2019-12-04 20:38:33 +05:30
it 'does not store data into properties' do
2022-06-21 17:19:12 +05:30
expect ( integration . properties ) . to be_empty
2019-12-04 20:38:33 +05:30
end
2020-11-24 15:15:51 +05:30
it 'stores data in data_fields correctly' do
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data . url ) . to eq ( url )
expect ( integration . jira_tracker_data . api_url ) . to eq ( api_url )
expect ( integration . jira_tracker_data . username ) . to eq ( username )
expect ( integration . jira_tracker_data . password ) . to eq ( password )
expect ( integration . jira_tracker_data . jira_issue_transition_id ) . to eq ( transition_id )
expect ( integration . jira_tracker_data . deployment_cloud? ) . to be_truthy
2020-11-24 15:15:51 +05:30
end
context 'when loading serverInfo' do
2021-09-30 23:02:18 +05:30
context 'with a Cloud instance' do
2020-11-24 15:15:51 +05:30
let ( :server_info_results ) { { 'deploymentType' = > 'Cloud' } }
it 'is detected' do
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data ) . to be_deployment_cloud
2020-11-24 15:15:51 +05:30
end
end
2021-09-30 23:02:18 +05:30
context 'with a Server instance' do
2020-11-24 15:15:51 +05:30
let ( :server_info_results ) { { 'deploymentType' = > 'Server' } }
it 'is detected' do
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data ) . to be_deployment_server
2020-11-24 15:15:51 +05:30
end
end
2021-09-04 01:27:46 +05:30
context 'from an Unknown instance' do
2020-11-24 15:15:51 +05:30
let ( :server_info_results ) { { 'deploymentType' = > 'FutureCloud' } }
2021-09-04 01:27:46 +05:30
context 'and URL ends in .atlassian.net' do
2023-01-10 11:22:00 +05:30
let ( :api_url ) { 'https://example-api.atlassian.net' }
2021-09-04 01:27:46 +05:30
it 'deployment_type is set to cloud' do
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data ) . to be_deployment_cloud
2021-09-04 01:27:46 +05:30
end
end
context 'and URL is something else' do
2023-01-10 11:22:00 +05:30
let ( :api_url ) { 'https://my-jira-api.someserver.com' }
2021-09-04 01:27:46 +05:30
it 'deployment_type is set to server' do
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data ) . to be_deployment_server
2021-09-04 01:27:46 +05:30
end
end
end
context 'and no ServerInfo response is received' do
let ( :server_info_results ) { { } }
context 'and URL ends in .atlassian.net' do
2023-01-10 11:22:00 +05:30
let ( :api_url ) { 'https://example-api.atlassian.net' }
2021-09-04 01:27:46 +05:30
it 'deployment_type is set to cloud' do
expect ( Gitlab :: AppLogger ) . to receive ( :warn ) . with ( message : " Jira API returned no ServerInfo, setting deployment_type from URL " , server_info : server_info_results , url : api_url )
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data ) . to be_deployment_cloud
2021-09-04 01:27:46 +05:30
end
end
context 'and URL is something else' do
2023-01-10 11:22:00 +05:30
let ( :api_url ) { 'https://my-jira-api.someserver.com' }
2021-09-04 01:27:46 +05:30
it 'deployment_type is set to server' do
expect ( Gitlab :: AppLogger ) . to receive ( :warn ) . with ( message : " Jira API returned no ServerInfo, setting deployment_type from URL " , server_info : server_info_results , url : api_url )
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data ) . to be_deployment_server
2021-09-04 01:27:46 +05:30
end
2020-11-24 15:15:51 +05:30
end
end
2019-12-04 20:38:33 +05:30
end
2019-09-30 21:07:59 +05:30
end
2019-12-04 20:38:33 +05:30
# we need to make sure we are able to read both from properties and jira_tracker_data table
2019-12-21 20:55:43 +05:30
# TODO: change this as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
2019-09-30 21:07:59 +05:30
context 'overriding properties' do
let ( :access_params ) do
2019-12-04 20:38:33 +05:30
{ url : url , api_url : api_url , username : username , password : password ,
jira_issue_transition_id : transition_id }
2019-09-30 21:07:59 +05:30
end
2020-10-24 23:57:45 +05:30
2019-12-04 20:38:33 +05:30
let ( :data_params ) do
{
url : url , api_url : api_url ,
username : username , password : password ,
jira_issue_transition_id : transition_id
}
end
shared_examples 'handles jira fields' do
let ( :data_params ) do
{
url : url , api_url : api_url ,
username : username , password : password ,
jira_issue_transition_id : transition_id
}
end
context 'reading data' do
it 'reads data correctly' do
2021-09-30 23:02:18 +05:30
expect ( integration . url ) . to eq ( url )
expect ( integration . api_url ) . to eq ( api_url )
expect ( integration . username ) . to eq ( username )
expect ( integration . password ) . to eq ( password )
expect ( integration . jira_issue_transition_id ) . to eq ( transition_id )
2019-12-04 20:38:33 +05:30
end
end
2019-09-30 21:07:59 +05:30
2020-03-13 15:44:24 +05:30
describe '#update' do
2019-12-04 20:38:33 +05:30
context 'basic update' do
2020-11-24 15:15:51 +05:30
let_it_be ( :new_username ) { 'new_username' }
let_it_be ( :new_url ) { 'http://jira-new.example.com' }
2019-12-04 20:38:33 +05:30
before do
2022-07-16 23:28:13 +05:30
integration . update! ( username : new_username , url : new_url , password : password )
2019-12-04 20:38:33 +05:30
end
it 'stores updated data in jira_tracker_data table' do
2021-09-30 23:02:18 +05:30
data = integration . jira_tracker_data . reload
2019-12-04 20:38:33 +05:30
expect ( data . url ) . to eq ( new_url )
expect ( data . api_url ) . to eq ( api_url )
expect ( data . username ) . to eq ( new_username )
expect ( data . password ) . to eq ( password )
expect ( data . jira_issue_transition_id ) . to eq ( transition_id )
end
end
2020-11-24 15:15:51 +05:30
context 'when updating the url, api_url, username, or password' do
2021-09-04 01:27:46 +05:30
context 'when updating the integration' do
it 'updates deployment type' do
2022-07-16 23:28:13 +05:30
integration . update! ( url : 'http://first.url' , password : password )
2021-09-30 23:02:18 +05:30
integration . jira_tracker_data . update! ( deployment_type : 'server' )
2020-11-24 15:15:51 +05:30
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data . deployment_server? ) . to be_truthy
2020-11-24 15:15:51 +05:30
2021-10-27 15:23:28 +05:30
integration . update! ( api_url : 'http://another.url' , password : password )
2021-09-30 23:02:18 +05:30
integration . jira_tracker_data . reload
2021-09-04 01:27:46 +05:30
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data . deployment_cloud? ) . to be_truthy
2021-09-04 01:27:46 +05:30
expect ( WebMock ) . to have_requested ( :get , / serverInfo / ) . twice
end
end
context 'when removing the integration' do
let ( :server_info_results ) { { } }
it 'updates deployment type' do
2021-09-30 23:02:18 +05:30
integration . update! ( url : nil , api_url : nil , active : false )
2021-09-04 01:27:46 +05:30
2021-09-30 23:02:18 +05:30
integration . jira_tracker_data . reload
2020-11-24 15:15:51 +05:30
2021-09-30 23:02:18 +05:30
expect ( integration . jira_tracker_data . deployment_unknown? ) . to be_truthy
2021-09-04 01:27:46 +05:30
end
2020-11-24 15:15:51 +05:30
end
it 'calls serverInfo for url' do
2021-10-27 15:23:28 +05:30
integration . update! ( url : 'http://first.url' , password : password )
2020-11-24 15:15:51 +05:30
expect ( WebMock ) . to have_requested ( :get , / serverInfo / )
end
it 'calls serverInfo for api_url' do
2021-10-27 15:23:28 +05:30
integration . update! ( api_url : 'http://another.url' , password : password )
2020-11-24 15:15:51 +05:30
expect ( WebMock ) . to have_requested ( :get , / serverInfo / )
end
it 'calls serverInfo for username' do
2021-09-30 23:02:18 +05:30
integration . update! ( username : 'test-user' )
2020-11-24 15:15:51 +05:30
expect ( WebMock ) . to have_requested ( :get , / serverInfo / )
end
it 'calls serverInfo for password' do
2021-09-30 23:02:18 +05:30
integration . update! ( password : 'test-password' )
2020-11-24 15:15:51 +05:30
expect ( WebMock ) . to have_requested ( :get , / serverInfo / )
end
end
context 'when not updating the url, api_url, username, or password' do
it 'does not update deployment type' do
2021-09-30 23:02:18 +05:30
expect { integration . update! ( jira_issue_transition_id : 'jira_issue_transition_id' ) }
. to raise_error ( ActiveRecord :: RecordInvalid )
2020-11-24 15:15:51 +05:30
expect ( WebMock ) . not_to have_requested ( :get , / serverInfo / )
end
end
2019-12-04 20:38:33 +05:30
end
end
2019-12-21 20:55:43 +05:30
# this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
2019-09-30 21:07:59 +05:30
context 'when data are stored in properties' do
2020-07-28 23:09:34 +05:30
let ( :properties ) { data_params }
2021-09-30 23:02:18 +05:30
let! ( :integration ) do
create ( :jira_integration , :without_properties_callback , properties : properties . merge ( additional : 'something' ) )
2019-09-30 21:07:59 +05:30
end
2019-12-04 20:38:33 +05:30
it_behaves_like 'handles jira fields'
2019-09-30 21:07:59 +05:30
end
context 'when data are stored in separated fields' do
2021-09-30 23:02:18 +05:30
let ( :integration ) do
create ( :jira_integration , data_params . merge ( properties : { } ) )
2019-09-30 21:07:59 +05:30
end
2019-12-04 20:38:33 +05:30
it_behaves_like 'handles jira fields'
2019-09-30 21:07:59 +05:30
end
context 'when data are stored in both properties and separated fields' do
2020-07-28 23:09:34 +05:30
let ( :properties ) { data_params }
2021-09-30 23:02:18 +05:30
let ( :integration ) do
2021-10-27 15:23:28 +05:30
create ( :jira_integration , :without_properties_callback , properties : properties ) . tap do | integration |
2021-06-08 01:23:25 +05:30
create ( :jira_tracker_data , data_params . merge ( integration : integration ) )
2019-12-04 20:38:33 +05:30
end
2019-09-30 21:07:59 +05:30
end
2019-12-04 20:38:33 +05:30
it_behaves_like 'handles jira fields'
2019-09-30 21:07:59 +05:30
end
end
2021-12-11 22:18:48 +05:30
describe '#client' do
2022-07-16 23:28:13 +05:30
subject do
2021-12-11 22:18:48 +05:30
stub_request ( :get , 'http://jira.example.com/foo' )
expect ( Gitlab :: HTTP ) . to receive ( :httparty_perform_request )
. with ( Net :: HTTP :: Get , '/foo' , hash_including ( timeouts ) ) . and_call_original
jira_integration . client . get ( '/foo' )
end
2022-07-16 23:28:13 +05:30
context 'when the FF :jira_raise_timeouts is enabled' do
let ( :timeouts ) do
{
open_timeout : 2 . minutes ,
read_timeout : 2 . minutes ,
write_timeout : 2 . minutes
}
end
it 'uses custom timeouts' do
subject
end
end
context 'when the FF :jira_raise_timeouts is disabled' do
before do
stub_feature_flags ( jira_raise_timeouts : false )
end
let ( :timeouts ) { Gitlab :: HTTP :: DEFAULT_TIMEOUT_OPTIONS }
it 'uses the default GitLab::HTTP timeouts' do
subject
end
end
2021-12-11 22:18:48 +05:30
end
2021-03-08 18:12:59 +05:30
describe '#find_issue' do
let ( :issue_key ) { 'JIRA-123' }
let ( :issue_url ) { " #{ url } /rest/api/2/issue/ #{ issue_key } " }
before do
stub_request ( :get , issue_url ) . with ( basic_auth : [ username , password ] )
end
2021-12-11 22:18:48 +05:30
it 'calls the Jira API to get the issue' do
2021-09-30 23:02:18 +05:30
jira_integration . find_issue ( issue_key )
2021-03-08 18:12:59 +05:30
expect ( WebMock ) . to have_requested ( :get , issue_url )
end
2021-03-11 19:13:27 +05:30
context 'with options' do
2021-04-29 21:17:54 +05:30
let ( :issue_url ) { " #{ url } /rest/api/2/issue/ #{ issue_key } ?expand=renderedFields,transitions " }
2021-03-11 19:13:27 +05:30
it 'calls the Jira API with the options to get the issue' do
2021-09-30 23:02:18 +05:30
jira_integration . find_issue ( issue_key , rendered_fields : true , transitions : true )
2021-03-11 19:13:27 +05:30
expect ( WebMock ) . to have_requested ( :get , issue_url )
end
end
2022-07-29 17:44:30 +05:30
context 'with restricted restrict_project_key option' do
subject ( :find_issue ) { jira_integration . find_issue ( issue_key , restrict_project_key : true ) }
it { is_expected . to eq ( nil ) }
context 'and project_key matches' do
let ( :project_key ) { 'JIRA' }
it 'calls the Jira API to get the issue' do
find_issue
expect ( WebMock ) . to have_requested ( :get , issue_url )
end
end
end
2021-03-08 18:12:59 +05:30
end
2017-08-17 22:00:37 +05:30
describe '#close_issue' do
let ( :custom_base_url ) { 'http://custom_url' }
2015-12-23 02:04:40 +05:30
2018-11-20 20:47:30 +05:30
shared_examples 'close_issue' do
2021-04-17 20:07:23 +05:30
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
2021-09-30 23:02:18 +05:30
jira_integration . close_issue ( resource , ExternalIssue . new ( issue_key , project ) )
2021-04-17 20:07:23 +05:30
end
2018-11-20 20:47:30 +05:30
before do
2021-09-30 23:02:18 +05:30
jira_integration . jira_issue_transition_id = '999'
2015-12-23 02:04:40 +05:30
2021-09-04 01:27:46 +05:30
# These stubs are needed to test Integrations::Jira#close_issue.
2018-11-20 20:47:30 +05:30
# 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.
2021-09-30 23:02:18 +05:30
open_issue = JIRA :: Resource :: Issue . new ( jira_integration . client , attrs : issue_fields . deep_stringify_keys )
2018-11-20 20:47:30 +05:30
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 )
2017-08-17 22:00:37 +05:30
2021-04-29 21:17:54 +05:30
allow_any_instance_of ( JIRA :: Resource :: Issue ) . to receive ( :key ) . and_return ( issue_key )
2018-11-20 20:47:30 +05:30
allow ( JIRA :: Resource :: Remotelink ) . to receive ( :all ) . and_return ( [ ] )
2015-12-23 02:04:40 +05:30
2021-04-17 20:07:23 +05:30
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 ) )
2018-11-20 20:47:30 +05:30
end
2017-08-17 22:00:37 +05:30
2021-03-11 19:13:27 +05:30
let ( :external_issue ) { ExternalIssue . new ( 'JIRA-123' , project ) }
def close_issue
2021-09-30 23:02:18 +05:30
jira_integration . close_issue ( resource , external_issue , current_user )
2021-03-11 19:13:27 +05:30
end
2019-09-30 21:07:59 +05:30
it 'calls Jira API' do
2021-03-11 19:13:27 +05:30
close_issue
2017-08-17 22:00:37 +05:30
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , comment_url ) . with (
2018-11-20 20:47:30 +05:30
body : / Issue solved with /
) . once
end
2017-09-10 17:25:29 +05:30
2021-03-11 19:13:27 +05:30
it 'tracks usage' do
expect ( Gitlab :: UsageDataCounters :: HLLRedisCounter )
. to receive ( :track_event )
. with ( 'i_ecosystem_jira_service_close_issue' , values : current_user . id )
close_issue
end
2022-08-27 11:52:29 +05:30
it_behaves_like 'Snowplow event tracking' do
subject { close_issue }
let ( :feature_flag_name ) { :route_hll_to_snowplow_phase2 }
let ( :category ) { 'Integrations::Jira' }
let ( :action ) { 'perform_integrations_action' }
let ( :namespace ) { project . namespace }
let ( :user ) { current_user }
let ( :label ) { 'redis_hll_counters.ecosystem.ecosystem_total_unique_counts_monthly' }
let ( :property ) { 'i_ecosystem_jira_service_close_issue' }
end
2019-09-04 21:01:54 +05:30
it 'does not fail if remote_link.all on issue returns nil' do
allow ( JIRA :: Resource :: Remotelink ) . to receive ( :all ) . and_return ( nil )
2021-03-11 19:13:27 +05:30
expect { close_issue } . not_to raise_error
2019-09-04 21:01:54 +05:30
end
2018-11-20 20:47:30 +05:30
# Check https://developer.atlassian.com/jiradev/jira-platform/guides/other/guide-jira-remote-issue-links/fields-in-remote-issue-links
# for more information
2019-09-30 21:07:59 +05:30
it 'creates Remote Link reference in Jira for comment' do
2021-03-11 19:13:27 +05:30
close_issue
2018-11-20 20:47:30 +05:30
favicon_path = " http://localhost/assets/ #{ find_asset ( 'favicon.png' ) . digest_path } "
# Creates comment
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , comment_url )
2019-09-30 21:07:59 +05:30
# Creates Remote Link in Jira issue fields
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , remote_link_url ) . with (
2018-11-20 20:47:30 +05:30
body : hash_including (
GlobalID : 'GitLab' ,
2019-07-07 11:18:12 +05:30
relationship : 'mentioned on' ,
2018-11-20 20:47:30 +05:30
object : {
2020-03-13 15:44:24 +05:30
url : " #{ Gitlab . config . gitlab . url } / #{ project . full_path } /-/commit/ #{ commit_id } " ,
2019-07-07 11:18:12 +05:30
title : " Solved by commit #{ commit_id } . " ,
2018-11-20 20:47:30 +05:30
icon : { title : 'GitLab' , url16x16 : favicon_path } ,
status : { resolved : true }
}
)
) . once
end
2017-09-10 17:25:29 +05:30
2020-01-01 13:55:28 +05:30
context 'when "comment_on_event_enabled" is set to false' do
it 'creates Remote Link reference but does not create comment' do
2021-09-30 23:02:18 +05:30
allow ( jira_integration ) . to receive_messages ( comment_on_event_enabled : false )
2021-03-11 19:13:27 +05:30
close_issue
2020-01-01 13:55:28 +05:30
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . not_to have_requested ( :post , comment_url )
expect ( WebMock ) . to have_requested ( :post , remote_link_url )
2020-01-01 13:55:28 +05:30
end
end
2020-04-08 14:13:33 +05:30
context 'when Remote Link already exists' do
let ( :remote_link ) do
double (
'remote link' ,
object : {
url : " #{ Gitlab . config . gitlab . url } / #{ project . full_path } /-/commit/ #{ commit_id } "
} . with_indifferent_access
)
end
it 'does not create comment' do
allow ( JIRA :: Resource :: Remotelink ) . to receive ( :all ) . and_return ( [ remote_link ] )
expect ( remote_link ) . to receive ( :save! )
2021-03-11 19:13:27 +05:30
close_issue
2020-04-08 14:13:33 +05:30
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . not_to have_requested ( :post , comment_url )
2020-04-08 14:13:33 +05:30
end
end
2018-11-20 20:47:30 +05:30
it 'does not send comment or remote links to issues already closed' do
allow_any_instance_of ( JIRA :: Resource :: Issue ) . to receive ( :resolution ) . and_return ( true )
2017-09-10 17:25:29 +05:30
2021-03-11 19:13:27 +05:30
close_issue
2017-08-17 22:00:37 +05:30
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . not_to have_requested ( :post , comment_url )
expect ( WebMock ) . not_to have_requested ( :post , remote_link_url )
2018-11-20 20:47:30 +05:30
end
2017-08-17 22:00:37 +05:30
2018-11-20 20:47:30 +05:30
it 'does not send comment or remote links to issues with unknown resolution' do
allow_any_instance_of ( JIRA :: Resource :: Issue ) . to receive ( :respond_to? ) . with ( :resolution ) . and_return ( false )
2017-08-17 22:00:37 +05:30
2021-03-11 19:13:27 +05:30
close_issue
2017-08-17 22:00:37 +05:30
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . not_to have_requested ( :post , comment_url )
expect ( WebMock ) . not_to have_requested ( :post , remote_link_url )
2017-08-17 22:00:37 +05:30
end
2018-11-20 20:47:30 +05:30
it 'references the GitLab commit' do
stub_config_setting ( base_url : custom_base_url )
2017-08-17 22:00:37 +05:30
2021-03-11 19:13:27 +05:30
close_issue
2018-11-20 20:47:30 +05:30
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , comment_url ) . with (
2020-03-13 15:44:24 +05:30
body : %r{ #{ custom_base_url } / #{ project . full_path } /-/commit/ #{ commit_id } }
2018-11-20 20:47:30 +05:30
) . 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
2021-03-11 19:13:27 +05:30
close_issue
2017-08-17 22:00:37 +05:30
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , comment_url ) . with (
2020-03-13 15:44:24 +05:30
body : %r{ #{ Gitlab . config . gitlab . url } / #{ project . full_path } /-/commit/ #{ commit_id } }
2018-11-20 20:47:30 +05:30
) . once
end
it 'logs exception when transition id is not valid' do
2022-07-16 23:28:13 +05:30
allow ( jira_integration ) . to receive ( :log_exception )
2021-04-17 20:07:23 +05:30
WebMock . stub_request ( :post , transitions_url ) . with ( basic_auth : %w( jira-username jira-password ) ) . and_raise ( " Bad Request " )
2017-08-17 22:00:37 +05:30
2021-03-11 19:13:27 +05:30
close_issue
2018-11-18 11:00:15 +05:30
2022-07-16 23:28:13 +05:30
expect ( jira_integration ) . to have_received ( :log_exception ) . with (
kind_of ( StandardError ) ,
message : 'Issue transition failed' ,
2020-04-08 14:13:33 +05:30
client_url : " http://jira.example.com "
)
2018-11-18 11:00:15 +05:30
end
2018-11-20 20:47:30 +05:30
it 'calls the api with jira_issue_transition_id' do
2021-03-11 19:13:27 +05:30
close_issue
2018-11-18 11:00:15 +05:30
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , transitions_url ) . with (
body : / "id":"999" /
2018-11-18 11:00:15 +05:30
) . once
end
2021-04-29 21:17:54 +05:30
context 'when custom transition IDs are blank' do
before do
2021-09-30 23:02:18 +05:30
jira_integration . jira_issue_transition_id = ''
2021-04-29 21:17:54 +05:30
end
it 'does not transition the issue' do
close_issue
expect ( WebMock ) . not_to have_requested ( :post , transitions_url )
end
end
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
2021-09-30 23:02:18 +05:30
jira_integration . jira_issue_transition_automatic = true
2021-04-29 21:17:54 +05:30
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
2021-04-17 20:07:23 +05:30
context 'when using multiple transition ids' do
before do
2021-09-30 23:02:18 +05:30
allow ( jira_integration ) . to receive_messages ( jira_issue_transition_id : '1,2,3' )
2021-04-17 20:07:23 +05:30
end
2018-11-18 11:00:15 +05:30
2021-04-17 20:07:23 +05:30
it 'calls the api with transition ids separated by comma' do
2021-03-11 19:13:27 +05:30
close_issue
2018-11-18 11:00:15 +05:30
1 . upto ( 3 ) do | transition_id |
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , transitions_url ) . with (
body : / "id":" #{ transition_id } " /
2018-11-18 11:00:15 +05:30
) . once
end
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , comment_url )
2018-11-18 11:00:15 +05:30
end
2018-11-20 20:47:30 +05:30
it 'calls the api with transition ids separated by semicolon' do
2021-09-30 23:02:18 +05:30
allow ( jira_integration ) . to receive_messages ( jira_issue_transition_id : '1;2;3' )
2018-11-18 11:00:15 +05:30
2021-03-11 19:13:27 +05:30
close_issue
2018-11-18 11:00:15 +05:30
1 . upto ( 3 ) do | transition_id |
2021-04-17 20:07:23 +05:30
expect ( WebMock ) . to have_requested ( :post , transitions_url ) . with (
body : / "id":" #{ transition_id } " /
2018-11-18 11:00:15 +05:30
) . once
end
2021-04-17 20:07:23 +05:30
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
2018-11-18 11:00:15 +05:30
end
end
2015-12-23 02:04:40 +05:30
end
2018-11-20 20:47:30 +05:30
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
2015-12-23 02:04:40 +05:30
end
2020-05-24 23:13:21 +05:30
describe '#create_cross_reference_note' do
2021-03-08 18:12:59 +05:30
let_it_be ( :user ) { build_stubbed ( :user ) }
2021-04-29 21:17:54 +05:30
2020-05-24 23:13:21 +05:30
let ( :jira_issue ) { ExternalIssue . new ( 'JIRA-123' , project ) }
2021-12-11 22:18:48 +05:30
let ( :success_message ) { 'SUCCESS: Successfully posted to http://jira.example.com.' }
let ( :favicon_path ) { " http://localhost/assets/ #{ find_asset ( 'favicon.png' ) . digest_path } " }
2020-05-24 23:13:21 +05:30
2021-09-30 23:02:18 +05:30
subject { jira_integration . create_cross_reference_note ( jira_issue , resource , user ) }
2020-05-24 23:13:21 +05:30
2021-12-11 22:18:48 +05:30
shared_examples 'handles cross-references' do
2022-01-26 12:08:38 +05:30
let ( :resource_name ) { jira_integration . send ( :mentionable_name , resource ) }
2021-12-11 22:18:48 +05:30
let ( :resource_url ) { jira_integration . send ( :build_entity_url , resource_name , resource . to_param ) }
2020-05-24 23:13:21 +05:30
let ( :issue_url ) { " #{ url } /rest/api/2/issue/JIRA-123 " }
let ( :comment_url ) { " #{ issue_url } /comment " }
let ( :remote_link_url ) { " #{ issue_url } /remotelink " }
before do
allow ( JIRA :: Resource :: Remotelink ) . to receive ( :all ) . and_return ( [ ] )
stub_request ( :get , issue_url ) . with ( basic_auth : [ username , password ] )
stub_request ( :post , comment_url ) . with ( basic_auth : [ username , password ] )
stub_request ( :post , remote_link_url ) . with ( basic_auth : [ username , password ] )
end
2021-12-11 22:18:48 +05:30
context 'when enabled' do
before do
allow ( jira_integration ) . to receive ( :can_cross_reference? ) { true }
end
2020-05-24 23:13:21 +05:30
2021-12-11 22:18:48 +05:30
it 'creates a comment and remote link' do
expect ( subject ) . to eq ( success_message )
expect ( WebMock ) . to have_requested ( :post , comment_url ) . with ( body : comment_body ) . once
expect ( WebMock ) . to have_requested ( :post , remote_link_url ) . with (
body : hash_including (
GlobalID : 'GitLab' ,
relationship : 'mentioned on' ,
object : {
url : resource_url ,
title : " #{ resource . model_name . human } - #{ resource . title } " ,
icon : { title : 'GitLab' , url16x16 : favicon_path } ,
status : { resolved : false }
}
)
) . once
end
context 'when comment already exists' do
before do
allow ( jira_integration ) . to receive ( :comment_exists? ) { true }
end
it 'does not create a comment or remote link' do
expect ( subject ) . to be_nil
expect ( WebMock ) . not_to have_requested ( :post , comment_url )
expect ( WebMock ) . not_to have_requested ( :post , remote_link_url )
end
end
context 'when remote link already exists' do
let ( :link ) { double ( object : { 'url' = > resource_url } ) }
before do
allow ( jira_integration ) . to receive ( :find_remote_link ) . and_return ( link )
end
it 'updates the remote link but does not create a comment' do
expect ( link ) . to receive ( :save! )
expect ( subject ) . to eq ( success_message )
expect ( WebMock ) . not_to have_requested ( :post , comment_url )
end
end
end
context 'when disabled' do
before do
allow ( jira_integration ) . to receive ( :can_cross_reference? ) { false }
end
it 'does not create a comment or remote link' do
expect ( subject ) . to eq ( " Events for #{ resource_name . pluralize . humanize ( capitalize : false ) } are disabled. " )
expect ( WebMock ) . not_to have_requested ( :post , comment_url )
expect ( WebMock ) . not_to have_requested ( :post , remote_link_url )
end
end
2021-03-11 19:13:27 +05:30
it 'tracks usage' do
expect ( Gitlab :: UsageDataCounters :: HLLRedisCounter )
. to receive ( :track_event )
. with ( 'i_ecosystem_jira_service_cross_reference' , values : user . id )
subject
end
2022-08-27 11:52:29 +05:30
it_behaves_like 'Snowplow event tracking' do
let ( :feature_flag_name ) { :route_hll_to_snowplow_phase2 }
let ( :category ) { 'Integrations::Jira' }
let ( :action ) { 'perform_integrations_action' }
let ( :namespace ) { project . namespace }
let ( :user ) { current_user }
let ( :label ) { 'redis_hll_counters.ecosystem.ecosystem_total_unique_counts_monthly' }
let ( :property ) { 'i_ecosystem_jira_service_cross_reference' }
end
2020-05-24 23:13:21 +05:30
end
2021-12-11 22:18:48 +05:30
context 'for commits' do
it_behaves_like 'handles cross-references' do
let ( :resource ) { project . commit ( 'master' ) }
let ( :comment_body ) { / mentioned this issue in \ [a commit \ |.* on branch \ [master \ | / }
2020-05-24 23:13:21 +05:30
end
2021-12-11 22:18:48 +05:30
end
2020-05-24 23:13:21 +05:30
2021-12-11 22:18:48 +05:30
context 'for issues' do
it_behaves_like 'handles cross-references' do
let ( :resource ) { build_stubbed ( :issue , project : project ) }
let ( :comment_body ) { / mentioned this issue in \ [a issue \ | / }
2020-05-24 23:13:21 +05:30
end
end
2021-12-11 22:18:48 +05:30
context 'for merge requests' do
it_behaves_like 'handles cross-references' do
let ( :resource ) { build_stubbed ( :merge_request , source_project : project ) }
let ( :comment_body ) { / mentioned this issue in \ [a merge request \ |.* on branch \ [master \ | / }
end
end
2020-05-24 23:13:21 +05:30
2021-12-11 22:18:48 +05:30
context 'for notes' do
it_behaves_like 'handles cross-references' do
let ( :resource ) { build_stubbed ( :note , project : project ) }
let ( :comment_body ) { / mentioned this issue in \ [a note \ | / }
2020-05-24 23:13:21 +05:30
end
2021-12-11 22:18:48 +05:30
end
2020-05-24 23:13:21 +05:30
2021-12-11 22:18:48 +05:30
context 'for snippets' do
it_behaves_like 'handles cross-references' do
let ( :resource ) { build_stubbed ( :snippet , project : project ) }
let ( :comment_body ) { / mentioned this issue in \ [a snippet \ | / }
2020-05-24 23:13:21 +05:30
end
end
end
2020-03-13 15:44:24 +05:30
describe '#test' do
2020-11-24 15:15:51 +05:30
let ( :server_info_results ) { { 'url' = > 'http://url' , 'deploymentType' = > 'Cloud' } }
2017-08-17 22:00:37 +05:30
2020-11-24 15:15:51 +05:30
def server_info
2021-09-30 23:02:18 +05:30
jira_integration . test ( nil )
2017-08-17 22:00:37 +05:30
end
2017-09-10 17:25:29 +05:30
context 'when the test succeeds' do
2020-03-13 15:44:24 +05:30
it 'gets Jira project with URL when API URL not set' do
2020-11-24 15:15:51 +05:30
expect ( server_info ) . to eq ( success : true , result : server_info_results )
expect ( WebMock ) . to have_requested ( :get , / jira.example.com / )
2017-09-10 17:25:29 +05:30
end
2020-03-13 15:44:24 +05:30
it 'gets Jira project with API URL if set' do
2021-09-30 23:02:18 +05:30
jira_integration . update! ( api_url : 'http://jira.api.com' )
2020-03-13 15:44:24 +05:30
2020-11-24 15:15:51 +05:30
expect ( server_info ) . to eq ( success : true , result : server_info_results )
expect ( WebMock ) . to have_requested ( :get , / jira.api.com / )
2017-09-10 17:25:29 +05:30
end
end
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
context 'when the test fails' do
it 'returns result with the error' do
test_url = 'http://jira.example.com/rest/api/2/serverInfo'
2020-06-23 00:09:42 +05:30
error_message = 'Some specific failure.'
2020-03-13 15:44:24 +05:30
WebMock . stub_request ( :get , test_url ) . with ( basic_auth : [ username , password ] )
2020-06-23 00:09:42 +05:30
. to_raise ( JIRA :: HTTPError . new ( double ( message : error_message ) ) )
2017-09-10 17:25:29 +05:30
2022-07-16 23:28:13 +05:30
expect ( jira_integration ) . to receive ( :log_exception ) . with (
kind_of ( JIRA :: HTTPError ) ,
message : 'Error sending message' ,
client_url : 'http://jira.example.com'
2020-03-13 15:44:24 +05:30
)
2021-09-30 23:02:18 +05:30
expect ( jira_integration . test ( nil ) ) . to eq ( success : false , result : error_message )
2017-09-10 17:25:29 +05:30
end
2017-08-17 22:00:37 +05:30
end
end
2015-04-26 12:48:37 +05:30
describe 'project and issue urls' do
context 'when gitlab.yml was initialized' do
2019-09-30 21:07:59 +05:30
it 'is prepopulated with the settings' do
2015-12-23 02:04:40 +05:30
settings = {
2017-09-10 17:25:29 +05:30
'jira' = > {
'url' = > 'http://jira.sample/projects/project_a' ,
'api_url' = > 'http://jira.sample/api'
2015-04-26 12:48:37 +05:30
}
}
allow ( Gitlab . config ) . to receive ( :issues_tracker ) . and_return ( settings )
2021-09-30 23:02:18 +05:30
integration = project . create_jira_integration ( active : true )
2015-04-26 12:48:37 +05:30
2021-09-30 23:02:18 +05:30
expect ( integration . url ) . to eq ( 'http://jira.sample/projects/project_a' )
expect ( integration . api_url ) . to eq ( 'http://jira.sample/api' )
2015-04-26 12:48:37 +05:30
end
end
2019-10-12 21:52:04 +05:30
it 'removes trailing slashes from url' do
2021-09-30 23:02:18 +05:30
integration = described_class . new ( url : 'http://jira.test.com/path/' )
2019-10-12 21:52:04 +05:30
2021-09-30 23:02:18 +05:30
expect ( integration . url ) . to eq ( 'http://jira.test.com/path' )
2019-10-12 21:52:04 +05:30
end
2015-04-26 12:48:37 +05:30
end
2018-11-08 19:23:39 +05:30
2019-12-21 20:55:43 +05:30
describe 'favicon urls' do
2018-11-08 19:23:39 +05:30
it 'includes the standard favicon' do
props = described_class . new . send ( :build_remote_link_props , url : 'http://example.com' , title : 'title' )
expect ( props [ :object ] [ :icon ] [ :url16x16 ] ) . to match %r{ ^http://localhost/assets/favicon(?:- \ h+).png$ }
end
it 'includes returns the custom favicon' do
create :appearance , favicon : fixture_file_upload ( 'spec/fixtures/dk.png' )
props = described_class . new . send ( :build_remote_link_props , url : 'http://example.com' , title : 'title' )
expect ( props [ :object ] [ :icon ] [ :url16x16 ] ) . to match %r{ ^http://localhost/uploads/-/system/appearance/favicon/ \ d+/dk.png$ }
end
end
2019-10-12 21:52:04 +05:30
context 'generating external URLs' do
2021-09-04 01:27:46 +05:30
let ( :integration ) { described_class . new ( url : 'http://jira.test.com/path/' ) }
describe '#web_url' do
it 'handles paths, slashes, and query string' do
expect ( integration . web_url ) . to eq ( integration . url )
expect ( integration . web_url ( 'subpath/' ) ) . to eq ( 'http://jira.test.com/path/subpath' )
expect ( integration . web_url ( '/subpath/' ) ) . to eq ( 'http://jira.test.com/path/subpath' )
expect ( integration . web_url ( 'subpath' , foo : :bar ) ) . to eq ( 'http://jira.test.com/path/subpath?foo=bar' )
end
it 'preserves existing query string' do
integration . url = 'http://jira.test.com/path/?nosso&foo=bar%20bar'
expect ( integration . web_url ) . to eq ( " http://jira.test.com/path?foo=bar%20bar&nosso " )
expect ( integration . web_url ( 'subpath/' ) ) . to eq ( 'http://jira.test.com/path/subpath?foo=bar%20bar&nosso' )
expect ( integration . web_url ( '/subpath/' ) ) . to eq ( 'http://jira.test.com/path/subpath?foo=bar%20bar&nosso' )
expect ( integration . web_url ( 'subpath' , bar : 'baz baz' ) ) . to eq ( 'http://jira.test.com/path/subpath?bar=baz%20baz&foo=bar%20bar&nosso' )
end
it 'returns an empty string if URL is not set' do
integration . url = nil
expect ( integration . web_url ) . to eq ( '' )
end
it 'includes Atlassian referrer for gitlab.com' do
allow ( Gitlab ) . to receive ( :com? ) . and_return ( true )
expect ( integration . web_url ) . to eq ( " http://jira.test.com/path? #{ described_class :: ATLASSIAN_REFERRER_GITLAB_COM . to_query } " )
allow ( Gitlab ) . to receive ( :staging? ) . and_return ( true )
expect ( integration . web_url ) . to eq ( integration . url )
end
it 'includes Atlassian referrer for self-managed' do
allow ( Gitlab ) . to receive ( :dev_or_test_env? ) . and_return ( false )
expect ( integration . web_url ) . to eq ( " http://jira.test.com/path? #{ described_class :: ATLASSIAN_REFERRER_SELF_MANAGED . to_query } " )
end
end
describe '#project_url' do
it 'returns the correct URL' do
expect ( integration . project_url ) . to eq ( 'http://jira.test.com/path' )
end
it 'returns an empty string if URL is not set' do
integration . url = nil
expect ( integration . project_url ) . to eq ( '' )
end
end
2019-10-12 21:52:04 +05:30
describe '#issues_url' do
2021-09-04 01:27:46 +05:30
it 'returns the correct URL' do
expect ( integration . issues_url ) . to eq ( 'http://jira.test.com/path/browse/:id' )
end
it 'returns an empty string if URL is not set' do
integration . url = nil
expect ( integration . issues_url ) . to eq ( '' )
2019-10-12 21:52:04 +05:30
end
end
describe '#new_issue_url' do
2021-09-04 01:27:46 +05:30
it 'returns the correct URL' do
expect ( integration . new_issue_url ) . to eq ( 'http://jira.test.com/path/secure/CreateIssue!default.jspa' )
end
it 'returns an empty string if URL is not set' do
integration . url = nil
expect ( integration . new_issue_url ) . to eq ( '' )
2019-10-12 21:52:04 +05:30
end
end
end
2021-04-29 21:17:54 +05:30
describe '#issue_transition_enabled?' do
it 'returns true if automatic transitions are enabled' do
2021-09-30 23:02:18 +05:30
jira_integration . jira_issue_transition_automatic = true
2021-04-29 21:17:54 +05:30
2021-09-30 23:02:18 +05:30
expect ( jira_integration . issue_transition_enabled? ) . to be ( true )
2021-04-29 21:17:54 +05:30
end
it 'returns true if custom transitions are set' do
2021-09-30 23:02:18 +05:30
jira_integration . jira_issue_transition_id = '1, 2, 3'
2021-04-29 21:17:54 +05:30
2021-09-30 23:02:18 +05:30
expect ( jira_integration . issue_transition_enabled? ) . to be ( true )
2021-04-29 21:17:54 +05:30
end
it 'returns false if automatic and custom transitions are disabled' do
2021-09-30 23:02:18 +05:30
expect ( jira_integration . issue_transition_enabled? ) . to be ( false )
end
end
describe 'valid_connection? and configured?' do
before do
allow ( jira_integration ) . to receive ( :test ) . with ( nil ) . and_return ( test_result )
end
context 'when the test fails' do
let ( :test_result ) { { success : false } }
it 'is falsey' do
expect ( jira_integration ) . not_to be_valid_connection
end
it 'implies that configured? is also falsey' do
expect ( jira_integration ) . not_to be_configured
end
end
context 'when the test succeeds' do
let ( :test_result ) { { success : true } }
it 'is truthy' do
expect ( jira_integration ) . to be_valid_connection
end
context 'when the integration is active' do
before do
jira_integration . active = true
end
it 'implies that configured? is also truthy' do
expect ( jira_integration ) . to be_configured
end
end
context 'when the integration is inactive' do
before do
jira_integration . active = false
end
it 'implies that configured? is falsey' do
expect ( jira_integration ) . not_to be_configured
end
end
2021-04-29 21:17:54 +05:30
end
end
2015-04-26 12:48:37 +05:30
end