diff options
Diffstat (limited to 'spec/models/integrations/jira_spec.rb')
-rw-r--r-- | spec/models/integrations/jira_spec.rb | 304 |
1 files changed, 169 insertions, 135 deletions
diff --git a/spec/models/integrations/jira_spec.rb b/spec/models/integrations/jira_spec.rb index 23ade570383..6ca72d68bbb 100644 --- a/spec/models/integrations/jira_spec.rb +++ b/spec/models/integrations/jira_spec.rb @@ -14,7 +14,7 @@ RSpec.describe Integrations::Jira do let(:password) { 'jira-password' } let(:transition_id) { 'test27' } let(:server_info_results) { { 'deploymentType' => 'Cloud' } } - let(:jira_service) do + let(:jira_integration) do described_class.new( project: project, url: url, @@ -100,20 +100,15 @@ RSpec.describe Integrations::Jira do end describe '#fields' do - let(:service) { create(:jira_service) } + let(:integration) { create(:jira_integration) } - subject(:fields) { service.fields } + subject(:fields) { integration.fields } it 'returns custom fields' do expect(fields.pluck(:name)).to eq(%w[url api_url username password]) end end - describe 'Associations' do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - describe '.reference_pattern' do using RSpec::Parameterized::TableSyntax @@ -146,39 +141,35 @@ RSpec.describe Integrations::Jira do } end - subject { described_class.create!(params) } + subject(:integration) { described_class.create!(params) } it 'does not store data into properties' do - expect(subject.properties).to be_nil + expect(integration.properties).to be_nil end it 'stores data in data_fields correctly' do - service = subject - - expect(service.jira_tracker_data.url).to eq(url) - expect(service.jira_tracker_data.api_url).to eq(api_url) - expect(service.jira_tracker_data.username).to eq(username) - expect(service.jira_tracker_data.password).to eq(password) - expect(service.jira_tracker_data.jira_issue_transition_id).to eq(transition_id) - expect(service.jira_tracker_data.deployment_cloud?).to be_truthy + 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 end context 'when loading serverInfo' do - let(:jira_service) { subject } - - context 'from a Cloud instance' do + context 'with a Cloud instance' do let(:server_info_results) { { 'deploymentType' => 'Cloud' } } it 'is detected' do - expect(jira_service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_cloud end end - context 'from a Server instance' do + context 'with a Server instance' do let(:server_info_results) { { 'deploymentType' => 'Server' } } it 'is detected' do - expect(jira_service.jira_tracker_data.deployment_server?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_server end end @@ -189,7 +180,7 @@ RSpec.describe Integrations::Jira do let(:api_url) { 'http://example-api.atlassian.net' } it 'deployment_type is set to cloud' do - expect(jira_service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_cloud end end @@ -197,7 +188,7 @@ RSpec.describe Integrations::Jira do let(:api_url) { 'http://my-jira-api.someserver.com' } it 'deployment_type is set to server' do - expect(jira_service.jira_tracker_data.deployment_server?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_server end end end @@ -210,7 +201,7 @@ RSpec.describe Integrations::Jira do 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) - expect(jira_service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_cloud end end @@ -219,7 +210,7 @@ RSpec.describe Integrations::Jira do 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) - expect(jira_service.jira_tracker_data.deployment_server?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_server end end end @@ -253,11 +244,11 @@ RSpec.describe Integrations::Jira do context 'reading data' do it 'reads data correctly' do - expect(service.url).to eq(url) - expect(service.api_url).to eq(api_url) - expect(service.username).to eq(username) - expect(service.password).to eq(password) - expect(service.jira_issue_transition_id).to eq(transition_id) + 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) end end @@ -267,15 +258,11 @@ RSpec.describe Integrations::Jira do let_it_be(:new_url) { 'http://jira-new.example.com' } before do - service.update!(username: new_username, url: new_url) - end - - it 'leaves properties field emtpy' do - # expect(service.reload.properties).to be_empty + integration.update!(username: new_username, url: new_url) end it 'stores updated data in jira_tracker_data table' do - data = service.jira_tracker_data.reload + data = integration.jira_tracker_data.reload expect(data.url).to eq(new_url) expect(data.api_url).to eq(api_url) @@ -288,15 +275,15 @@ RSpec.describe Integrations::Jira do context 'when updating the url, api_url, username, or password' do context 'when updating the integration' do it 'updates deployment type' do - service.update!(url: 'http://first.url') - service.jira_tracker_data.update!(deployment_type: 'server') + integration.update!(url: 'http://first.url') + integration.jira_tracker_data.update!(deployment_type: 'server') - expect(service.jira_tracker_data.deployment_server?).to be_truthy + expect(integration.jira_tracker_data.deployment_server?).to be_truthy - service.update!(api_url: 'http://another.url') - service.jira_tracker_data.reload + integration.update!(api_url: 'http://another.url') + integration.jira_tracker_data.reload - expect(service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data.deployment_cloud?).to be_truthy expect(WebMock).to have_requested(:get, /serverInfo/).twice end end @@ -305,34 +292,34 @@ RSpec.describe Integrations::Jira do let(:server_info_results) { {} } it 'updates deployment type' do - service.update!(url: nil, api_url: nil, active: false) + integration.update!(url: nil, api_url: nil, active: false) - service.jira_tracker_data.reload + integration.jira_tracker_data.reload - expect(service.jira_tracker_data.deployment_unknown?).to be_truthy + expect(integration.jira_tracker_data.deployment_unknown?).to be_truthy end end it 'calls serverInfo for url' do - service.update!(url: 'http://first.url') + integration.update!(url: 'http://first.url') expect(WebMock).to have_requested(:get, /serverInfo/) end it 'calls serverInfo for api_url' do - service.update!(api_url: 'http://another.url') + integration.update!(api_url: 'http://another.url') expect(WebMock).to have_requested(:get, /serverInfo/) end it 'calls serverInfo for username' do - service.update!(username: 'test-user') + integration.update!(username: 'test-user') expect(WebMock).to have_requested(:get, /serverInfo/) end it 'calls serverInfo for password' do - service.update!(password: 'test-password') + integration.update!(password: 'test-password') expect(WebMock).to have_requested(:get, /serverInfo/) end @@ -340,7 +327,8 @@ RSpec.describe Integrations::Jira do context 'when not updating the url, api_url, username, or password' do it 'does not update deployment type' do - expect {service.update!(jira_issue_transition_id: 'jira_issue_transition_id')}.to raise_error(ActiveRecord::RecordInvalid) + expect { integration.update!(jira_issue_transition_id: 'jira_issue_transition_id') } + .to raise_error(ActiveRecord::RecordInvalid) expect(WebMock).not_to have_requested(:get, /serverInfo/) end @@ -348,9 +336,9 @@ RSpec.describe Integrations::Jira do context 'when not allowed to test an instance or group' do it 'does not update deployment type' do - allow(service).to receive(:can_test?).and_return(false) + allow(integration).to receive(:testable?).and_return(false) - service.update!(url: 'http://first.url') + integration.update!(url: 'http://first.url') expect(WebMock).not_to have_requested(:get, /serverInfo/) end @@ -368,68 +356,68 @@ RSpec.describe Integrations::Jira do end it 'resets password if url changed' do - service - service.url = 'http://jira_edited.example.com' - service.save! + integration + integration.url = 'http://jira_edited.example.com' + integration.save! - expect(service.reload.url).to eq('http://jira_edited.example.com') - expect(service.password).to be_nil + expect(integration.reload.url).to eq('http://jira_edited.example.com') + expect(integration.password).to be_nil end it 'does not reset password if url "changed" to the same url as before' do - service.url = 'http://jira.example.com' - service.save! + integration.url = 'http://jira.example.com' + integration.save! - expect(service.reload.url).to eq('http://jira.example.com') - expect(service.password).not_to be_nil + expect(integration.reload.url).to eq('http://jira.example.com') + expect(integration.password).not_to be_nil end it 'resets password if url not changed but api url added' do - service.api_url = 'http://jira_edited.example.com/rest/api/2' - service.save! + integration.api_url = 'http://jira_edited.example.com/rest/api/2' + integration.save! - expect(service.reload.api_url).to eq('http://jira_edited.example.com/rest/api/2') - expect(service.password).to be_nil + expect(integration.reload.api_url).to eq('http://jira_edited.example.com/rest/api/2') + expect(integration.password).to be_nil end it 'does not reset password if new url is set together with password, even if it\'s the same password' do - service.url = 'http://jira_edited.example.com' - service.password = password - service.save! + integration.url = 'http://jira_edited.example.com' + integration.password = password + integration.save! - expect(service.password).to eq(password) - expect(service.url).to eq('http://jira_edited.example.com') + expect(integration.password).to eq(password) + expect(integration.url).to eq('http://jira_edited.example.com') end it 'resets password if url changed, even if setter called multiple times' do - service.url = 'http://jira1.example.com/rest/api/2' - service.url = 'http://jira1.example.com/rest/api/2' - service.save! + integration.url = 'http://jira1.example.com/rest/api/2' + integration.url = 'http://jira1.example.com/rest/api/2' + integration.save! - expect(service.password).to be_nil + expect(integration.password).to be_nil end it 'does not reset password if username changed' do - service.username = 'some_name' - service.save! + integration.username = 'some_name' + integration.save! - expect(service.reload.password).to eq(password) + expect(integration.reload.password).to eq(password) end it 'does not reset password if password changed' do - service.url = 'http://jira_edited.example.com' - service.password = 'new_password' - service.save! + integration.url = 'http://jira_edited.example.com' + integration.password = 'new_password' + integration.save! - expect(service.reload.password).to eq('new_password') + expect(integration.reload.password).to eq('new_password') end it 'does not reset password if the password is touched and same as before' do - service.url = 'http://jira_edited.example.com' - service.password = password - service.save! + integration.url = 'http://jira_edited.example.com' + integration.password = password + integration.save! - expect(service.reload.password).to eq(password) + expect(integration.reload.password).to eq(password) end end @@ -443,23 +431,23 @@ RSpec.describe Integrations::Jira do end it 'resets password if api url changed' do - service.api_url = 'http://jira_edited.example.com/rest/api/2' - service.save! + integration.api_url = 'http://jira_edited.example.com/rest/api/2' + integration.save! - expect(service.password).to be_nil + expect(integration.password).to be_nil end it 'does not reset password if url changed' do - service.url = 'http://jira_edited.example.com' - service.save! + integration.url = 'http://jira_edited.example.com' + integration.save! - expect(service.password).to eq(password) + expect(integration.password).to eq(password) end it 'resets password if api url set to empty' do - service.update!(api_url: '') + integration.update!(api_url: '') - expect(service.reload.password).to be_nil + expect(integration.reload.password).to be_nil end end end @@ -472,11 +460,11 @@ RSpec.describe Integrations::Jira do end it 'saves password if new url is set together with password' do - service.url = 'http://jira_edited.example.com/rest/api/2' - service.password = 'password' - service.save! - expect(service.reload.password).to eq('password') - expect(service.reload.url).to eq('http://jira_edited.example.com/rest/api/2') + integration.url = 'http://jira_edited.example.com/rest/api/2' + integration.password = 'password' + integration.save! + expect(integration.reload.password).to eq('password') + expect(integration.reload.url).to eq('http://jira_edited.example.com/rest/api/2') end end end @@ -486,16 +474,16 @@ RSpec.describe Integrations::Jira do # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 context 'when data are stored in properties' do let(:properties) { data_params } - let!(:service) do - create(:jira_service, :without_properties_callback, properties: properties.merge(additional: 'something')) + let!(:integration) do + create(:jira_integration, :without_properties_callback, properties: properties.merge(additional: 'something')) end it_behaves_like 'handles jira fields' end context 'when data are stored in separated fields' do - let(:service) do - create(:jira_service, data_params.merge(properties: {})) + let(:integration) do + create(:jira_integration, data_params.merge(properties: {})) end it_behaves_like 'handles jira fields' @@ -503,8 +491,8 @@ RSpec.describe Integrations::Jira do context 'when data are stored in both properties and separated fields' do let(:properties) { data_params } - let(:service) do - create(:jira_service, :without_properties_callback, active: false, properties: properties).tap do |integration| + let(:integration) do + create(:jira_integration, :without_properties_callback, active: false, properties: properties).tap do |integration| create(:jira_tracker_data, data_params.merge(integration: integration)) end end @@ -522,7 +510,7 @@ RSpec.describe Integrations::Jira do end it 'call the Jira API to get the issue' do - jira_service.find_issue(issue_key) + jira_integration.find_issue(issue_key) expect(WebMock).to have_requested(:get, issue_url) end @@ -531,7 +519,7 @@ RSpec.describe Integrations::Jira do 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, transitions: true) + jira_integration.find_issue(issue_key, rendered_fields: true, transitions: true) expect(WebMock).to have_requested(:get, issue_url) end @@ -558,16 +546,16 @@ RSpec.describe Integrations::Jira do end subject(:close_issue) do - jira_service.close_issue(resource, ExternalIssue.new(issue_key, project)) + jira_integration.close_issue(resource, ExternalIssue.new(issue_key, project)) end before do - jira_service.jira_issue_transition_id = '999' + jira_integration.jira_issue_transition_id = '999' # These stubs are needed to test Integrations::Jira#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: issue_fields.deep_stringify_keys) + open_issue = JIRA::Resource::Issue.new(jira_integration.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) @@ -585,7 +573,7 @@ RSpec.describe Integrations::Jira do let(:external_issue) { ExternalIssue.new('JIRA-123', project) } def close_issue - jira_service.close_issue(resource, external_issue, current_user) + jira_integration.close_issue(resource, external_issue, current_user) end it 'calls Jira API' do @@ -636,7 +624,7 @@ RSpec.describe Integrations::Jira 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_integration).to receive_messages(comment_on_event_enabled: false) close_issue expect(WebMock).not_to have_requested(:post, comment_url) @@ -709,12 +697,12 @@ RSpec.describe Integrations::Jira do end it 'logs exception when transition id is not valid' do - allow(jira_service).to receive(:log_error) + allow(jira_integration).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_integration).to have_received(:log_error).with( "Issue transition failed", error: hash_including( exception_class: 'StandardError', @@ -734,7 +722,7 @@ RSpec.describe Integrations::Jira do context 'when custom transition IDs are blank' do before do - jira_service.jira_issue_transition_id = '' + jira_integration.jira_issue_transition_id = '' end it 'does not transition the issue' do @@ -755,7 +743,7 @@ RSpec.describe Integrations::Jira do end before do - jira_service.jira_issue_transition_automatic = true + jira_integration.jira_issue_transition_automatic = true close_issue end @@ -789,7 +777,7 @@ RSpec.describe Integrations::Jira do context 'when using multiple transition ids' do before do - allow(jira_service).to receive_messages(jira_issue_transition_id: '1,2,3') + allow(jira_integration).to receive_messages(jira_issue_transition_id: '1,2,3') end it 'calls the api with transition ids separated by comma' do @@ -805,7 +793,7 @@ RSpec.describe Integrations::Jira do 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_integration).to receive_messages(jira_issue_transition_id: '1;2;3') close_issue @@ -864,7 +852,7 @@ RSpec.describe Integrations::Jira do let(:jira_issue) { ExternalIssue.new('JIRA-123', project) } - subject { jira_service.create_cross_reference_note(jira_issue, resource, user) } + subject { jira_integration.create_cross_reference_note(jira_issue, resource, user) } shared_examples 'creates a comment on Jira' do let(:issue_url) { "#{url}/rest/api/2/issue/JIRA-123" } @@ -936,7 +924,7 @@ RSpec.describe Integrations::Jira do let(:server_info_results) { { 'url' => 'http://url', 'deploymentType' => 'Cloud' } } def server_info - jira_service.test(nil) + jira_integration.test(nil) end context 'when the test succeeds' do @@ -946,7 +934,7 @@ RSpec.describe Integrations::Jira do end it 'gets Jira project with API URL if set' do - jira_service.update!(api_url: 'http://jira.api.com') + jira_integration.update!(api_url: 'http://jira.api.com') expect(server_info).to eq(success: true, result: server_info_results) expect(WebMock).to have_requested(:get, /jira.api.com/) @@ -961,13 +949,13 @@ RSpec.describe Integrations::Jira do WebMock.stub_request(:get, test_url).with(basic_auth: [username, password]) .to_raise(JIRA::HTTPError.new(double(message: error_message))) - expect(jira_service).to receive(:log_error).with( + expect(jira_integration).to receive(:log_error).with( 'Error sending message', client_url: 'http://jira.example.com', error: error_message ) - expect(jira_service.test(nil)).to eq(success: false, result: error_message) + expect(jira_integration.test(nil)).to eq(success: false, result: error_message) end end end @@ -983,17 +971,17 @@ RSpec.describe Integrations::Jira do } allow(Gitlab.config).to receive(:issues_tracker).and_return(settings) - service = project.create_jira_service(active: true) + integration = project.create_jira_integration(active: true) - expect(service.url).to eq('http://jira.sample/projects/project_a') - expect(service.api_url).to eq('http://jira.sample/api') + expect(integration.url).to eq('http://jira.sample/projects/project_a') + expect(integration.api_url).to eq('http://jira.sample/api') end end it 'removes trailing slashes from url' do - service = described_class.new(url: 'http://jira.test.com/path/') + integration = described_class.new(url: 'http://jira.test.com/path/') - expect(service.url).to eq('http://jira.test.com/path') + expect(integration.url).to eq('http://jira.test.com/path') end end @@ -1093,19 +1081,65 @@ RSpec.describe Integrations::Jira do describe '#issue_transition_enabled?' do it 'returns true if automatic transitions are enabled' do - jira_service.jira_issue_transition_automatic = true + jira_integration.jira_issue_transition_automatic = true - expect(jira_service.issue_transition_enabled?).to be(true) + expect(jira_integration.issue_transition_enabled?).to be(true) end it 'returns true if custom transitions are set' do - jira_service.jira_issue_transition_id = '1, 2, 3' + jira_integration.jira_issue_transition_id = '1, 2, 3' - expect(jira_service.issue_transition_enabled?).to be(true) + expect(jira_integration.issue_transition_enabled?).to be(true) end it 'returns false if automatic and custom transitions are disabled' do - expect(jira_service.issue_transition_enabled?).to be(false) + 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 end end end |