summaryrefslogtreecommitdiff
path: root/spec/models/integrations
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
commite8d2c2579383897a1dd7f9debd359abe8ae8373d (patch)
treec42be41678c2586d49a75cabce89322082698334 /spec/models/integrations
parentfc845b37ec3a90aaa719975f607740c22ba6a113 (diff)
downloadgitlab-ce-e8d2c2579383897a1dd7f9debd359abe8ae8373d.tar.gz
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'spec/models/integrations')
-rw-r--r--spec/models/integrations/asana_spec.rb10
-rw-r--r--spec/models/integrations/assembla_spec.rb6
-rw-r--r--spec/models/integrations/bamboo_spec.rb88
-rw-r--r--spec/models/integrations/base_chat_notification_spec.rb107
-rw-r--r--spec/models/integrations/base_issue_tracker_spec.rb12
-rw-r--r--spec/models/integrations/bugzilla_spec.rb15
-rw-r--r--spec/models/integrations/buildkite_spec.rb40
-rw-r--r--spec/models/integrations/campfire_spec.rb10
-rw-r--r--spec/models/integrations/confluence_spec.rb13
-rw-r--r--spec/models/integrations/custom_issue_tracker_spec.rb15
-rw-r--r--spec/models/integrations/datadog_spec.rb20
-rw-r--r--spec/models/integrations/discord_spec.rb23
-rw-r--r--spec/models/integrations/drone_ci_spec.rb58
-rw-r--r--spec/models/integrations/emails_on_push_spec.rb14
-rw-r--r--spec/models/integrations/ewm_spec.rb15
-rw-r--r--spec/models/integrations/external_wiki_spec.rb11
-rw-r--r--spec/models/integrations/flowdock_spec.rb10
-rw-r--r--spec/models/integrations/irker_spec.rb10
-rw-r--r--spec/models/integrations/jenkins_spec.rb92
-rw-r--r--spec/models/integrations/jira_spec.rb304
-rw-r--r--spec/models/integrations/mattermost_slash_commands_spec.rb30
-rw-r--r--spec/models/integrations/microsoft_teams_spec.rb57
-rw-r--r--spec/models/integrations/open_project_spec.rb13
-rw-r--r--spec/models/integrations/packagist_spec.rb10
-rw-r--r--spec/models/integrations/pipelines_email_spec.rb4
-rw-r--r--spec/models/integrations/pivotaltracker_spec.rb31
-rw-r--r--spec/models/integrations/prometheus_spec.rb538
-rw-r--r--spec/models/integrations/pushover_spec.rb10
-rw-r--r--spec/models/integrations/redmine_spec.rb15
-rw-r--r--spec/models/integrations/slack_slash_commands_spec.rb8
-rw-r--r--spec/models/integrations/slack_spec.rb8
-rw-r--r--spec/models/integrations/teamcity_spec.rb84
-rw-r--r--spec/models/integrations/youtrack_spec.rb13
33 files changed, 1081 insertions, 613 deletions
diff --git a/spec/models/integrations/asana_spec.rb b/spec/models/integrations/asana_spec.rb
index 4473478910a..f7e7eb1b0ae 100644
--- a/spec/models/integrations/asana_spec.rb
+++ b/spec/models/integrations/asana_spec.rb
@@ -3,11 +3,6 @@
require 'spec_helper'
RSpec.describe Integrations::Asana do
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
context 'active' do
before do
@@ -42,13 +37,12 @@ RSpec.describe Integrations::Asana do
allow(@asana).to receive_messages(
project: project,
project_id: project.id,
- service_hook: true,
api_key: 'verySecret',
restrict_to_branch: 'master'
)
end
- it 'calls Asana service to create a story' do
+ it 'calls Asana integration to create a story' do
data = create_data_for_commits("Message from commit. related to ##{gid}")
expected_message = "#{data[:user_name]} pushed to branch #{data[:ref]} of #{project.full_name} ( #{data[:commits][0][:url]} ): #{data[:commits][0][:message]}"
@@ -59,7 +53,7 @@ RSpec.describe Integrations::Asana do
@asana.execute(data)
end
- it 'calls Asana service to create a story and close a task' do
+ it 'calls Asana integration to create a story and close a task' do
data = create_data_for_commits('fix #456789')
d1 = double('Asana::Resources::Task')
expect(d1).to receive(:add_comment)
diff --git a/spec/models/integrations/assembla_spec.rb b/spec/models/integrations/assembla_spec.rb
index e5972bce95d..960dfea3dc4 100644
--- a/spec/models/integrations/assembla_spec.rb
+++ b/spec/models/integrations/assembla_spec.rb
@@ -5,11 +5,6 @@ require 'spec_helper'
RSpec.describe Integrations::Assembla do
include StubRequests
- describe "Associations" do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe "Execute" do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
@@ -19,7 +14,6 @@ RSpec.describe Integrations::Assembla do
allow(@assembla_integration).to receive_messages(
project_id: project.id,
project: project,
- service_hook: true,
token: 'verySecret',
subdomain: 'project_name'
)
diff --git a/spec/models/integrations/bamboo_spec.rb b/spec/models/integrations/bamboo_spec.rb
index 39966f7978d..73ebf404828 100644
--- a/spec/models/integrations/bamboo_spec.rb
+++ b/spec/models/integrations/bamboo_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Integrations::Bamboo, :use_clean_rails_memory_store_caching do
let_it_be(:project) { create(:project) }
- subject(:service) do
+ subject(:integration) do
described_class.create!(
project: project,
properties: {
@@ -22,53 +22,48 @@ RSpec.describe Integrations::Bamboo, :use_clean_rails_memory_store_caching do
)
end
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when active' do
before do
- subject.active = true
+ integration.active = true
end
it { is_expected.to validate_presence_of(:build_key) }
it { is_expected.to validate_presence_of(:bamboo_url) }
- it_behaves_like 'issue tracker service URL attribute', :bamboo_url
+ it_behaves_like 'issue tracker integration URL attribute', :bamboo_url
describe '#username' do
it 'does not validate the presence of username if password is nil' do
- subject.password = nil
+ integration.password = nil
- expect(subject).not_to validate_presence_of(:username)
+ expect(integration).not_to validate_presence_of(:username)
end
it 'validates the presence of username if password is present' do
- subject.password = 'secret'
+ integration.password = 'secret'
- expect(subject).to validate_presence_of(:username)
+ expect(integration).to validate_presence_of(:username)
end
end
describe '#password' do
it 'does not validate the presence of password if username is nil' do
- subject.username = nil
+ integration.username = nil
- expect(subject).not_to validate_presence_of(:password)
+ expect(integration).not_to validate_presence_of(:password)
end
it 'validates the presence of password if username is present' do
- subject.username = 'john'
+ integration.username = 'john'
- expect(subject).to validate_presence_of(:password)
+ expect(integration).to validate_presence_of(:password)
end
end
end
- context 'when service is inactive' do
+ context 'when inactive' do
before do
- subject.active = false
+ integration.active = false
end
it { is_expected.not_to validate_presence_of(:build_key) }
@@ -82,45 +77,38 @@ RSpec.describe Integrations::Bamboo, :use_clean_rails_memory_store_caching do
describe 'before_update :reset_password' do
context 'when a password was previously set' do
it 'resets password if url changed' do
- bamboo_integration = service
-
- bamboo_integration.bamboo_url = 'http://gitlab1.com'
- bamboo_integration.save!
+ integration.bamboo_url = 'http://gitlab1.com'
+ integration.save!
- expect(bamboo_integration.password).to be_nil
+ expect(integration.password).to be_nil
end
it 'does not reset password if username changed' do
- bamboo_integration = service
+ integration.username = 'some_name'
+ integration.save!
- bamboo_integration.username = 'some_name'
- bamboo_integration.save!
-
- expect(bamboo_integration.password).to eq('password')
+ expect(integration.password).to eq('password')
end
it "does not reset password if new url is set together with password, even if it's the same password" do
- bamboo_integration = service
-
- bamboo_integration.bamboo_url = 'http://gitlab_edited.com'
- bamboo_integration.password = 'password'
- bamboo_integration.save!
+ integration.bamboo_url = 'http://gitlab_edited.com'
+ integration.password = 'password'
+ integration.save!
- expect(bamboo_integration.password).to eq('password')
- expect(bamboo_integration.bamboo_url).to eq('http://gitlab_edited.com')
+ expect(integration.password).to eq('password')
+ expect(integration.bamboo_url).to eq('http://gitlab_edited.com')
end
end
it 'saves password if new url is set together with password when no password was previously set' do
- bamboo_integration = service
- bamboo_integration.password = nil
+ integration.password = nil
- bamboo_integration.bamboo_url = 'http://gitlab_edited.com'
- bamboo_integration.password = 'password'
- bamboo_integration.save!
+ integration.bamboo_url = 'http://gitlab_edited.com'
+ integration.password = 'password'
+ integration.save!
- expect(bamboo_integration.password).to eq('password')
- expect(bamboo_integration.bamboo_url).to eq('http://gitlab_edited.com')
+ expect(integration.password).to eq('password')
+ expect(integration.bamboo_url).to eq('http://gitlab_edited.com')
end
end
end
@@ -129,29 +117,29 @@ RSpec.describe Integrations::Bamboo, :use_clean_rails_memory_store_caching do
it 'runs update and build action' do
stub_update_and_build_request
- subject.execute(Gitlab::DataBuilder::Push::SAMPLE_DATA)
+ integration.execute(Gitlab::DataBuilder::Push::SAMPLE_DATA)
end
end
describe '#build_page' do
it 'returns the contents of the reactive cache' do
- stub_reactive_cache(service, { build_page: 'foo' }, 'sha', 'ref')
+ stub_reactive_cache(integration, { build_page: 'foo' }, 'sha', 'ref')
- expect(service.build_page('sha', 'ref')).to eq('foo')
+ expect(integration.build_page('sha', 'ref')).to eq('foo')
end
end
describe '#commit_status' do
it 'returns the contents of the reactive cache' do
- stub_reactive_cache(service, { commit_status: 'foo' }, 'sha', 'ref')
+ stub_reactive_cache(integration, { commit_status: 'foo' }, 'sha', 'ref')
- expect(service.commit_status('sha', 'ref')).to eq('foo')
+ expect(integration.commit_status('sha', 'ref')).to eq('foo')
end
end
shared_examples 'reactive cache calculation' do
describe '#build_page' do
- subject { service.calculate_reactive_cache('123', 'unused')[:build_page] }
+ subject { integration.calculate_reactive_cache('123', 'unused')[:build_page] }
it 'returns a specific URL when status is 500' do
stub_request(status: 500)
@@ -183,7 +171,7 @@ RSpec.describe Integrations::Bamboo, :use_clean_rails_memory_store_caching do
end
describe '#commit_status' do
- subject { service.calculate_reactive_cache('123', 'unused')[:commit_status] }
+ subject { integration.calculate_reactive_cache('123', 'unused')[:commit_status] }
it 'sets commit status to :error when status is 500' do
stub_request(status: 500)
diff --git a/spec/models/integrations/base_chat_notification_spec.rb b/spec/models/integrations/base_chat_notification_spec.rb
index 656eaa3bbdd..ac4031a9b7d 100644
--- a/spec/models/integrations/base_chat_notification_spec.rb
+++ b/spec/models/integrations/base_chat_notification_spec.rb
@@ -15,26 +15,8 @@ RSpec.describe Integrations::BaseChatNotification do
it { is_expected.to validate_inclusion_of(:labels_to_be_notified_behavior).in_array(%w[match_any match_all]).allow_blank }
end
- describe '#can_test?' do
- context 'with empty repository' do
- it 'returns true' do
- subject.project = create(:project, :empty_repo)
-
- expect(subject.can_test?).to be true
- end
- end
-
- context 'with repository' do
- it 'returns true' do
- subject.project = create(:project, :repository)
-
- expect(subject.can_test?).to be true
- end
- end
- end
-
describe '#execute' do
- subject(:chat_service) { described_class.new }
+ subject(:chat_integration) { described_class.new }
let_it_be(:project) { create(:project, :repository) }
@@ -43,10 +25,9 @@ RSpec.describe Integrations::BaseChatNotification do
let(:data) { Gitlab::DataBuilder::Push.build_sample(subject.project, user) }
before do
- allow(chat_service).to receive_messages(
+ allow(chat_integration).to receive_messages(
project: project,
project_id: project.id,
- service_hook: true,
webhook: webhook_url
)
@@ -57,8 +38,8 @@ RSpec.describe Integrations::BaseChatNotification do
context 'with a repository' do
it 'returns true' do
- expect(chat_service).to receive(:notify).and_return(true)
- expect(chat_service.execute(data)).to be true
+ expect(chat_integration).to receive(:notify).and_return(true)
+ expect(chat_integration.execute(data)).to be true
end
end
@@ -66,8 +47,8 @@ RSpec.describe Integrations::BaseChatNotification do
it 'returns true' do
subject.project = create(:project, :empty_repo)
- expect(chat_service).to receive(:notify).and_return(true)
- expect(chat_service.execute(data)).to be true
+ expect(chat_integration).to receive(:notify).and_return(true)
+ expect(chat_integration.execute(data)).to be true
end
end
@@ -75,8 +56,8 @@ RSpec.describe Integrations::BaseChatNotification do
it 'does not remove spaces' do
allow(project).to receive(:full_name).and_return('Project Name')
- expect(chat_service).to receive(:get_message).with(any_args, hash_including(project_name: 'Project Name'))
- chat_service.execute(data)
+ expect(chat_integration).to receive(:get_message).with(any_args, hash_including(project_name: 'Project Name'))
+ chat_integration.execute(data)
end
end
@@ -89,76 +70,76 @@ RSpec.describe Integrations::BaseChatNotification do
let(:data) { Gitlab::DataBuilder::Note.build(note, user) }
- shared_examples 'notifies the chat service' do
+ shared_examples 'notifies the chat integration' do
specify do
- expect(chat_service).to receive(:notify).with(any_args)
+ expect(chat_integration).to receive(:notify).with(any_args)
- chat_service.execute(data)
+ chat_integration.execute(data)
end
end
- shared_examples 'does not notify the chat service' do
+ shared_examples 'does not notify the chat integration' do
specify do
- expect(chat_service).not_to receive(:notify).with(any_args)
+ expect(chat_integration).not_to receive(:notify).with(any_args)
- chat_service.execute(data)
+ chat_integration.execute(data)
end
end
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
context 'with label filter' do
- subject(:chat_service) { described_class.new(labels_to_be_notified: '~Bug') }
+ subject(:chat_integration) { described_class.new(labels_to_be_notified: '~Bug') }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
context 'MergeRequest events' do
let(:data) { create(:merge_request, labels: [label]).to_hook_data(user) }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
context 'Issue events' do
let(:data) { issue.to_hook_data(user) }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
end
context 'when labels_to_be_notified_behavior is not defined' do
- subject(:chat_service) { described_class.new(labels_to_be_notified: label_filter) }
+ subject(:chat_integration) { described_class.new(labels_to_be_notified: label_filter) }
context 'no matching labels' do
let(:label_filter) { '~some random label' }
- it_behaves_like 'does not notify the chat service'
+ it_behaves_like 'does not notify the chat integration'
end
context 'only one label matches' do
let(:label_filter) { '~some random label, ~Bug' }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
end
context 'when labels_to_be_notified_behavior is blank' do
- subject(:chat_service) { described_class.new(labels_to_be_notified: label_filter, labels_to_be_notified_behavior: '') }
+ subject(:chat_integration) { described_class.new(labels_to_be_notified: label_filter, labels_to_be_notified_behavior: '') }
context 'no matching labels' do
let(:label_filter) { '~some random label' }
- it_behaves_like 'does not notify the chat service'
+ it_behaves_like 'does not notify the chat integration'
end
context 'only one label matches' do
let(:label_filter) { '~some random label, ~Bug' }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
end
context 'when labels_to_be_notified_behavior is match_any' do
- subject(:chat_service) do
+ subject(:chat_integration) do
described_class.new(
labels_to_be_notified: label_filter,
labels_to_be_notified_behavior: 'match_any'
@@ -168,24 +149,24 @@ RSpec.describe Integrations::BaseChatNotification do
context 'no label filter' do
let(:label_filter) { nil }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
context 'no matching labels' do
let(:label_filter) { '~some random label' }
- it_behaves_like 'does not notify the chat service'
+ it_behaves_like 'does not notify the chat integration'
end
context 'only one label matches' do
let(:label_filter) { '~some random label, ~Bug' }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
end
context 'when labels_to_be_notified_behavior is match_all' do
- subject(:chat_service) do
+ subject(:chat_integration) do
described_class.new(
labels_to_be_notified: label_filter,
labels_to_be_notified_behavior: 'match_all'
@@ -195,31 +176,31 @@ RSpec.describe Integrations::BaseChatNotification do
context 'no label filter' do
let(:label_filter) { nil }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
context 'no matching labels' do
let(:label_filter) { '~some random label' }
- it_behaves_like 'does not notify the chat service'
+ it_behaves_like 'does not notify the chat integration'
end
context 'only one label matches' do
let(:label_filter) { '~some random label, ~Bug' }
- it_behaves_like 'does not notify the chat service'
+ it_behaves_like 'does not notify the chat integration'
end
context 'labels matches exactly' do
let(:label_filter) { '~Bug, ~Backend, ~Community contribution' }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
context 'labels matches but object has more' do
let(:label_filter) { '~Bug, ~Backend' }
- it_behaves_like 'notifies the chat service'
+ it_behaves_like 'notifies the chat integration'
end
context 'labels are distributed on multiple objects' do
@@ -241,22 +222,22 @@ RSpec.describe Integrations::BaseChatNotification do
})
end
- it_behaves_like 'does not notify the chat service'
+ it_behaves_like 'does not notify the chat integration'
end
end
end
context 'with "channel" property' do
before do
- allow(chat_service).to receive(:channel).and_return(channel)
+ allow(chat_integration).to receive(:channel).and_return(channel)
end
context 'empty string' do
let(:channel) { '' }
it 'does not include the channel' do
- expect(chat_service).to receive(:notify).with(any_args, hash_excluding(:channel)).and_return(true)
- expect(chat_service.execute(data)).to be(true)
+ expect(chat_integration).to receive(:notify).with(any_args, hash_excluding(:channel)).and_return(true)
+ expect(chat_integration.execute(data)).to be(true)
end
end
@@ -264,20 +245,20 @@ RSpec.describe Integrations::BaseChatNotification do
let(:channel) { ' ' }
it 'does not include the channel' do
- expect(chat_service).to receive(:notify).with(any_args, hash_excluding(:channel)).and_return(true)
- expect(chat_service.execute(data)).to be(true)
+ expect(chat_integration).to receive(:notify).with(any_args, hash_excluding(:channel)).and_return(true)
+ expect(chat_integration.execute(data)).to be(true)
end
end
end
shared_examples 'with channel specified' do |channel, expected_channels|
before do
- allow(chat_service).to receive(:push_channel).and_return(channel)
+ allow(chat_integration).to receive(:push_channel).and_return(channel)
end
it 'notifies all channels' do
- expect(chat_service).to receive(:notify).with(any_args, hash_including(channel: expected_channels)).and_return(true)
- expect(chat_service.execute(data)).to be(true)
+ expect(chat_integration).to receive(:notify).with(any_args, hash_including(channel: expected_channels)).and_return(true)
+ expect(chat_integration.execute(data)).to be(true)
end
end
diff --git a/spec/models/integrations/base_issue_tracker_spec.rb b/spec/models/integrations/base_issue_tracker_spec.rb
index 0f1bc39929a..25e27e96a84 100644
--- a/spec/models/integrations/base_issue_tracker_spec.rb
+++ b/spec/models/integrations/base_issue_tracker_spec.rb
@@ -7,26 +7,26 @@ RSpec.describe Integrations::BaseIssueTracker do
let(:project) { create :project }
describe 'only one issue tracker per project' do
- let(:service) { Integrations::Redmine.new(project: project, active: true, issue_tracker_data: build(:issue_tracker_data)) }
+ let(:integration) { Integrations::Redmine.new(project: project, active: true, issue_tracker_data: build(:issue_tracker_data)) }
before do
create(:custom_issue_tracker_integration, project: project)
end
- context 'when service is changed manually by user' do
+ context 'when integration is changed manually by user' do
it 'executes the validation' do
- valid = service.valid?(:manual_change)
+ valid = integration.valid?(:manual_change)
expect(valid).to be_falsey
- expect(service.errors[:base]).to include(
+ expect(integration.errors[:base]).to include(
'Another issue tracker is already in use. Only one issue tracker service can be active at a time'
)
end
end
- context 'when service is changed internally' do
+ context 'when integration is changed internally' do
it 'does not execute the validation' do
- expect(service.valid?).to be_truthy
+ expect(integration.valid?).to be_truthy
end
end
end
diff --git a/spec/models/integrations/bugzilla_spec.rb b/spec/models/integrations/bugzilla_spec.rb
index e75fa8dd4d4..432306c8fa8 100644
--- a/spec/models/integrations/bugzilla_spec.rb
+++ b/spec/models/integrations/bugzilla_spec.rb
@@ -3,13 +3,8 @@
require 'spec_helper'
RSpec.describe Integrations::Bugzilla do
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -17,12 +12,12 @@ RSpec.describe Integrations::Bugzilla do
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:issues_url) }
it { is_expected.to validate_presence_of(:new_issue_url) }
- it_behaves_like 'issue tracker service URL attribute', :project_url
- it_behaves_like 'issue tracker service URL attribute', :issues_url
- it_behaves_like 'issue tracker service URL attribute', :new_issue_url
+ it_behaves_like 'issue tracker integration URL attribute', :project_url
+ it_behaves_like 'issue tracker integration URL attribute', :issues_url
+ it_behaves_like 'issue tracker integration URL attribute', :new_issue_url
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
diff --git a/spec/models/integrations/buildkite_spec.rb b/spec/models/integrations/buildkite_spec.rb
index 7dc81da7003..4207ae0d555 100644
--- a/spec/models/integrations/buildkite_spec.rb
+++ b/spec/models/integrations/buildkite_spec.rb
@@ -8,34 +8,32 @@ RSpec.describe Integrations::Buildkite, :use_clean_rails_memory_store_caching do
let(:project) { create(:project) }
- subject(:service) do
+ subject(:integration) do
described_class.create!(
project: project,
properties: {
- service_hook: true,
project_url: 'https://buildkite.com/organization-name/example-pipeline',
token: 'secret-sauce-webhook-token:secret-sauce-status-token'
}
)
end
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
+ it_behaves_like Integrations::HasWebHook do
+ let(:hook_url) { 'https://webhook.buildkite.com/deliver/secret-sauce-webhook-token' }
end
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:token) }
- it_behaves_like 'issue tracker service URL attribute', :project_url
+ it_behaves_like 'issue tracker integration URL attribute', :project_url
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -47,7 +45,7 @@ RSpec.describe Integrations::Buildkite, :use_clean_rails_memory_store_caching do
describe '.supported_events' do
it 'supports push, merge_request, and tag_push events' do
- expect(service.supported_events).to eq %w(push merge_request tag_push)
+ expect(integration.supported_events).to eq %w(push merge_request tag_push)
end
end
@@ -57,18 +55,18 @@ RSpec.describe Integrations::Buildkite, :use_clean_rails_memory_store_caching do
end
it 'always activates SSL verification after saved' do
- service.create_service_hook(enable_ssl_verification: false)
+ integration.create_service_hook(enable_ssl_verification: false)
- service.enable_ssl_verification = false
- service.active = true
+ integration.enable_ssl_verification = false
+ integration.active = true
- expect { service.save! }
- .to change { service.service_hook.enable_ssl_verification }.from(false).to(true)
+ expect { integration.save! }
+ .to change { integration.service_hook.enable_ssl_verification }.from(false).to(true)
end
- describe '#webhook_url' do
+ describe '#hook_url' do
it 'returns the webhook url' do
- expect(service.webhook_url).to eq(
+ expect(integration.hook_url).to eq(
'https://webhook.buildkite.com/deliver/secret-sauce-webhook-token'
)
end
@@ -76,7 +74,7 @@ RSpec.describe Integrations::Buildkite, :use_clean_rails_memory_store_caching do
describe '#commit_status_path' do
it 'returns the correct status page' do
- expect(service.commit_status_path('2ab7834c')).to eq(
+ expect(integration.commit_status_path('2ab7834c')).to eq(
'https://gitlab.buildkite.com/status/secret-sauce-status-token.json?commit=2ab7834c'
)
end
@@ -84,7 +82,7 @@ RSpec.describe Integrations::Buildkite, :use_clean_rails_memory_store_caching do
describe '#build_page' do
it 'returns the correct build page' do
- expect(service.build_page('2ab7834c', nil)).to eq(
+ expect(integration.build_page('2ab7834c', nil)).to eq(
'https://buildkite.com/organization-name/example-pipeline/builds?commit=2ab7834c'
)
end
@@ -92,9 +90,9 @@ RSpec.describe Integrations::Buildkite, :use_clean_rails_memory_store_caching do
describe '#commit_status' do
it 'returns the contents of the reactive cache' do
- stub_reactive_cache(service, { commit_status: 'foo' }, 'sha', 'ref')
+ stub_reactive_cache(integration, { commit_status: 'foo' }, 'sha', 'ref')
- expect(service.commit_status('sha', 'ref')).to eq('foo')
+ expect(integration.commit_status('sha', 'ref')).to eq('foo')
end
end
@@ -104,7 +102,7 @@ RSpec.describe Integrations::Buildkite, :use_clean_rails_memory_store_caching do
'https://gitlab.buildkite.com/status/secret-sauce-status-token.json?commit=123'
end
- subject { service.calculate_reactive_cache('123', 'unused')[:commit_status] }
+ subject { integration.calculate_reactive_cache('123', 'unused')[:commit_status] }
it 'sets commit status to :error when status is 500' do
stub_request(status: 500)
diff --git a/spec/models/integrations/campfire_spec.rb b/spec/models/integrations/campfire_spec.rb
index d68f8e0bd4e..0044e6fae21 100644
--- a/spec/models/integrations/campfire_spec.rb
+++ b/spec/models/integrations/campfire_spec.rb
@@ -5,13 +5,8 @@ require 'spec_helper'
RSpec.describe Integrations::Campfire do
include StubRequests
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -19,7 +14,7 @@ RSpec.describe Integrations::Campfire do
it { is_expected.to validate_presence_of(:token) }
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -37,7 +32,6 @@ RSpec.describe Integrations::Campfire do
allow(@campfire_integration).to receive_messages(
project_id: project.id,
project: project,
- service_hook: true,
token: 'verySecret',
subdomain: 'project-name',
room: 'test-room'
diff --git a/spec/models/integrations/confluence_spec.rb b/spec/models/integrations/confluence_spec.rb
index 08e18c99376..e2f9316bc95 100644
--- a/spec/models/integrations/confluence_spec.rb
+++ b/spec/models/integrations/confluence_spec.rb
@@ -3,17 +3,12 @@
require 'spec_helper'
RSpec.describe Integrations::Confluence do
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
before do
subject.active = active
end
- context 'when service is active' do
+ context 'when integration is active' do
let(:active) { true }
it { is_expected.not_to allow_value('https://example.com').for(:confluence_url) }
@@ -35,7 +30,7 @@ RSpec.describe Integrations::Confluence do
it { is_expected.to validate_presence_of(:confluence_url) }
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
let(:active) { false }
it { is_expected.not_to validate_presence_of(:confluence_url) }
@@ -71,13 +66,13 @@ RSpec.describe Integrations::Confluence do
subject { project.project_setting.has_confluence? }
- it 'sets the property to true when service is active' do
+ it 'sets the property to true when integration is active' do
create(:confluence_integration, project: project, active: true)
is_expected.to be(true)
end
- it 'sets the property to false when service is not active' do
+ it 'sets the property to false when integration is not active' do
create(:confluence_integration, project: project, active: false)
is_expected.to be(false)
diff --git a/spec/models/integrations/custom_issue_tracker_spec.rb b/spec/models/integrations/custom_issue_tracker_spec.rb
index 25f2648e738..e1ffe7a74f0 100644
--- a/spec/models/integrations/custom_issue_tracker_spec.rb
+++ b/spec/models/integrations/custom_issue_tracker_spec.rb
@@ -3,13 +3,8 @@
require 'spec_helper'
RSpec.describe Integrations::CustomIssueTracker do
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -17,12 +12,12 @@ RSpec.describe Integrations::CustomIssueTracker do
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:issues_url) }
it { is_expected.to validate_presence_of(:new_issue_url) }
- it_behaves_like 'issue tracker service URL attribute', :project_url
- it_behaves_like 'issue tracker service URL attribute', :issues_url
- it_behaves_like 'issue tracker service URL attribute', :new_issue_url
+ it_behaves_like 'issue tracker integration URL attribute', :project_url
+ it_behaves_like 'issue tracker integration URL attribute', :issues_url
+ it_behaves_like 'issue tracker integration URL attribute', :new_issue_url
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
diff --git a/spec/models/integrations/datadog_spec.rb b/spec/models/integrations/datadog_spec.rb
index 165b21840e0..e2749ab1bc1 100644
--- a/spec/models/integrations/datadog_spec.rb
+++ b/spec/models/integrations/datadog_spec.rb
@@ -10,13 +10,13 @@ RSpec.describe Integrations::Datadog do
let(:active) { true }
let(:dd_site) { 'datadoghq.com' }
- let(:default_url) { 'https://webhooks-http-intake.logs.datadoghq.com/v1/input/' }
+ let(:default_url) { 'https://webhooks-http-intake.logs.datadoghq.com/api/v2/webhook' }
let(:api_url) { '' }
let(:api_key) { SecureRandom.hex(32) }
let(:dd_env) { 'ci' }
let(:dd_service) { 'awesome-gitlab' }
- let(:expected_hook_url) { default_url + api_key + "?env=#{dd_env}&service=#{dd_service}" }
+ let(:expected_hook_url) { default_url + "?dd-api-key=#{api_key}&env=#{dd_env}&service=#{dd_service}" }
let(:instance) do
described_class.new(
@@ -38,9 +38,9 @@ RSpec.describe Integrations::Datadog do
let(:pipeline_data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
let(:build_data) { Gitlab::DataBuilder::Build.build(build) }
- describe 'associations' do
- it { is_expected.to belong_to(:project) }
- it { is_expected.to have_one(:service_hook) }
+ it_behaves_like Integrations::HasWebHook do
+ let(:integration) { instance }
+ let(:hook_url) { "#{described_class::URL_TEMPLATE % { datadog_domain: dd_site }}?dd-api-key=#{api_key}&env=#{dd_env}&service=#{dd_service}" }
end
describe 'validations' do
@@ -65,7 +65,7 @@ RSpec.describe Integrations::Datadog do
context 'with custom api_url' do
let(:dd_site) { '' }
- let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/v1/input/' }
+ let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/api/v2/webhook' }
it { is_expected.not_to validate_presence_of(:datadog_site) }
it { is_expected.to validate_presence_of(:api_url) }
@@ -91,7 +91,7 @@ RSpec.describe Integrations::Datadog do
end
end
- context 'when service is not active' do
+ context 'when integration is not active' do
let(:active) { false }
it { is_expected.to be_valid }
@@ -107,9 +107,9 @@ RSpec.describe Integrations::Datadog do
end
context 'with custom URL' do
- let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/v1/input/' }
+ let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/api/v2/webhook' }
- it { is_expected.to eq(api_url + api_key + "?env=#{dd_env}&service=#{dd_service}") }
+ it { is_expected.to eq(api_url + "?dd-api-key=#{api_key}&env=#{dd_env}&service=#{dd_service}") }
context 'blank' do
let(:api_url) { '' }
@@ -122,7 +122,7 @@ RSpec.describe Integrations::Datadog do
let(:dd_service) { '' }
let(:dd_env) { '' }
- it { is_expected.to eq(default_url + api_key) }
+ it { is_expected.to eq(default_url + "?dd-api-key=#{api_key}") }
end
end
diff --git a/spec/models/integrations/discord_spec.rb b/spec/models/integrations/discord_spec.rb
index bff6a8ee5b2..b85620782c1 100644
--- a/spec/models/integrations/discord_spec.rb
+++ b/spec/models/integrations/discord_spec.rb
@@ -11,7 +11,9 @@ RSpec.describe Integrations::Discord do
embeds: [
include(
author: include(name: be_present),
- description: be_present
+ description: be_present,
+ color: be_present,
+ timestamp: be_present
)
]
}
@@ -33,7 +35,6 @@ RSpec.describe Integrations::Discord do
allow(subject).to receive_messages(
project: project,
project_id: project.id,
- service_hook: true,
webhook: webhook_url
)
@@ -47,15 +48,19 @@ RSpec.describe Integrations::Discord do
allow(client).to receive(:execute).and_yield(builder)
end
- subject.execute(sample_data)
+ freeze_time do
+ subject.execute(sample_data)
- expect(builder.to_json_hash[:embeds].first).to include(
- description: start_with("#{user.name} pushed to branch [master](http://localhost/#{project.namespace.path}/#{project.path}/commits/master) of"),
- author: hash_including(
- icon_url: start_with('https://www.gravatar.com/avatar/'),
- name: user.name
+ expect(builder.to_json_hash[:embeds].first).to include(
+ description: start_with("#{user.name} pushed to branch [master](http://localhost/#{project.namespace.path}/#{project.path}/commits/master) of"),
+ author: hash_including(
+ icon_url: start_with('https://www.gravatar.com/avatar/'),
+ name: user.name
+ ),
+ color: 16543014,
+ timestamp: Time.now.utc.iso8601
)
- )
+ end
end
context 'DNS rebind to local address' do
diff --git a/spec/models/integrations/drone_ci_spec.rb b/spec/models/integrations/drone_ci_spec.rb
index 137f078edca..062e23d628e 100644
--- a/spec/models/integrations/drone_ci_spec.rb
+++ b/spec/models/integrations/drone_ci_spec.rb
@@ -5,11 +5,6 @@ require 'spec_helper'
RSpec.describe Integrations::DroneCi, :use_clean_rails_memory_store_caching do
include ReactiveCachingHelpers
- describe 'associations' do
- it { is_expected.to belong_to(:project) }
- it { is_expected.to have_one(:service_hook) }
- end
-
describe 'validations' do
context 'active' do
before do
@@ -18,7 +13,7 @@ RSpec.describe Integrations::DroneCi, :use_clean_rails_memory_store_caching do
it { is_expected.to validate_presence_of(:token) }
it { is_expected.to validate_presence_of(:drone_url) }
- it_behaves_like 'issue tracker service URL attribute', :drone_url
+ it_behaves_like 'issue tracker integration URL attribute', :drone_url
end
context 'inactive' do
@@ -32,7 +27,15 @@ RSpec.describe Integrations::DroneCi, :use_clean_rails_memory_store_caching do
end
shared_context :drone_ci_integration do
- let(:drone) { described_class.new }
+ subject(:drone) do
+ described_class.new(
+ project: project,
+ active: true,
+ drone_url: drone_url,
+ token: token
+ )
+ end
+
let(:project) { create(:project, :repository, name: 'project') }
let(:path) { project.full_path }
let(:drone_url) { 'http://drone.example.com' }
@@ -45,16 +48,6 @@ RSpec.describe Integrations::DroneCi, :use_clean_rails_memory_store_caching do
let(:build_page) { "#{drone_url}/gitlab/#{path}/redirect/commits/#{sha}?branch=#{branch}" }
let(:commit_status_path) { "#{drone_url}/gitlab/#{path}/commits/#{sha}?branch=#{branch}&access_token=#{token}" }
- before do
- allow(drone).to receive_messages(
- project_id: project.id,
- project: project,
- active: true,
- drone_url: drone_url,
- token: token
- )
- end
-
def stub_request(status: 200, body: nil)
body ||= %q({"status":"success"})
@@ -66,7 +59,21 @@ RSpec.describe Integrations::DroneCi, :use_clean_rails_memory_store_caching do
end
end
- describe "service page/path methods" do
+ it_behaves_like Integrations::HasWebHook do
+ include_context :drone_ci_integration
+
+ let(:integration) { drone }
+ let(:hook_url) { "#{drone_url}/hook?owner=#{project.namespace.full_path}&name=#{project.path}&access_token=#{token}" }
+
+ it 'does not create a hook if project is not present' do
+ integration.project = nil
+ integration.instance = true
+
+ expect { integration.save! }.not_to change(ServiceHook, :count)
+ end
+ end
+
+ describe "integration page/path methods" do
include_context :drone_ci_integration
it { expect(drone.build_page(sha, branch)).to eq(build_page) }
@@ -137,10 +144,17 @@ RSpec.describe Integrations::DroneCi, :use_clean_rails_memory_store_caching do
Gitlab::DataBuilder::Push.build_sample(project, user)
end
- it do
- service_hook = double
- expect(service_hook).to receive(:execute)
- expect(drone).to receive(:service_hook).and_return(service_hook)
+ it 'executes the webhook' do
+ expect(drone).to receive(:execute_web_hook!).with(push_sample_data)
+
+ drone.execute(push_sample_data)
+ end
+
+ it 'does not try to execute the webhook if the integration is not in a project' do
+ drone.project = nil
+ drone.instance = true
+
+ expect(drone).not_to receive(:execute_web_hook!)
drone.execute(push_sample_data)
end
diff --git a/spec/models/integrations/emails_on_push_spec.rb b/spec/models/integrations/emails_on_push_spec.rb
index c82d4bdff9b..bdca267f6cb 100644
--- a/spec/models/integrations/emails_on_push_spec.rb
+++ b/spec/models/integrations/emails_on_push_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Integrations::EmailsOnPush do
let_it_be(:project) { create_default(:project).freeze }
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -14,7 +14,7 @@ RSpec.describe Integrations::EmailsOnPush do
it { is_expected.to validate_presence_of(:recipients) }
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -27,7 +27,7 @@ RSpec.describe Integrations::EmailsOnPush do
stub_const("#{described_class}::RECIPIENTS_LIMIT", 2)
end
- subject(:service) { described_class.new(project: project, recipients: recipients, active: true) }
+ subject(:integration) { described_class.new(project: project, recipients: recipients, active: true) }
context 'valid number of recipients' do
let(:recipients) { 'foo@bar.com duplicate@example.com Duplicate@example.com invalid-email' }
@@ -43,14 +43,14 @@ RSpec.describe Integrations::EmailsOnPush do
it { is_expected.not_to be_valid }
it 'adds an error message' do
- service.valid?
+ integration.valid?
- expect(service.errors).to contain_exactly('Recipients can\'t exceed 2')
+ expect(integration.errors).to contain_exactly('Recipients can\'t exceed 2')
end
- context 'when service is not active' do
+ context 'when integration is not active' do
before do
- service.active = false
+ integration.active = false
end
it { is_expected.to be_valid }
diff --git a/spec/models/integrations/ewm_spec.rb b/spec/models/integrations/ewm_spec.rb
index 38897adb447..49681fefe55 100644
--- a/spec/models/integrations/ewm_spec.rb
+++ b/spec/models/integrations/ewm_spec.rb
@@ -3,13 +3,8 @@
require 'spec_helper'
RSpec.describe Integrations::Ewm do
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -17,12 +12,12 @@ RSpec.describe Integrations::Ewm do
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:issues_url) }
it { is_expected.to validate_presence_of(:new_issue_url) }
- it_behaves_like 'issue tracker service URL attribute', :project_url
- it_behaves_like 'issue tracker service URL attribute', :issues_url
- it_behaves_like 'issue tracker service URL attribute', :new_issue_url
+ it_behaves_like 'issue tracker integration URL attribute', :project_url
+ it_behaves_like 'issue tracker integration URL attribute', :issues_url
+ it_behaves_like 'issue tracker integration URL attribute', :new_issue_url
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
diff --git a/spec/models/integrations/external_wiki_spec.rb b/spec/models/integrations/external_wiki_spec.rb
index 8c20b810301..e4d6a1c7c84 100644
--- a/spec/models/integrations/external_wiki_spec.rb
+++ b/spec/models/integrations/external_wiki_spec.rb
@@ -3,22 +3,17 @@
require 'spec_helper'
RSpec.describe Integrations::ExternalWiki do
- describe "Associations" do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
it { is_expected.to validate_presence_of(:external_wiki_url) }
- it_behaves_like 'issue tracker service URL attribute', :external_wiki_url
+ it_behaves_like 'issue tracker integration URL attribute', :external_wiki_url
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
diff --git a/spec/models/integrations/flowdock_spec.rb b/spec/models/integrations/flowdock_spec.rb
index 189831fa32d..daafb1b3958 100644
--- a/spec/models/integrations/flowdock_spec.rb
+++ b/spec/models/integrations/flowdock_spec.rb
@@ -3,13 +3,8 @@
require 'spec_helper'
RSpec.describe Integrations::Flowdock do
- describe "Associations" do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -17,7 +12,7 @@ RSpec.describe Integrations::Flowdock do
it { is_expected.to validate_presence_of(:token) }
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -38,7 +33,6 @@ RSpec.describe Integrations::Flowdock do
allow(flowdock_integration).to receive_messages(
project_id: project.id,
project: project,
- service_hook: true,
token: 'verySecret'
)
WebMock.stub_request(:post, api_url)
diff --git a/spec/models/integrations/irker_spec.rb b/spec/models/integrations/irker_spec.rb
index a69be1292e0..8b207e8b43e 100644
--- a/spec/models/integrations/irker_spec.rb
+++ b/spec/models/integrations/irker_spec.rb
@@ -5,13 +5,8 @@ require 'socket'
require 'json'
RSpec.describe Integrations::Irker do
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -19,7 +14,7 @@ RSpec.describe Integrations::Irker do
it { is_expected.to validate_presence_of(:recipients) }
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -46,7 +41,6 @@ RSpec.describe Integrations::Irker do
active: true,
project: project,
project_id: project.id,
- service_hook: true,
server_host: @irker_server.addr[2],
server_port: @irker_server.addr[1],
default_irc_uri: 'irc://chat.freenode.net/',
diff --git a/spec/models/integrations/jenkins_spec.rb b/spec/models/integrations/jenkins_spec.rb
index 2374dfe4480..9eb2a7fc098 100644
--- a/spec/models/integrations/jenkins_spec.rb
+++ b/spec/models/integrations/jenkins_spec.rb
@@ -24,14 +24,14 @@ RSpec.describe Integrations::Jenkins do
let(:jenkins_authorization) { "Basic " + ::Base64.strict_encode64(jenkins_username + ':' + jenkins_password) }
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
+ it_behaves_like Integrations::HasWebHook do
+ let(:integration) { described_class.new(jenkins_params) }
+ let(:hook_url) { "http://#{ERB::Util.url_encode jenkins_username}:#{ERB::Util.url_encode jenkins_password}@jenkins.example.com/project/my_project" }
end
describe 'username validation' do
- before do
- @jenkins_service = described_class.create!(
+ let(:jenkins_integration) do
+ described_class.create!(
active: active,
project: project,
properties: {
@@ -43,9 +43,9 @@ RSpec.describe Integrations::Jenkins do
)
end
- subject { @jenkins_service }
+ subject { jenkins_integration }
- context 'when the service is active' do
+ context 'when the integration is active' do
let(:active) { true }
context 'when password was not touched' do
@@ -74,7 +74,7 @@ RSpec.describe Integrations::Jenkins do
end
end
- context 'when the service is inactive' do
+ context 'when the integration is inactive' do
let(:active) { false }
it { is_expected.not_to validate_presence_of :username }
@@ -84,7 +84,7 @@ RSpec.describe Integrations::Jenkins do
describe '#hook_url' do
let(:username) { nil }
let(:password) { nil }
- let(:jenkins_service) do
+ let(:jenkins_integration) do
described_class.new(
project: project,
properties: {
@@ -96,7 +96,7 @@ RSpec.describe Integrations::Jenkins do
)
end
- subject { jenkins_service.hook_url }
+ subject { jenkins_integration.hook_url }
context 'when the jenkins_url has no relative path' do
let(:jenkins_url) { 'http://jenkins.example.com/' }
@@ -138,10 +138,10 @@ RSpec.describe Integrations::Jenkins do
user = create(:user, username: 'username')
project = create(:project, name: 'project')
push_sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)
- jenkins_service = described_class.create!(jenkins_params)
+ jenkins_integration = described_class.create!(jenkins_params)
stub_request(:post, jenkins_hook_url).with(headers: { 'Authorization' => jenkins_authorization })
- result = jenkins_service.test(push_sample_data)
+ result = jenkins_integration.test(push_sample_data)
expect(result).to eq({ success: true, result: '' })
end
@@ -152,20 +152,20 @@ RSpec.describe Integrations::Jenkins do
let(:namespace) { create(:group, :private) }
let(:project) { create(:project, :private, name: 'project', namespace: namespace) }
let(:push_sample_data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
- let(:jenkins_service) { described_class.create!(jenkins_params) }
+ let(:jenkins_integration) { described_class.create!(jenkins_params) }
before do
stub_request(:post, jenkins_hook_url)
end
it 'invokes the Jenkins API' do
- jenkins_service.execute(push_sample_data)
+ jenkins_integration.execute(push_sample_data)
expect(a_request(:post, jenkins_hook_url)).to have_been_made.once
end
it 'adds default web hook headers to the request' do
- jenkins_service.execute(push_sample_data)
+ jenkins_integration.execute(push_sample_data)
expect(
a_request(:post, jenkins_hook_url)
@@ -174,7 +174,7 @@ RSpec.describe Integrations::Jenkins do
end
it 'request url contains properly serialized username and password' do
- jenkins_service.execute(push_sample_data)
+ jenkins_integration.execute(push_sample_data)
expect(
a_request(:post, 'http://jenkins.example.com/project/my_project')
@@ -187,8 +187,8 @@ RSpec.describe Integrations::Jenkins do
let(:project) { create(:project) }
context 'when a password was previously set' do
- before do
- @jenkins_service = described_class.create!(
+ let(:jenkins_integration) do
+ described_class.create!(
project: project,
properties: {
jenkins_url: 'http://jenkins.example.com/',
@@ -199,42 +199,47 @@ RSpec.describe Integrations::Jenkins do
end
it 'resets password if url changed' do
- @jenkins_service.jenkins_url = 'http://jenkins-edited.example.com/'
- @jenkins_service.save!
- expect(@jenkins_service.password).to be_nil
+ jenkins_integration.jenkins_url = 'http://jenkins-edited.example.com/'
+ jenkins_integration.save!
+
+ expect(jenkins_integration.password).to be_nil
end
it 'resets password if username is blank' do
- @jenkins_service.username = ''
- @jenkins_service.save!
- expect(@jenkins_service.password).to be_nil
+ jenkins_integration.username = ''
+ jenkins_integration.save!
+
+ expect(jenkins_integration.password).to be_nil
end
it 'does not reset password if username changed' do
- @jenkins_service.username = 'some_name'
- @jenkins_service.save!
- expect(@jenkins_service.password).to eq('password')
+ jenkins_integration.username = 'some_name'
+ jenkins_integration.save!
+
+ expect(jenkins_integration.password).to eq('password')
end
it 'does not reset password if new url is set together with password, even if it\'s the same password' do
- @jenkins_service.jenkins_url = 'http://jenkins_edited.example.com/'
- @jenkins_service.password = 'password'
- @jenkins_service.save!
- expect(@jenkins_service.password).to eq('password')
- expect(@jenkins_service.jenkins_url).to eq('http://jenkins_edited.example.com/')
+ jenkins_integration.jenkins_url = 'http://jenkins_edited.example.com/'
+ jenkins_integration.password = 'password'
+ jenkins_integration.save!
+
+ expect(jenkins_integration.password).to eq('password')
+ expect(jenkins_integration.jenkins_url).to eq('http://jenkins_edited.example.com/')
end
it 'resets password if url changed, even if setter called multiple times' do
- @jenkins_service.jenkins_url = 'http://jenkins1.example.com/'
- @jenkins_service.jenkins_url = 'http://jenkins1.example.com/'
- @jenkins_service.save!
- expect(@jenkins_service.password).to be_nil
+ jenkins_integration.jenkins_url = 'http://jenkins1.example.com/'
+ jenkins_integration.jenkins_url = 'http://jenkins1.example.com/'
+ jenkins_integration.save!
+
+ expect(jenkins_integration.password).to be_nil
end
end
context 'when no password was previously set' do
- before do
- @jenkins_service = described_class.create!(
+ let(:jenkins_integration) do
+ described_class.create!(
project: create(:project),
properties: {
jenkins_url: 'http://jenkins.example.com/',
@@ -244,11 +249,12 @@ RSpec.describe Integrations::Jenkins do
end
it 'saves password if new url is set together with password' do
- @jenkins_service.jenkins_url = 'http://jenkins_edited.example.com/'
- @jenkins_service.password = 'password'
- @jenkins_service.save!
- expect(@jenkins_service.password).to eq('password')
- expect(@jenkins_service.jenkins_url).to eq('http://jenkins_edited.example.com/')
+ jenkins_integration.jenkins_url = 'http://jenkins_edited.example.com/'
+ jenkins_integration.password = 'password'
+ jenkins_integration.save!
+
+ expect(jenkins_integration.password).to eq('password')
+ expect(jenkins_integration.jenkins_url).to eq('http://jenkins_edited.example.com/')
end
end
end
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
diff --git a/spec/models/integrations/mattermost_slash_commands_spec.rb b/spec/models/integrations/mattermost_slash_commands_spec.rb
index c8a6584591c..b6abe00469b 100644
--- a/spec/models/integrations/mattermost_slash_commands_spec.rb
+++ b/spec/models/integrations/mattermost_slash_commands_spec.rb
@@ -5,27 +5,29 @@ require 'spec_helper'
RSpec.describe Integrations::MattermostSlashCommands do
it_behaves_like Integrations::BaseSlashCommands
- context 'Mattermost API' do
+ describe 'Mattermost API' do
let(:project) { create(:project) }
- let(:service) { project.build_mattermost_slash_commands_service }
+ let(:integration) { project.build_mattermost_slash_commands_integration }
let(:user) { create(:user) }
before do
session = ::Mattermost::Session.new(nil)
session.base_uri = 'http://mattermost.example.com'
- allow_any_instance_of(::Mattermost::Client).to receive(:with_session)
- .and_yield(session)
+ allow(session).to receive(:with_session).and_yield(session)
+ allow(::Mattermost::Session).to receive(:new).and_return(session)
end
describe '#configure' do
subject do
- service.configure(user, team_id: 'abc',
- trigger: 'gitlab', url: 'http://trigger.url',
- icon_url: 'http://icon.url/icon.png')
+ integration.configure(user,
+ team_id: 'abc',
+ trigger: 'gitlab',
+ url: 'http://trigger.url',
+ icon_url: 'http://icon.url/icon.png')
end
- context 'the requests succeeds' do
+ context 'when the request succeeds' do
before do
stub_request(:post, 'http://mattermost.example.com/api/v4/commands')
.with(body: {
@@ -48,18 +50,18 @@ RSpec.describe Integrations::MattermostSlashCommands do
)
end
- it 'saves the service' do
+ it 'saves the integration' do
expect { subject }.to change { project.integrations.count }.by(1)
end
it 'saves the token' do
subject
- expect(service.reload.token).to eq('token')
+ expect(integration.reload.token).to eq('token')
end
end
- context 'an error is received' do
+ context 'when an error is received' do
before do
stub_request(:post, 'http://mattermost.example.com/api/v4/commands')
.to_return(
@@ -86,10 +88,10 @@ RSpec.describe Integrations::MattermostSlashCommands do
describe '#list_teams' do
subject do
- service.list_teams(user)
+ integration.list_teams(user)
end
- context 'the requests succeeds' do
+ context 'when the request succeeds' do
before do
stub_request(:get, 'http://mattermost.example.com/api/v4/users/me/teams')
.to_return(
@@ -104,7 +106,7 @@ RSpec.describe Integrations::MattermostSlashCommands do
end
end
- context 'an error is received' do
+ context 'when an error is received' do
before do
stub_request(:get, 'http://mattermost.example.com/api/v4/users/me/teams')
.to_return(
diff --git a/spec/models/integrations/microsoft_teams_spec.rb b/spec/models/integrations/microsoft_teams_spec.rb
index 2f1be233eb2..21b9a005746 100644
--- a/spec/models/integrations/microsoft_teams_spec.rb
+++ b/spec/models/integrations/microsoft_teams_spec.rb
@@ -3,25 +3,20 @@
require 'spec_helper'
RSpec.describe Integrations::MicrosoftTeams do
- let(:chat_service) { described_class.new }
+ let(:chat_integration) { described_class.new }
let(:webhook_url) { 'https://example.gitlab.com/' }
- describe "Associations" do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
it { is_expected.to validate_presence_of(:webhook) }
- it_behaves_like 'issue tracker service URL attribute', :webhook
+ it_behaves_like 'issue tracker integration URL attribute', :webhook
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -42,10 +37,9 @@ RSpec.describe Integrations::MicrosoftTeams do
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
before do
- allow(chat_service).to receive_messages(
+ allow(chat_integration).to receive_messages(
project: project,
project_id: project.id,
- service_hook: true,
webhook: webhook_url
)
@@ -58,28 +52,29 @@ RSpec.describe Integrations::MicrosoftTeams do
end
it "calls Microsoft Teams API for push events" do
- chat_service.execute(push_sample_data)
+ chat_integration.execute(push_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
it 'specifies the webhook when it is configured' do
- expect(::MicrosoftTeams::Notifier).to receive(:new).with(webhook_url).and_return(double(:microsoft_teams_service).as_null_object)
+ integration = double(:microsoft_teams_integration).as_null_object
+ expect(::MicrosoftTeams::Notifier).to receive(:new).with(webhook_url).and_return(integration)
- chat_service.execute(push_sample_data)
+ chat_integration.execute(push_sample_data)
end
end
context 'with issue events' do
let(:opts) { { title: 'Awesome issue', description: 'please fix' } }
let(:issues_sample_data) do
- service = Issues::CreateService.new(project: project, current_user: user, params: opts)
+ service = Issues::CreateService.new(project: project, current_user: user, params: opts, spam_params: nil)
issue = service.execute
service.hook_data(issue, 'open')
end
it "calls Microsoft Teams API" do
- chat_service.execute(issues_sample_data)
+ chat_integration.execute(issues_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@@ -106,7 +101,7 @@ RSpec.describe Integrations::MicrosoftTeams do
end
it "calls Microsoft Teams API" do
- chat_service.execute(merge_sample_data)
+ chat_integration.execute(merge_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@@ -126,7 +121,7 @@ RSpec.describe Integrations::MicrosoftTeams do
let(:wiki_page_sample_data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, 'create') }
it "calls Microsoft Teams API" do
- chat_service.execute(wiki_page_sample_data)
+ chat_integration.execute(wiki_page_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@@ -138,10 +133,9 @@ RSpec.describe Integrations::MicrosoftTeams do
let(:project) { create(:project, :repository, creator: user) }
before do
- allow(chat_service).to receive_messages(
+ allow(chat_integration).to receive_messages(
project: project,
project_id: project.id,
- service_hook: true,
webhook: webhook_url
)
@@ -159,7 +153,7 @@ RSpec.describe Integrations::MicrosoftTeams do
it "calls Microsoft Teams API for commit comment events" do
data = Gitlab::DataBuilder::Note.build(commit_note, user)
- chat_service.execute(data)
+ chat_integration.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@@ -174,7 +168,7 @@ RSpec.describe Integrations::MicrosoftTeams do
it "calls Microsoft Teams API for merge request comment events" do
data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
- chat_service.execute(data)
+ chat_integration.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@@ -188,7 +182,7 @@ RSpec.describe Integrations::MicrosoftTeams do
it "calls Microsoft Teams API for issue comment events" do
data = Gitlab::DataBuilder::Note.build(issue_note, user)
- chat_service.execute(data)
+ chat_integration.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@@ -203,7 +197,7 @@ RSpec.describe Integrations::MicrosoftTeams do
it "calls Microsoft Teams API for snippet comment events" do
data = Gitlab::DataBuilder::Note.build(snippet_note, user)
- chat_service.execute(data)
+ chat_integration.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
@@ -221,9 +215,8 @@ RSpec.describe Integrations::MicrosoftTeams do
end
before do
- allow(chat_service).to receive_messages(
+ allow(chat_integration).to receive_messages(
project: project,
- service_hook: true,
webhook: webhook_url
)
end
@@ -231,14 +224,14 @@ RSpec.describe Integrations::MicrosoftTeams do
shared_examples 'call Microsoft Teams API' do |branches_to_be_notified: nil|
before do
WebMock.stub_request(:post, webhook_url)
- chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
+ chat_integration.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
end
it 'calls Microsoft Teams API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
data[:markdown] = true
- chat_service.execute(data)
+ chat_integration.execute(data)
message = Integrations::ChatMessage::PipelineMessage.new(data)
@@ -250,11 +243,11 @@ RSpec.describe Integrations::MicrosoftTeams do
shared_examples 'does not call Microsoft Teams API' do |branches_to_be_notified: nil|
before do
- chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
+ chat_integration.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
end
it 'does not call Microsoft Teams API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
- result = chat_service.execute(data)
+ result = chat_integration.execute(data)
expect(result).to be_falsy
end
@@ -272,7 +265,7 @@ RSpec.describe Integrations::MicrosoftTeams do
context 'with default to notify_only_broken_pipelines' do
it 'does not call Microsoft Teams API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
- result = chat_service.execute(data)
+ result = chat_integration.execute(data)
expect(result).to be_falsy
end
@@ -280,7 +273,7 @@ RSpec.describe Integrations::MicrosoftTeams do
context 'with setting notify_only_broken_pipelines to false' do
before do
- chat_service.notify_only_broken_pipelines = false
+ chat_integration.notify_only_broken_pipelines = false
end
it_behaves_like 'call Microsoft Teams API'
diff --git a/spec/models/integrations/open_project_spec.rb b/spec/models/integrations/open_project_spec.rb
index e5b976dc91d..789911acae8 100644
--- a/spec/models/integrations/open_project_spec.rb
+++ b/spec/models/integrations/open_project_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Integrations::OpenProject do
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -13,11 +13,11 @@ RSpec.describe Integrations::OpenProject do
it { is_expected.to validate_presence_of(:token) }
it { is_expected.to validate_presence_of(:project_identifier_code) }
- it_behaves_like 'issue tracker service URL attribute', :url
- it_behaves_like 'issue tracker service URL attribute', :api_url
+ it_behaves_like 'issue tracker integration URL attribute', :url
+ it_behaves_like 'issue tracker integration URL attribute', :api_url
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -27,9 +27,4 @@ RSpec.describe Integrations::OpenProject do
it { is_expected.not_to validate_presence_of(:project_identifier_code) }
end
end
-
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
end
diff --git a/spec/models/integrations/packagist_spec.rb b/spec/models/integrations/packagist_spec.rb
index 48f7e81adca..dce96890522 100644
--- a/spec/models/integrations/packagist_spec.rb
+++ b/spec/models/integrations/packagist_spec.rb
@@ -24,23 +24,23 @@ RSpec.describe Integrations::Packagist do
let(:packagist_server) { 'https://packagist.example.com' }
let(:project) { create(:project) }
- describe "Associations" do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
+ it_behaves_like Integrations::HasWebHook do
+ let(:integration) { described_class.new(packagist_params) }
+ let(:hook_url) { "#{packagist_server}/api/update-package?username=#{packagist_username}&apiToken=#{packagist_token}" }
end
describe '#execute' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:push_sample_data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
- let(:packagist_service) { described_class.create!(packagist_params) }
+ let(:packagist_integration) { described_class.create!(packagist_params) }
before do
stub_request(:post, packagist_hook_url)
end
it 'calls Packagist API' do
- packagist_service.execute(push_sample_data)
+ packagist_integration.execute(push_sample_data)
expect(a_request(:post, packagist_hook_url)).to have_been_made.once
end
diff --git a/spec/models/integrations/pipelines_email_spec.rb b/spec/models/integrations/pipelines_email_spec.rb
index 90055b04bb8..761049f25fe 100644
--- a/spec/models/integrations/pipelines_email_spec.rb
+++ b/spec/models/integrations/pipelines_email_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Integrations::PipelinesEmail, :mailer do
end
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -28,7 +28,7 @@ RSpec.describe Integrations::PipelinesEmail, :mailer do
it { is_expected.to validate_presence_of(:recipients) }
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
diff --git a/spec/models/integrations/pivotaltracker_spec.rb b/spec/models/integrations/pivotaltracker_spec.rb
index 2ce90b6f739..bf8458a376c 100644
--- a/spec/models/integrations/pivotaltracker_spec.rb
+++ b/spec/models/integrations/pivotaltracker_spec.rb
@@ -5,13 +5,8 @@ require 'spec_helper'
RSpec.describe Integrations::Pivotaltracker do
include StubRequests
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -19,7 +14,7 @@ RSpec.describe Integrations::Pivotaltracker do
it { is_expected.to validate_presence_of(:token) }
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -29,9 +24,9 @@ RSpec.describe Integrations::Pivotaltracker do
end
describe 'Execute' do
- let(:service) do
- described_class.new.tap do |service|
- service.token = 'secret_api_token'
+ let(:integration) do
+ described_class.new.tap do |integration|
+ integration.token = 'secret_api_token'
end
end
@@ -59,7 +54,7 @@ RSpec.describe Integrations::Pivotaltracker do
end
it 'posts correct message' do
- service.execute(push_data)
+ integration.execute(push_data)
expect(WebMock).to have_requested(:post, stubbed_hostname(url)).with(
body: {
'source_commit' => {
@@ -77,22 +72,22 @@ RSpec.describe Integrations::Pivotaltracker do
end
context 'when allowed branches is specified' do
- let(:service) do
- super().tap do |service|
- service.restrict_to_branch = 'master,v10'
+ let(:integration) do
+ super().tap do |integration|
+ integration.restrict_to_branch = 'master,v10'
end
end
it 'posts message if branch is in the list' do
- service.execute(push_data(branch: 'master'))
- service.execute(push_data(branch: 'v10'))
+ integration.execute(push_data(branch: 'master'))
+ integration.execute(push_data(branch: 'v10'))
expect(WebMock).to have_requested(:post, stubbed_hostname(url)).twice
end
it 'does not post message if branch is not in the list' do
- service.execute(push_data(branch: 'mas'))
- service.execute(push_data(branch: 'v11'))
+ integration.execute(push_data(branch: 'mas'))
+ integration.execute(push_data(branch: 'v11'))
expect(WebMock).not_to have_requested(:post, stubbed_hostname(url))
end
diff --git a/spec/models/integrations/prometheus_spec.rb b/spec/models/integrations/prometheus_spec.rb
new file mode 100644
index 00000000000..f6f242bf58e
--- /dev/null
+++ b/spec/models/integrations/prometheus_spec.rb
@@ -0,0 +1,538 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require 'googleauth'
+
+RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching, :snowplow do
+ include PrometheusHelpers
+ include ReactiveCachingHelpers
+
+ let_it_be_with_reload(:project) { create(:prometheus_project) }
+
+ let(:integration) { project.prometheus_integration }
+
+ context 'redirects' do
+ it 'does not follow redirects' do
+ redirect_to = 'https://redirected.example.com'
+ redirect_req_stub = stub_prometheus_request(prometheus_query_url('1'), status: 302, headers: { location: redirect_to })
+ redirected_req_stub = stub_prometheus_request(redirect_to, body: { 'status': 'success' })
+
+ result = integration.test
+
+ # result = { success: false, result: error }
+ expect(result[:success]).to be_falsy
+ expect(result[:result]).to be_instance_of(Gitlab::PrometheusClient::UnexpectedResponseError)
+
+ expect(redirect_req_stub).to have_been_requested
+ expect(redirected_req_stub).not_to have_been_requested
+ end
+ end
+
+ describe 'Validations' do
+ context 'when manual_configuration is enabled' do
+ before do
+ integration.manual_configuration = true
+ end
+
+ it 'validates presence of api_url' do
+ expect(integration).to validate_presence_of(:api_url)
+ end
+ end
+
+ context 'when manual configuration is disabled' do
+ before do
+ integration.manual_configuration = false
+ end
+
+ it 'does not validate presence of api_url' do
+ expect(integration).not_to validate_presence_of(:api_url)
+ expect(integration.valid?).to eq(true)
+ end
+
+ context 'local connections allowed' do
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+ end
+
+ it 'does not validate presence of api_url' do
+ expect(integration).not_to validate_presence_of(:api_url)
+ expect(integration.valid?).to eq(true)
+ end
+ end
+ end
+
+ context 'when the api_url domain points to localhost or local network' do
+ let(:domain) { Addressable::URI.parse(integration.api_url).hostname }
+
+ it 'cannot query' do
+ expect(integration.can_query?).to be true
+
+ aggregate_failures do
+ ['127.0.0.1', '192.168.2.3'].each do |url|
+ allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)])
+
+ expect(integration.can_query?).to be false
+ end
+ end
+ end
+
+ it 'can query when local requests are allowed' do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+
+ aggregate_failures do
+ ['127.0.0.1', '192.168.2.3'].each do |url|
+ allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)])
+
+ expect(integration.can_query?).to be true
+ end
+ end
+ end
+
+ context 'with self-monitoring project and internal Prometheus' do
+ before do
+ integration.api_url = 'http://localhost:9090'
+
+ stub_application_setting(self_monitoring_project_id: project.id)
+ stub_config(prometheus: { enable: true, server_address: 'localhost:9090' })
+ end
+
+ it 'allows self-monitoring project to connect to internal Prometheus' do
+ aggregate_failures do
+ ['127.0.0.1', '192.168.2.3'].each do |url|
+ allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)])
+
+ expect(integration.can_query?).to be true
+ end
+ end
+ end
+
+ it 'does not allow self-monitoring project to connect to other local URLs' do
+ integration.api_url = 'http://localhost:8000'
+
+ aggregate_failures do
+ ['127.0.0.1', '192.168.2.3'].each do |url|
+ allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)])
+
+ expect(integration.can_query?).to be false
+ end
+ end
+ end
+ end
+ end
+ end
+
+ describe 'callbacks' do
+ context 'after_create' do
+ let(:project) { create(:project) }
+ let(:integration) { build(:prometheus_integration, project: project) }
+
+ subject(:create_integration) { integration.save! }
+
+ it 'creates default alerts' do
+ expect(Prometheus::CreateDefaultAlertsWorker)
+ .to receive(:perform_async)
+ .with(project.id)
+
+ create_integration
+ end
+
+ context 'no project exists' do
+ let(:integration) { build(:prometheus_integration, :instance) }
+
+ it 'does not create default alerts' do
+ expect(Prometheus::CreateDefaultAlertsWorker)
+ .not_to receive(:perform_async)
+
+ create_integration
+ end
+ end
+ end
+ end
+
+ describe '#test' do
+ before do
+ integration.manual_configuration = true
+ end
+
+ let!(:req_stub) { stub_prometheus_request(prometheus_query_url('1'), body: prometheus_value_body('vector')) }
+
+ context 'success' do
+ it 'reads the discovery endpoint' do
+ expect(integration.test[:result]).to eq('Checked API endpoint')
+ expect(integration.test[:success]).to be_truthy
+ expect(req_stub).to have_been_requested.twice
+ end
+ end
+
+ context 'failure' do
+ let!(:req_stub) { stub_prometheus_request(prometheus_query_url('1'), status: 404) }
+
+ it 'fails to read the discovery endpoint' do
+ expect(integration.test[:success]).to be_falsy
+ expect(req_stub).to have_been_requested
+ end
+ end
+ end
+
+ describe '#prometheus_client' do
+ let(:api_url) { 'http://some_url' }
+
+ before do
+ integration.active = true
+ integration.api_url = api_url
+ integration.manual_configuration = manual_configuration
+ end
+
+ context 'manual configuration is enabled' do
+ let(:manual_configuration) { true }
+
+ it 'calls valid?' do
+ allow(integration).to receive(:valid?).and_call_original
+
+ expect(integration.prometheus_client).not_to be_nil
+
+ expect(integration).to have_received(:valid?)
+ end
+ end
+
+ context 'manual configuration is disabled' do
+ let(:manual_configuration) { false }
+
+ it 'no client provided' do
+ expect(integration.prometheus_client).to be_nil
+ end
+ end
+
+ context 'when local requests are allowed' do
+ let(:manual_configuration) { true }
+ let(:api_url) { 'http://192.168.1.1:9090' }
+
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+
+ stub_prometheus_request("#{api_url}/api/v1/query?query=1")
+ end
+
+ it 'allows local requests' do
+ expect(integration.prometheus_client).not_to be_nil
+ expect { integration.prometheus_client.ping }.not_to raise_error
+ end
+ end
+
+ context 'when local requests are blocked' do
+ let(:manual_configuration) { true }
+ let(:api_url) { 'http://192.168.1.1:9090' }
+
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+
+ stub_prometheus_request("#{api_url}/api/v1/query?query=1")
+ end
+
+ it 'blocks local requests' do
+ expect(integration.prometheus_client).to be_nil
+ end
+
+ context 'with self monitoring project and internal Prometheus URL' do
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+ stub_application_setting(self_monitoring_project_id: project.id)
+
+ stub_config(prometheus: {
+ enable: true,
+ server_address: api_url
+ })
+ end
+
+ it 'allows local requests' do
+ expect(integration.prometheus_client).not_to be_nil
+ expect { integration.prometheus_client.ping }.not_to raise_error
+ end
+ end
+ end
+
+ context 'behind IAP' do
+ let(:manual_configuration) { true }
+
+ let(:google_iap_service_account) do
+ {
+ type: "service_account",
+ # dummy private key generated only for this test to pass openssl validation
+ private_key: <<~KEY
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIBOAIBAAJAU85LgUY5o6j6j/07GMLCNUcWJOBA1buZnNgKELayA6mSsHrIv31J
+ Y8kS+9WzGPQninea7DcM4hHA7smMgQD1BwIDAQABAkAqKxMy6PL3tn7dFL43p0ex
+ JyOtSmlVIiAZG1t1LXhE/uoLpYi5DnbYqGgu0oih+7nzLY/dXpNpXUmiRMOUEKmB
+ AiEAoTi2rBXbrLSi2C+H7M/nTOjMQQDuZ8Wr4uWpKcjYJTMCIQCFEskL565oFl/7
+ RRQVH+cARrAsAAoJSbrOBAvYZ0PI3QIgIEFwis10vgEF86rOzxppdIG/G+JL0IdD
+ 9IluZuXAGPECIGUo7qSaLr75o2VEEgwtAFH5aptIPFjrL5LFCKwtdB4RAiAYZgFV
+ HCMmaooAw/eELuMoMWNYmujZ7VaAnOewGDW0uw==
+ -----END RSA PRIVATE KEY-----
+ KEY
+ }
+ end
+
+ def stub_iap_request
+ integration.google_iap_service_account_json = Gitlab::Json.generate(google_iap_service_account)
+ integration.google_iap_audience_client_id = 'IAP_CLIENT_ID.apps.googleusercontent.com'
+
+ stub_request(:post, 'https://oauth2.googleapis.com/token')
+ .to_return(
+ status: 200,
+ body: '{"id_token": "FOO"}',
+ headers: { 'Content-Type': 'application/json; charset=UTF-8' }
+ )
+ end
+
+ it 'includes the authorization header' do
+ stub_iap_request
+
+ expect(integration.prometheus_client).not_to be_nil
+ expect(integration.prometheus_client.send(:options)).to have_key(:headers)
+ expect(integration.prometheus_client.send(:options)[:headers]).to eq(authorization: "Bearer FOO")
+ end
+
+ context 'when passed with token_credential_uri', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/284819' do
+ let(:malicious_host) { 'http://example.com' }
+
+ where(:param_name) do
+ [
+ :token_credential_uri,
+ :tokencredentialuri,
+ :Token_credential_uri,
+ :tokenCredentialUri
+ ]
+ end
+
+ with_them do
+ it 'does not make any unexpected HTTP requests' do
+ google_iap_service_account[param_name] = malicious_host
+ stub_iap_request
+ stub_request(:any, malicious_host).to_raise('Making additional HTTP requests is forbidden!')
+
+ expect(integration.prometheus_client).not_to be_nil
+ end
+ end
+ end
+ end
+ end
+
+ describe '#prometheus_available?' do
+ context 'clusters with enabled prometheus' do
+ before do
+ create(:clusters_integrations_prometheus, cluster: cluster)
+ end
+
+ context 'cluster belongs to project' do
+ let(:cluster) { create(:cluster, projects: [project]) }
+
+ it 'returns true' do
+ expect(integration.prometheus_available?).to be(true)
+ end
+ end
+
+ context 'cluster belongs to projects group' do
+ let_it_be(:group) { create(:group) }
+
+ let(:project) { create(:prometheus_project, group: group) }
+ let(:cluster) { create(:cluster_for_group, groups: [group]) }
+
+ it 'returns true' do
+ expect(integration.prometheus_available?).to be(true)
+ end
+
+ it 'avoids N+1 queries' do
+ integration
+ 5.times do |i|
+ other_cluster = create(:cluster_for_group, groups: [group], environment_scope: i)
+ create(:clusters_integrations_prometheus, cluster: other_cluster)
+ end
+ expect { integration.prometheus_available? }.not_to exceed_query_limit(1)
+ end
+ end
+
+ context 'cluster belongs to gitlab instance' do
+ let(:cluster) { create(:cluster, :instance) }
+
+ it 'returns true' do
+ expect(integration.prometheus_available?).to be(true)
+ end
+ end
+ end
+
+ context 'clusters with prometheus disabled' do
+ let(:cluster) { create(:cluster, projects: [project]) }
+ let!(:prometheus) { create(:clusters_integrations_prometheus, :disabled, cluster: cluster) }
+
+ it 'returns false' do
+ expect(integration.prometheus_available?).to be(false)
+ end
+ end
+
+ context 'clusters without prometheus' do
+ let(:cluster) { create(:cluster, projects: [project]) }
+
+ it 'returns false' do
+ expect(integration.prometheus_available?).to be(false)
+ end
+ end
+
+ context 'no clusters' do
+ it 'returns false' do
+ expect(integration.prometheus_available?).to be(false)
+ end
+ end
+ end
+
+ describe '#synchronize_service_state before_save callback' do
+ context 'no clusters with prometheus are installed' do
+ context 'when integration is inactive' do
+ before do
+ integration.active = false
+ end
+
+ it 'activates integration when manual_configuration is enabled' do
+ expect { integration.update!(manual_configuration: true) }.to change { integration.active }.from(false).to(true)
+ end
+
+ it 'keeps integration inactive when manual_configuration is disabled' do
+ expect { integration.update!(manual_configuration: false) }.not_to change { integration.active }.from(false)
+ end
+ end
+
+ context 'when integration is active' do
+ before do
+ integration.active = true
+ end
+
+ it 'keeps the integration active when manual_configuration is enabled' do
+ expect { integration.update!(manual_configuration: true) }.not_to change { integration.active }.from(true)
+ end
+
+ it 'inactivates the integration when manual_configuration is disabled' do
+ expect { integration.update!(manual_configuration: false) }.to change { integration.active }.from(true).to(false)
+ end
+ end
+ end
+
+ context 'with prometheus installed in the cluster' do
+ before do
+ allow(integration).to receive(:prometheus_available?).and_return(true)
+ end
+
+ context 'when integration is inactive' do
+ before do
+ integration.active = false
+ end
+
+ it 'activates integration when manual_configuration is enabled' do
+ expect { integration.update!(manual_configuration: true) }.to change { integration.active }.from(false).to(true)
+ end
+
+ it 'activates integration when manual_configuration is disabled' do
+ expect { integration.update!(manual_configuration: false) }.to change { integration.active }.from(false).to(true)
+ end
+ end
+
+ context 'when integration is active' do
+ before do
+ integration.active = true
+ end
+
+ it 'keeps integration active when manual_configuration is enabled' do
+ expect { integration.update!(manual_configuration: true) }.not_to change { integration.active }.from(true)
+ end
+
+ it 'keeps integration active when manual_configuration is disabled' do
+ expect { integration.update!(manual_configuration: false) }.not_to change { integration.active }.from(true)
+ end
+ end
+ end
+ end
+
+ describe '#track_events after_commit callback' do
+ before do
+ allow(integration).to receive(:prometheus_available?).and_return(true)
+ end
+
+ context "enabling manual_configuration" do
+ it "tracks enable event" do
+ integration.update!(manual_configuration: false)
+ integration.update!(manual_configuration: true)
+
+ expect_snowplow_event(category: 'cluster:services:prometheus', action: 'enabled_manual_prometheus')
+ end
+
+ it "tracks disable event" do
+ integration.update!(manual_configuration: true)
+ integration.update!(manual_configuration: false)
+
+ expect_snowplow_event(category: 'cluster:services:prometheus', action: 'disabled_manual_prometheus')
+ end
+ end
+ end
+
+ describe '#editable?' do
+ it 'is editable' do
+ expect(integration.editable?).to be(true)
+ end
+
+ context 'when cluster exists with prometheus enabled' do
+ let(:cluster) { create(:cluster, projects: [project]) }
+
+ before do
+ integration.update!(manual_configuration: false)
+
+ create(:clusters_integrations_prometheus, cluster: cluster)
+ end
+
+ it 'remains editable' do
+ expect(integration.editable?).to be(true)
+ end
+ end
+ end
+
+ describe '#fields' do
+ let(:expected_fields) do
+ [
+ {
+ type: 'checkbox',
+ name: 'manual_configuration',
+ title: s_('PrometheusService|Active'),
+ help: s_('PrometheusService|Select this checkbox to override the auto configuration settings with your own settings.'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'api_url',
+ title: 'API URL',
+ placeholder: s_('PrometheusService|https://prometheus.example.com/'),
+ help: s_('PrometheusService|The Prometheus API base URL.'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'google_iap_audience_client_id',
+ title: 'Google IAP Audience Client ID',
+ placeholder: s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com'),
+ help: s_('PrometheusService|PrometheusService|The ID of the IAP-secured resource.'),
+ autocomplete: 'off',
+ required: false
+ },
+ {
+ type: 'textarea',
+ name: 'google_iap_service_account_json',
+ title: 'Google IAP Service Account JSON',
+ placeholder: s_('PrometheusService|{ "type": "service_account", "project_id": ... }'),
+ help: s_('PrometheusService|The contents of the credentials.json file of your service account.'),
+ required: false
+ }
+ ]
+ end
+
+ it 'returns fields' do
+ expect(integration.fields).to eq(expected_fields)
+ end
+ end
+end
diff --git a/spec/models/integrations/pushover_spec.rb b/spec/models/integrations/pushover_spec.rb
index be8dc5634a0..716a00c5bcf 100644
--- a/spec/models/integrations/pushover_spec.rb
+++ b/spec/models/integrations/pushover_spec.rb
@@ -5,13 +5,8 @@ require 'spec_helper'
RSpec.describe Integrations::Pushover do
include StubRequests
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -21,7 +16,7 @@ RSpec.describe Integrations::Pushover do
it { is_expected.to validate_presence_of(:priority) }
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -51,7 +46,6 @@ RSpec.describe Integrations::Pushover do
allow(pushover).to receive_messages(
project: project,
project_id: project.id,
- service_hook: true,
api_key: api_key,
user_key: user_key,
device: device,
diff --git a/spec/models/integrations/redmine_spec.rb b/spec/models/integrations/redmine_spec.rb
index 083585d4fed..59997d2b6f6 100644
--- a/spec/models/integrations/redmine_spec.rb
+++ b/spec/models/integrations/redmine_spec.rb
@@ -3,11 +3,6 @@
require 'spec_helper'
RSpec.describe Integrations::Redmine do
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
# if redmine is set in setting the urls are set to defaults
# therefore the validation passes as the values are not nil
@@ -18,7 +13,7 @@ RSpec.describe Integrations::Redmine do
allow(Gitlab.config).to receive(:issues_tracker).and_return(settings)
end
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -27,12 +22,12 @@ RSpec.describe Integrations::Redmine do
it { is_expected.to validate_presence_of(:issues_url) }
it { is_expected.to validate_presence_of(:new_issue_url) }
- it_behaves_like 'issue tracker service URL attribute', :project_url
- it_behaves_like 'issue tracker service URL attribute', :issues_url
- it_behaves_like 'issue tracker service URL attribute', :new_issue_url
+ it_behaves_like 'issue tracker integration URL attribute', :project_url
+ it_behaves_like 'issue tracker integration URL attribute', :issues_url
+ it_behaves_like 'issue tracker integration URL attribute', :new_issue_url
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
diff --git a/spec/models/integrations/slack_slash_commands_spec.rb b/spec/models/integrations/slack_slash_commands_spec.rb
index a9d3c820a3c..ff89d2c6a40 100644
--- a/spec/models/integrations/slack_slash_commands_spec.rb
+++ b/spec/models/integrations/slack_slash_commands_spec.rb
@@ -18,8 +18,8 @@ RSpec.describe Integrations::SlackSlashCommands do
}
end
- let(:service) do
- project.create_slack_slash_commands_service(
+ let(:integration) do
+ project.create_slack_slash_commands_integration(
properties: { token: 'token' },
active: true
)
@@ -30,11 +30,11 @@ RSpec.describe Integrations::SlackSlashCommands do
end
before do
- allow(service).to receive(:authorize_chat_name_url).and_return(authorize_url)
+ allow(integration).to receive(:authorize_chat_name_url).and_return(authorize_url)
end
it 'uses slack compatible links' do
- response = service.trigger(params)
+ response = integration.trigger(params)
expect(response[:text]).to include("<#{authorize_url}|connect your GitLab account>")
end
diff --git a/spec/models/integrations/slack_spec.rb b/spec/models/integrations/slack_spec.rb
index e598c528967..4661d9c8291 100644
--- a/spec/models/integrations/slack_spec.rb
+++ b/spec/models/integrations/slack_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Integrations::Slack do
stub_request(:post, "https://slack.service.url/")
end
- let_it_be(:slack_service) { create(:slack_service, branches_to_be_notified: 'all') }
+ let_it_be(:slack_integration) { create(:integrations_slack, branches_to_be_notified: 'all') }
it 'uses only known events', :aggregate_failures do
described_class::SUPPORTED_EVENTS_FOR_USAGE_LOG.each do |action|
@@ -26,7 +26,7 @@ RSpec.describe Integrations::Slack do
it 'increases the usage data counter' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(event_name, values: user.id).and_call_original
- slack_service.execute(data)
+ slack_integration.execute(data)
end
end
@@ -38,7 +38,7 @@ RSpec.describe Integrations::Slack do
it 'does not increase the usage data counter' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event).with('i_ecosystem_slack_service_pipeline_notification', values: user.id)
- slack_service.execute(data)
+ slack_integration.execute(data)
end
end
@@ -126,7 +126,7 @@ RSpec.describe Integrations::Slack do
it 'does not increase the usage data counter' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
- slack_service.execute(data)
+ slack_integration.execute(data)
end
end
end
diff --git a/spec/models/integrations/teamcity_spec.rb b/spec/models/integrations/teamcity_spec.rb
index b88a4722ad4..d425357aef0 100644
--- a/spec/models/integrations/teamcity_spec.rb
+++ b/spec/models/integrations/teamcity_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do
let(:teamcity_full_url) { 'http://gitlab.com/teamcity/httpAuth/app/rest/builds/branch:unspecified:any,revision:123' }
let(:project) { create(:project) }
- subject(:service) do
+ subject(:integration) do
described_class.create!(
project: project,
properties: {
@@ -22,20 +22,15 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do
)
end
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
it { is_expected.to validate_presence_of(:build_type) }
it { is_expected.to validate_presence_of(:teamcity_url) }
- it_behaves_like 'issue tracker service URL attribute', :teamcity_url
+ it_behaves_like 'issue tracker integration URL attribute', :teamcity_url
describe '#username' do
it 'does not validate the presence of username if password is nil' do
@@ -66,7 +61,7 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do
end
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end
@@ -79,71 +74,66 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do
end
describe 'Callbacks' do
+ let(:teamcity_integration) { integration }
+
describe 'before_update :reset_password' do
context 'when a password was previously set' do
it 'resets password if url changed' do
- teamcity_service = service
+ teamcity_integration.teamcity_url = 'http://gitlab1.com'
+ teamcity_integration.save!
- teamcity_service.teamcity_url = 'http://gitlab1.com'
- teamcity_service.save!
-
- expect(teamcity_service.password).to be_nil
+ expect(teamcity_integration.password).to be_nil
end
it 'does not reset password if username changed' do
- teamcity_service = service
-
- teamcity_service.username = 'some_name'
- teamcity_service.save!
+ teamcity_integration.username = 'some_name'
+ teamcity_integration.save!
- expect(teamcity_service.password).to eq('password')
+ expect(teamcity_integration.password).to eq('password')
end
it "does not reset password if new url is set together with password, even if it's the same password" do
- teamcity_service = service
-
- teamcity_service.teamcity_url = 'http://gitlab_edited.com'
- teamcity_service.password = 'password'
- teamcity_service.save!
+ teamcity_integration.teamcity_url = 'http://gitlab_edited.com'
+ teamcity_integration.password = 'password'
+ teamcity_integration.save!
- expect(teamcity_service.password).to eq('password')
- expect(teamcity_service.teamcity_url).to eq('http://gitlab_edited.com')
+ expect(teamcity_integration.password).to eq('password')
+ expect(teamcity_integration.teamcity_url).to eq('http://gitlab_edited.com')
end
end
it 'saves password if new url is set together with password when no password was previously set' do
- teamcity_service = service
- teamcity_service.password = nil
+ teamcity_integration.password = nil
- teamcity_service.teamcity_url = 'http://gitlab_edited.com'
- teamcity_service.password = 'password'
- teamcity_service.save!
+ teamcity_integration.teamcity_url = 'http://gitlab_edited.com'
+ teamcity_integration.password = 'password'
+ teamcity_integration.save!
- expect(teamcity_service.password).to eq('password')
- expect(teamcity_service.teamcity_url).to eq('http://gitlab_edited.com')
+ expect(teamcity_integration.password).to eq('password')
+ expect(teamcity_integration.teamcity_url).to eq('http://gitlab_edited.com')
end
end
end
describe '#build_page' do
it 'returns the contents of the reactive cache' do
- stub_reactive_cache(service, { build_page: 'foo' }, 'sha', 'ref')
+ stub_reactive_cache(integration, { build_page: 'foo' }, 'sha', 'ref')
- expect(service.build_page('sha', 'ref')).to eq('foo')
+ expect(integration.build_page('sha', 'ref')).to eq('foo')
end
end
describe '#commit_status' do
it 'returns the contents of the reactive cache' do
- stub_reactive_cache(service, { commit_status: 'foo' }, 'sha', 'ref')
+ stub_reactive_cache(integration, { commit_status: 'foo' }, 'sha', 'ref')
- expect(service.commit_status('sha', 'ref')).to eq('foo')
+ expect(integration.commit_status('sha', 'ref')).to eq('foo')
end
end
describe '#calculate_reactive_cache' do
context 'build_page' do
- subject { service.calculate_reactive_cache('123', 'unused')[:build_page] }
+ subject { integration.calculate_reactive_cache('123', 'unused')[:build_page] }
it 'returns a specific URL when status is 500' do
stub_request(status: 500)
@@ -179,7 +169,7 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do
end
context 'commit_status' do
- subject { service.calculate_reactive_cache('123', 'unused')[:commit_status] }
+ subject { integration.calculate_reactive_cache('123', 'unused')[:commit_status] }
it 'sets commit status to :error when status is 500' do
stub_request(status: 500)
@@ -243,25 +233,25 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do
it 'handles push request correctly' do
stub_post_to_build_queue(branch: 'dev-123_branch')
- expect(service.execute(data)).to include('Ok')
+ expect(integration.execute(data)).to include('Ok')
end
it 'returns nil when ref is blank' do
data[:after] = Gitlab::Git::BLANK_SHA
- expect(service.execute(data)).to be_nil
+ expect(integration.execute(data)).to be_nil
end
it 'returns nil when there is no content' do
data[:total_commits_count] = 0
- expect(service.execute(data)).to be_nil
+ expect(integration.execute(data)).to be_nil
end
it 'returns nil when a merge request is opened for the same ref' do
create(:merge_request, source_project: project, source_branch: 'dev-123_branch')
- expect(service.execute(data)).to be_nil
+ expect(integration.execute(data)).to be_nil
end
end
@@ -283,26 +273,26 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do
it 'handles merge request correctly' do
stub_post_to_build_queue(branch: 'dev-123_branch')
- expect(service.execute(data)).to include('Ok')
+ expect(integration.execute(data)).to include('Ok')
end
it 'returns nil when merge request is not opened' do
data[:object_attributes][:state] = 'closed'
- expect(service.execute(data)).to be_nil
+ expect(integration.execute(data)).to be_nil
end
it 'returns nil unless merge request is marked as unchecked' do
data[:object_attributes][:merge_status] = 'can_be_merged'
- expect(service.execute(data)).to be_nil
+ expect(integration.execute(data)).to be_nil
end
end
it 'returns nil when event is not supported' do
data = { object_kind: 'foo' }
- expect(service.execute(data)).to be_nil
+ expect(integration.execute(data)).to be_nil
end
end
diff --git a/spec/models/integrations/youtrack_spec.rb b/spec/models/integrations/youtrack_spec.rb
index 314204f6fb4..f6a9dd8ef37 100644
--- a/spec/models/integrations/youtrack_spec.rb
+++ b/spec/models/integrations/youtrack_spec.rb
@@ -3,13 +3,8 @@
require 'spec_helper'
RSpec.describe Integrations::Youtrack do
- describe 'Associations' do
- it { is_expected.to belong_to :project }
- it { is_expected.to have_one :service_hook }
- end
-
describe 'Validations' do
- context 'when service is active' do
+ context 'when integration is active' do
before do
subject.active = true
end
@@ -17,11 +12,11 @@ RSpec.describe Integrations::Youtrack do
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:issues_url) }
- it_behaves_like 'issue tracker service URL attribute', :project_url
- it_behaves_like 'issue tracker service URL attribute', :issues_url
+ it_behaves_like 'issue tracker integration URL attribute', :project_url
+ it_behaves_like 'issue tracker integration URL attribute', :issues_url
end
- context 'when service is inactive' do
+ context 'when integration is inactive' do
before do
subject.active = false
end