diff options
Diffstat (limited to 'spec/models/integrations/jira_spec.rb')
-rw-r--r-- | spec/models/integrations/jira_spec.rb | 164 |
1 files changed, 154 insertions, 10 deletions
diff --git a/spec/models/integrations/jira_spec.rb b/spec/models/integrations/jira_spec.rb index a4ccae459cf..d3cb386e8e0 100644 --- a/spec/models/integrations/jira_spec.rb +++ b/spec/models/integrations/jira_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Integrations::Jira do +RSpec.describe Integrations::Jira, feature_category: :integrations do include AssetsHelpers let_it_be(:project) { create(:project, :repository) } @@ -11,6 +11,9 @@ RSpec.describe Integrations::Jira do let(:url) { 'http://jira.example.com' } let(:api_url) { 'http://api-jira.example.com' } let(:username) { 'jira-username' } + let(:jira_auth_type) { 0 } + let(:jira_issue_prefix) { '' } + let(:jira_issue_regex) { '' } let(:password) { 'jira-password' } let(:project_key) { nil } let(:transition_id) { 'test27' } @@ -48,9 +51,39 @@ RSpec.describe Integrations::Jira do 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 { is_expected.to validate_presence_of(:jira_auth_type) } + it { is_expected.to validate_length_of(:jira_issue_regex).is_at_most(255) } + it { is_expected.to validate_length_of(:jira_issue_prefix).is_at_most(255) } + it { is_expected.to validate_inclusion_of(:jira_auth_type).in_array([0, 1]) } it_behaves_like 'issue tracker integration URL attribute', :url it_behaves_like 'issue tracker integration URL attribute', :api_url + + context 'with personal_access_token_authorization' do + before do + jira_integration.jira_auth_type = 1 + end + + it { is_expected.not_to validate_presence_of(:username) } + end + + context 'when URL is for Jira Cloud' do + before do + jira_integration.url = 'https://test.atlassian.net' + end + + it 'is valid when jira_auth_type is basic' do + jira_integration.jira_auth_type = 0 + + expect(jira_integration).to be_valid + end + + it 'is invalid when jira_auth_type is PAT' do + jira_integration.jira_auth_type = 1 + + expect(jira_integration).not_to be_valid + end + end end context 'when integration is inactive' do @@ -62,6 +95,10 @@ RSpec.describe Integrations::Jira do 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) } + it { is_expected.not_to validate_presence_of(:jira_auth_type) } + it { is_expected.not_to validate_length_of(:jira_issue_regex).is_at_most(255) } + it { is_expected.not_to validate_length_of(:jira_issue_prefix).is_at_most(255) } + it { is_expected.not_to validate_inclusion_of(:jira_auth_type).in_array([0, 1]) } end describe 'jira_issue_transition_id' do @@ -167,7 +204,7 @@ RSpec.describe Integrations::Jira do subject(:fields) { integration.fields } it 'returns custom fields' do - expect(fields.pluck(:name)).to eq(%w[url api_url username password jira_issue_transition_id]) + expect(fields.pluck(:name)).to eq(%w[url api_url jira_auth_type username password jira_issue_regex jira_issue_prefix jira_issue_transition_id]) end end @@ -202,7 +239,7 @@ RSpec.describe Integrations::Jira do end end - describe '.reference_pattern' do + describe '#reference_pattern' do using RSpec::Parameterized::TableSyntax where(:key, :result) do @@ -216,11 +253,77 @@ RSpec.describe Integrations::Jira do '3EXT_EXT-1234' | '' 'CVE-2022-123' | '' 'CVE-123' | 'CVE-123' + 'abc-JIRA-1234' | 'JIRA-1234' end with_them do specify do - expect(described_class.reference_pattern.match(key).to_s).to eq(result) + expect(jira_integration.reference_pattern.match(key).to_s).to eq(result) + end + end + + context 'with match prefix' do + before do + jira_integration.jira_issue_prefix = 'jira#' + end + + where(:key, :result, :issue_key) do + 'jira##123' | '' | '' + 'jira#1#23#12' | '' | '' + 'jira#JIRA-1234A' | 'jira#JIRA-1234' | 'JIRA-1234' + 'jira#JIRA-1234-some_tag' | 'jira#JIRA-1234' | 'JIRA-1234' + 'JIRA-1234A' | '' | '' + 'JIRA-1234-some_tag' | '' | '' + 'myjira#JIRA-1234-some_tag' | '' | '' + 'MYjira#JIRA-1234-some_tag' | '' | '' + 'my-jira#JIRA-1234-some_tag' | 'jira#JIRA-1234' | 'JIRA-1234' + end + + with_them do + specify do + expect(jira_integration.reference_pattern.match(key).to_s).to eq(result) + + expect(jira_integration.reference_pattern.match(key)[:issue]).to eq(issue_key) unless result.empty? + end + end + end + + context 'with trailing space in jira_issue_prefix' do + before do + jira_integration.jira_issue_prefix = 'Jira# ' + end + + it 'leaves the trailing space' do + expect(jira_integration.jira_issue_prefix).to eq('Jira# ') + end + + it 'pulls the issue ID without a prefix' do + expect(jira_integration.reference_pattern.match('Jira# FOO-123')[:issue]).to eq('FOO-123') + end + end + + context 'with custom issue pattern' do + before do + jira_integration.jira_issue_regex = '[A-Z][0-9]-[0-9]+' + end + + where(:key, :result) do + 'J1-123' | 'J1-123' + 'AAbJ J1-123' | 'J1-123' + '#A1-123' | 'A1-123' + 'J1-1234-some_tag' | 'J1-1234' + 'J1-1234A' | 'J1-1234' + 'J1-1234-some_tag' | 'J1-1234' + 'JI1-123' | '' + 'J1I-123' | '' + 'JI-123' | '' + '#123' | '' + end + + with_them do + specify do + expect(jira_integration.reference_pattern.match(key).to_s).to eq(result) + end end end end @@ -251,7 +354,10 @@ RSpec.describe Integrations::Jira do project: project, url: url, api_url: api_url, + jira_auth_type: jira_auth_type, username: username, password: password, + jira_issue_regex: jira_issue_regex, + jira_issue_prefix: jira_issue_prefix, jira_issue_transition_id: transition_id } end @@ -265,8 +371,11 @@ RSpec.describe Integrations::Jira do it 'stores data in data_fields correctly' do 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.jira_auth_type).to eq(jira_auth_type) 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_regex).to eq(jira_issue_regex) + expect(integration.jira_tracker_data.jira_issue_prefix).to eq(jira_issue_prefix) expect(integration.jira_tracker_data.jira_issue_transition_id).to eq(transition_id) expect(integration.jira_tracker_data.deployment_cloud?).to be_truthy end @@ -469,15 +578,54 @@ RSpec.describe Integrations::Jira do end describe '#client' do + before do + stub_request(:get, 'http://jira.example.com/foo') + end + it 'uses the default GitLab::HTTP timeouts' do timeouts = Gitlab::HTTP::DEFAULT_TIMEOUT_OPTIONS - 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 + + context 'with basic auth' do + before do + jira_integration.jira_auth_type = 0 + end + + it 'uses correct authorization options' do + expect_next_instance_of(JIRA::Client) do |instance| + expect(instance.request_client.options).to include( + additional_cookies: ['OBBasicAuth=fromDialog'], + auth_type: :basic, + use_cookies: true, + password: jira_integration.password, + username: jira_integration.username + ) + end + + jira_integration.client.get('/foo') + end + end + + context 'with personal access token auth' do + before do + jira_integration.jira_auth_type = 1 + end + + it 'uses correct authorization options' do + expect_next_instance_of(JIRA::Client) do |instance| + expect(instance.request_client.options).to include( + default_headers: { "Authorization" => "Bearer #{password}" } + ) + end + + jira_integration.client.get('/foo') + end + end end describe '#find_issue' do @@ -590,7 +738,6 @@ RSpec.describe Integrations::Jira do it_behaves_like 'Snowplow event tracking with RedisHLL context' 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 } @@ -944,7 +1091,6 @@ RSpec.describe Integrations::Jira do end it_behaves_like 'Snowplow event tracking with RedisHLL context' do - let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } let(:category) { 'Integrations::Jira' } let(:action) { 'perform_integrations_action' } let(:namespace) { project.namespace } @@ -1095,9 +1241,7 @@ RSpec.describe Integrations::Jira do expect(integration.web_url).to eq('') end - it 'includes Atlassian referrer for gitlab.com' do - allow(Gitlab).to receive(:com?).and_return(true) - + it 'includes Atlassian referrer for SaaS', :saas do 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) |