Commit a4d50620 authored by Alex Kalderimis's avatar Alex Kalderimis

Rename service initialization to integration initialization

Renames the general integration initialization and reflection methods
to use the 'integration' terminology.
parent c48976f5
......@@ -7,7 +7,7 @@ class Projects::MattermostsController < Projects::ApplicationController
layout 'project_settings'
before_action :authorize_admin_project!
before_action :service
before_action :integration
before_action :teams, only: [:new]
feature_category :integrations
......@@ -16,11 +16,11 @@ class Projects::MattermostsController < Projects::ApplicationController
end
def create
result, message = @service.configure(current_user, configure_params)
result, message = integration.configure(current_user, configure_params)
if result
flash[:notice] = 'This service is now configured'
redirect_to edit_project_service_path(@project, service)
redirect_to edit_project_service_path(@project, integration)
else
flash[:alert] = message || 'Failed to configure service'
redirect_to new_project_mattermost_path(@project)
......@@ -31,15 +31,16 @@ class Projects::MattermostsController < Projects::ApplicationController
def configure_params
params.require(:mattermost).permit(:trigger, :team_id).merge(
url: service_trigger_url(@service),
url: service_trigger_url(integration),
icon_url: asset_url('slash-command-logo.png', skip_pipeline: true))
end
def teams
@teams, @teams_error_message = @service.list_teams(current_user)
@teams, @teams_error_message = integration.list_teams(current_user)
end
def service
@service ||= @project.find_or_initialize_service('mattermost_slash_commands')
def integration
@integration ||= @project.find_or_initialize_integration('mattermost_slash_commands')
@service = @integration # TODO: remove when https://gitlab.com/gitlab-org/gitlab/-/issues/330300 is complete
end
end
# frozen_string_literal: true
class Projects::ServiceHookLogsController < Projects::HookLogsController
before_action :service, only: [:show, :retry]
before_action :integration, only: [:show, :retry]
def retry
execute_hook
redirect_to edit_project_service_path(@project, @service)
redirect_to edit_project_service_path(@project, @integration)
end
private
def hook
@hook ||= service.service_hook
@hook ||= integration.service_hook
end
def service
@service ||= @project.find_or_initialize_service(params[:service_id])
def integration
@integration ||= @project.find_or_initialize_integration(params[:service_id])
@service = @integration # TODO: remove when https://gitlab.com/gitlab-org/gitlab/-/issues/330300 is complete
end
end
......@@ -84,7 +84,7 @@ class Projects::ServicesController < Projects::ApplicationController
end
def integration
@integration ||= @project.find_or_initialize_service(params[:id])
@integration ||= @project.find_or_initialize_integration(params[:id])
end
alias_method :service, :integration
......
......@@ -9,7 +9,7 @@ module Projects
feature_category :integrations
def show
@integrations = @project.find_or_initialize_services
@integrations = @project.find_or_initialize_integrations
end
end
end
......
......@@ -5,7 +5,7 @@ module OperationsHelper
def prometheus_integration
strong_memoize(:prometheus_integration) do
@project.find_or_initialize_service(::Integrations::Prometheus.to_param)
@project.find_or_initialize_integration(::Integrations::Prometheus.to_param)
end
end
......
......@@ -217,7 +217,7 @@ class Integration < ApplicationRecord
private_class_method :create_nonexistent_templates
def self.find_or_initialize_non_project_specific_integration(name, instance: false, group_id: nil)
return unless name.in?(available_services_names(include_project_specific: false))
return unless name.in?(available_integration_names(include_project_specific: false))
integration_name_to_model(name).find_or_initialize_by(instance: instance, group_id: group_id)
end
......@@ -242,13 +242,13 @@ class Integration < ApplicationRecord
end
private_class_method :nonexistent_services_types_for
# Returns a list of available service names.
# Returns a list of available integration names.
# Example: ["asana", ...]
# @deprecated
def self.available_services_names(include_project_specific: true, include_dev: true)
service_names = services_names
service_names += project_specific_services_names if include_project_specific
service_names += dev_services_names if include_dev
def self.available_integration_names(include_project_specific: true, include_dev: true)
service_names = integration_names
service_names += project_specific_integration_names if include_project_specific
service_names += dev_integration_names if include_dev
service_names.sort_by(&:downcase)
end
......@@ -261,20 +261,20 @@ class Integration < ApplicationRecord
integration_names
end
def self.dev_services_names
def self.dev_integration_names
return [] unless Rails.env.development?
DEV_INTEGRATION_NAMES
end
def self.project_specific_services_names
def self.project_specific_integration_names
PROJECT_SPECIFIC_INTEGRATION_NAMES
end
# Returns a list of available service types.
# Example: ["AsanaService", ...]
def self.available_services_types(include_project_specific: true, include_dev: true)
available_services_names(include_project_specific: include_project_specific, include_dev: include_dev).map do |service_name|
available_integration_names(include_project_specific: include_project_specific, include_dev: include_dev).map do |service_name|
integration_name_to_type(service_name)
end
end
......
......@@ -120,8 +120,6 @@ module Integrations
end
def execute(data)
return if project.disabled_services.include?(to_param)
object_kind = data[:object_kind]
object_kind = 'job' if object_kind == 'build'
return unless supported_events.include?(object_kind)
......
......@@ -1398,22 +1398,22 @@ class Project < ApplicationRecord
@external_wiki ||= integrations.external_wikis.first
end
def find_or_initialize_services
available_services_names = Integration.available_services_names - disabled_services
available_services_names.map do |service_name|
find_or_initialize_service(service_name)
end.sort_by(&:title)
def find_or_initialize_integrations
Integration
.available_integration_names
.difference(disabled_integrations)
.map { find_or_initialize_integration(_1) }
.sort_by(&:title)
end
def disabled_services
def disabled_integrations
[]
end
def find_or_initialize_service(name)
return if disabled_services.include?(name)
def find_or_initialize_integration(name)
return if disabled_integrations.include?(name)
find_service(integrations, name) || build_from_instance_or_template(name) || build_service(name)
find_integration(integrations, name) || build_from_instance_or_template(name) || build_integration(name)
end
# rubocop: disable CodeReuse/ServiceClass
......@@ -2659,19 +2659,19 @@ class Project < ApplicationRecord
project_feature.update!(container_registry_access_level: access_level)
end
def find_service(services, name)
services.find { |service| service.to_param == name }
def find_integration(integrations, name)
integrations.find { _1.to_param == name }
end
def build_from_instance_or_template(name)
instance = find_service(services_instances, name)
instance = find_integration(services_instances, name)
return Integration.build_from_integration(instance, project_id: id) if instance
template = find_service(services_templates, name)
template = find_integration(services_templates, name)
return Integration.build_from_integration(template, project_id: id) if template
end
def build_service(name)
def build_integration(name)
Integration.integration_name_to_model(name).new(project_id: id)
end
......
......@@ -193,14 +193,14 @@ module Projects
# Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/326665
def create_prometheus_integration
service = @project.find_or_initialize_service(::Integrations::Prometheus.to_param)
integration = @project.find_or_initialize_integration(::Integrations::Prometheus.to_param)
# If the service has already been inserted in the database, that
# means it came from a template, and there's nothing more to do.
return if service.persisted?
return if integration.persisted?
if service.prometheus_available?
service.save!
if integration.prometheus_available?
integration.save!
else
@project.prometheus_integration = nil
end
......
......@@ -102,10 +102,10 @@ module Projects
def prometheus_integration_params
return {} unless attrs = params[:prometheus_integration_attributes]
service = project.find_or_initialize_service(::Integrations::Prometheus.to_param)
service.assign_attributes(attrs)
integration = project.find_or_initialize_integration(::Integrations::Prometheus.to_param)
integration.assign_attributes(attrs)
{ prometheus_integration_attributes: service.attributes.except(*%w(id project_id created_at updated_at)) }
{ prometheus_integration_attributes: integration.attributes.except(*%w[id project_id created_at updated_at]) }
end
def incident_management_setting_params
......
......@@ -67,7 +67,7 @@ module Projects
end
def valid_for_manual?(token)
prometheus = project.find_or_initialize_service('prometheus')
prometheus = project.find_or_initialize_integration('prometheus')
return false unless prometheus.manual_configuration?
if setting = project.alerting_setting
......
......@@ -15,7 +15,7 @@ module Clusters
return unless cluster
cluster.all_projects.find_each do |project|
project.find_or_initialize_service(service_name).update!(active: true)
project.find_or_initialize_integration(service_name).update!(active: true)
end
end
end
......
......@@ -21,15 +21,15 @@ module Projects
private
def create_prometheus_integration(project)
service = project.find_or_initialize_service(::Integrations::Prometheus.to_param)
integration = project.find_or_initialize_integration(::Integrations::Prometheus.to_param)
# If the service has already been inserted in the database, that
# means it came from a template, and there's nothing more to do.
return if service.persisted?
return if integration.persisted?
return unless service.prometheus_available?
return unless integration.prometheus_available?
service.save!
integration.save!
rescue ActiveRecord::RecordInvalid => e
Gitlab::ErrorTracking.track_exception(e, extra: { project_id: project.id })
end
......
......@@ -19,8 +19,8 @@ module EE
class_methods do
extend ::Gitlab::Utils::Override
override :project_specific_services_names
def project_specific_services_names
override :project_specific_integration_names
def project_specific_integration_names
integrations = super + EE_PROJECT_SPECIFIC_INTEGRATION_NAMES
integrations += EE_COM_PROJECT_SPECIFIC_INTEGRATION_NAMES if ::Gitlab.com?
integrations
......
......@@ -634,13 +634,13 @@ module EE
end
alias_method :merge_requests_ff_only_enabled?, :merge_requests_ff_only_enabled
override :disabled_services
def disabled_services
strong_memoize(:disabled_services) do
super.tap do |services|
services.push('github') unless feature_available?(:github_project_service_integration)
::Gitlab::CurrentSettings.slack_app_enabled ? services.push('slack_slash_commands') : services.push('gitlab_slack_application')
end
override :disabled_integrations
def disabled_integrations
strong_memoize(:disabled_integrations) do
gh = github_integration_enabled? ? [] : %w[github]
slack = ::Gitlab::CurrentSettings.slack_app_enabled ? %w[slack_slash_commands] : %w[gitlab_slack_application]
super + gh + slack
end
end
......@@ -802,6 +802,10 @@ module EE
private
def github_integration_enabled?
feature_available?(:github_project_service_integration)
end
def group_hooks
GroupHook.where(group_id: group.self_and_ancestors)
end
......
......@@ -126,7 +126,7 @@ module Integrations
end
def disabled?
project.disabled_services.include?(to_param)
project.disabled_integrations.include?(to_param)
end
def update_status(status_message)
......
......@@ -11,25 +11,25 @@ RSpec.describe Projects::Settings::IntegrationsController do
sign_in(user)
end
shared_examples 'endpoint with some disabled services' do
it 'has some disabled services' do
shared_examples 'endpoint with some disabled integrations' do
it 'has some disabled integrations' do
get :show, params: { namespace_id: project.namespace, project_id: project }
expect(active_services).not_to include(*disabled_services)
expect(active_services).not_to include(*disabled_integrations)
end
end
shared_examples 'endpoint without disabled services' do
it 'does not have disabled services' do
shared_examples 'endpoint without disabled integrations' do
it 'does not have disabled integrations' do
get :show, params: { namespace_id: project.namespace, project_id: project }
expect(active_services).to include(*disabled_services)
expect(active_services).to include(*disabled_integrations)
end
end
context 'sets correct services list' do
let(:active_services) { assigns(:integrations).map(&:model_name) }
let(:disabled_services) { %w[Integrations::Github] }
let(:disabled_integrations) { %w[Integrations::Github] }
it 'enables SlackSlashCommands and disables GitlabSlackApplication' do
get :show, params: { namespace_id: project.namespace, project_id: project }
......@@ -49,7 +49,7 @@ RSpec.describe Projects::Settings::IntegrationsController do
end
context 'without a license key' do
it_behaves_like 'endpoint with some disabled services'
it_behaves_like 'endpoint with some disabled integrations'
end
context 'with a license key' do
......@@ -65,7 +65,7 @@ RSpec.describe Projects::Settings::IntegrationsController do
stub_application_setting(check_namespace_plan: true)
end
it_behaves_like 'endpoint with some disabled services'
it_behaves_like 'endpoint with some disabled integrations'
end
context 'when checking if namespace plan is not enabled' do
......@@ -73,7 +73,7 @@ RSpec.describe Projects::Settings::IntegrationsController do
stub_application_setting(check_namespace_plan: false)
end
it_behaves_like 'endpoint without disabled services'
it_behaves_like 'endpoint without disabled integrations'
end
end
end
......
......@@ -3,11 +3,11 @@
require 'spec_helper'
RSpec.describe Integration do
describe '.available_services_names' do
it { expect(described_class.available_services_names).to include('github') }
describe '.available_integration_names' do
it { expect(described_class.available_integration_names).to include('github') }
end
describe '.project_specific_services_names' do
describe '.project_specific_integration_names' do
before do
allow(::Gitlab).to receive(:com?).and_return(com)
end
......@@ -16,7 +16,7 @@ RSpec.describe Integration do
let(:com) { false }
it do
expect(described_class.project_specific_services_names)
expect(described_class.project_specific_integration_names)
.to include(*described_class::EE_PROJECT_SPECIFIC_INTEGRATION_NAMES)
end
end
......@@ -25,7 +25,7 @@ RSpec.describe Integration do
let(:com) { true }
it do
expect(described_class.project_specific_services_names)
expect(described_class.project_specific_integration_names)
.to include(*described_class::EE_PROJECT_SPECIFIC_INTEGRATION_NAMES, *Integration::EE_COM_PROJECT_SPECIFIC_INTEGRATION_NAMES)
end
end
......
......@@ -1463,13 +1463,13 @@ RSpec.describe Project do
end
end
describe '#disabled_services' do
describe '#disabled_integrations' do
let(:project) { build(:project) }
subject { project.disabled_services }
subject { project.disabled_integrations }
where(:license_feature, :disabled_services) do
:github_project_service_integration | %w(github)
where(:license_feature, :disabled_integrations) do
:github_project_service_integration | %w[github]
end
with_them do
......@@ -1478,7 +1478,7 @@ RSpec.describe Project do
stub_licensed_features(license_feature => true)
end
it { is_expected.not_to include(*disabled_services) }
it { is_expected.not_to include(*disabled_integrations) }
end
context 'when feature is unavailable' do
......@@ -1486,7 +1486,7 @@ RSpec.describe Project do
stub_licensed_features(license_feature => false)
end
it { is_expected.to include(*disabled_services) }
it { is_expected.to include(*disabled_integrations) }
end
end
end
......
......@@ -77,8 +77,8 @@ module API
present services, with: Entities::ProjectServiceBasic
end
SERVICES.each do |service_slug, settings|
desc "Set #{service_slug} service for project"
SERVICES.each do |slug, settings|
desc "Set #{slug} service for project"
params do
settings.each do |setting|
if setting[:required]
......@@ -88,12 +88,12 @@ module API
end
end
end
put ":id/services/#{service_slug}" do
service = user_project.find_or_initialize_service(service_slug.underscore)
service_params = declared_params(include_missing: false).merge(active: true)
put ":id/services/#{slug}" do
integration = user_project.find_or_initialize_integration(slug.underscore)
params = declared_params(include_missing: false).merge(active: true)
if service.update(service_params)
present service, with: Entities::ProjectService
if integration.update(params)
present integration, with: Entities::ProjectService
else
render_api_error!('400 Bad Request', 400)
end
......@@ -102,19 +102,15 @@ module API
desc "Delete a service for project"
params do
requires :service_slug, type: String, values: SERVICES.keys, desc: 'The name of the service'
requires :slug, type: String, values: SERVICES.keys, desc: 'The name of the service'
end
delete ":id/services/:service_slug" do
service = user_project.find_or_initialize_service(params[:service_slug].underscore)
delete ":id/services/:slug" do
integration = user_project.find_or_initialize_integration(params[:slug].underscore)
destroy_conditionally!(service) do
attrs = service_attributes(service).inject({}) do |hash, key|
hash.merge!(key => nil)
end
destroy_conditionally!(integration) do
attrs = service_attributes(integration).index_with { nil }.merge(active: false)
unless service.update(attrs.merge(active: false))
render_api_error!('400 Bad Request', 400)
end
render_api_error!('400 Bad Request', 400) unless service.update(attrs)
end
end
......@@ -122,10 +118,10 @@ module API
success Entities::ProjectService
end
params do
requires :service_slug, type: String, values: SERVICES.keys, desc: 'The name of the service'
requires :slug, type: String, values: SERVICES.keys, desc: 'The name of the service'
end
get ":id/services/:service_slug" do
integration = user_project.find_or_initialize_service(params[:service_slug].underscore)
get ":id/services/:slug" do
integration = user_project.find_or_initialize_integration(params[:slug].underscore)
not_found!('Service') unless integration&.persisted?
......
......@@ -156,10 +156,10 @@ module Gitlab
underscored_service = matched_login['service'].underscore
return unless Integration.available_services_names.include?(underscored_service)
return unless Integration.available_integration_names.include?(underscored_service)
# We treat underscored_service as a trusted input because it is included
# in the Integration.available_services_names allowlist.
# in the Integration.available_integration_names allowlist.
accessor = Project.integration_association_name(underscored_service)
service = project.public_send(accessor) # rubocop:disable GitlabSecurity/PublicSend
......
......@@ -107,10 +107,10 @@ module Gitlab
return success(result) unless prometheus_enabled?
return success(result) unless prometheus_server_address.present?
service = result[:project].find_or_initialize_service('prometheus')
prometheus = result[:project].find_or_initialize_integration('prometheus')
unless service.update(prometheus_integration_attributes)
log_error('Could not save prometheus manual configuration for self-monitoring project. Errors: %{errors}' % { errors: service.errors.full_messages })
unless prometheus.update(prometheus_integration_attributes)
log_error('Could not save prometheus manual configuration for self-monitoring project. Errors: %{errors}' % { errors: prometheus.errors.full_messages })
return error(_('Could not save prometheus manual configuration'))
end
......
......@@ -26,7 +26,7 @@ module Gitlab
private
def service_prometheus_adapter
project.find_or_initialize_service('prometheus')
project.find_or_initialize_integration('prometheus')
end
end
end
......
......@@ -403,7 +403,7 @@ module Gitlab
def services_usage
# rubocop: disable UsageData/LargeTable:
Integration.available_services_names(include_dev: false).each_with_object({}) do |name, response|
Integration.available_integration_names(include_dev: false).each_with_object({}) do |name, response|
type = Integration.integration_name_to_type(name)
response[:"projects_#{name}_active"] = count(Integration.active.where.not(project: nil).where(type: type))
......
......@@ -10,7 +10,7 @@ RSpec.describe Admin::IntegrationsController do
end
describe '#edit' do
Integration.available_services_names.each do |integration_name|
Integration.available_integration_names.each do |integration_name|
context "#{integration_name}" do
it 'successfully displays the template' do
get :edit, params: { id: integration_name }
......@@ -27,7 +27,7 @@ RSpec.describe Admin::IntegrationsController do
end
it 'returns 404' do
get :edit, params: { id: Integration.available_services_names.sample }
get :edit, params: { id: Integration.available_integration_names.sample }
expect(response).to have_gitlab_http_status(:not_found)
end
......
......@@ -36,7 +36,7 @@ RSpec.describe Groups::Settings::IntegrationsController do
describe '#edit' do
context 'when user is not owner' do
it 'renders not_found' do
get :edit, params: { group_id: group, id: Integration.available_services_names(include_project_specific: false).sample }
get :edit, params: { group_id: group, id: Integration.available_integration_names(include_project_specific: false).sample }
expect(response).to have_gitlab_http_status(:not_found)
end
......@@ -47,8 +47,8 @@ RSpec.describe Groups::Settings::IntegrationsController do
group.add_owner(user)
end
Integration.available_services_names(include_project_specific: false).each do |integration_name|
context "#{integration_name}" do
Integration.available_integration_names(include_project_specific: false).each do |integration_name|
context integration_name do
it 'successfully displays the template' do
get :edit, params: { group_id: group, id: integration_name }
......
......@@ -24,8 +24,8 @@ RSpec.describe OperationsHelper do
let_it_be(:prometheus_integration) { ::Integrations::Prometheus.new(project: project) }
before do
allow(project).to receive(:find_or_initialize_service).and_call_original
allow(project).to receive(:find_or_initialize_service).with('prometheus').and_return(prometheus_integration)
allow(project).to receive(:find_or_initialize_integration).and_call_original
allow(project).to receive(:find_or_initialize_integration).with('prometheus').and_return(prometheus_integration)
end
it 'returns the correct values' do
......
......@@ -13,7 +13,7 @@ RSpec.describe Gitlab::Prometheus::Adapter do
let(:prometheus_integration) { double(:prometheus_integration, can_query?: true) }
before do
allow(project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_integration
allow(project).to receive(:find_or_initialize_integration).with('prometheus').and_return prometheus_integration
end
it 'return prometheus integration as prometheus adapter' do
......@@ -33,7 +33,7 @@ RSpec.describe Gitlab::Prometheus::Adapter do
let(:prometheus_integration) { double(:prometheus_integration, can_query?: false) }
before do
allow(project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_integration
allow(project).to receive(:find_or_initialize_integration).with('prometheus').and_return prometheus_integration
end
context 'with cluster with prometheus disabled' do
......
......@@ -23,7 +23,7 @@ RSpec.describe DeploymentMetrics do
let(:prometheus_integration) { instance_double(::Integrations::Prometheus, can_query?: true, configured?: true) }
before do
allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_integration
allow(deployment.project).to receive(:find_or_initialize_integration).with('prometheus').and_return prometheus_integration
end
it { is_expected.to be_truthy }
......@@ -33,7 +33,7 @@ RSpec.describe DeploymentMetrics do
let(:prometheus_integration) { instance_double(::Integrations::Prometheus, configured?: true, can_query?: false) }
before do
allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_integration
allow(deployment.project).to receive(:find_or_initialize_integration).with('prometheus').and_return prometheus_integration
end
it { is_expected.to be_falsy }
......@@ -43,7 +43,7 @@ RSpec.describe DeploymentMetrics do
let(:prometheus_integration) { instance_double(::Integrations::Prometheus, configured?: false, can_query?: false) }
before do
allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_integration
allow(deployment.project).to receive(:find_or_initialize_integration).with('prometheus').and_return prometheus_integration
end
it { is_expected.to be_falsy }
......
......@@ -251,11 +251,13 @@ RSpec.describe Integration do
describe '.find_or_initialize_all_non_project_specific' do
shared_examples 'service instances' do
it 'returns the available service instances' do
expect(Integration.find_or_initialize_all_non_project_specific(Integration.for_instance).map(&:to_param)).to match_array(Integration.available_services_names(include_project_specific: false))
expect(Integration.find_or_initialize_all_non_project_specific(Integration.for_instance).map(&:to_param))
.to match_array(Integration.available_integration_names(include_project_specific: false))
end
it 'does not create service instances' do
expect { Integration.find_or_initialize_all_non_project_specific(Integration.for_instance) }.not_to change { Integration.count }
expect { Integration.find_or_initialize_all_non_project_specific(Integration.for_instance) }
.not_to change(Integration, :count)
end
end
......@@ -298,7 +300,9 @@ RSpec.describe Integration do
describe '.find_or_create_templates' do
it 'creates service templates' do
expect { Integration.find_or_create_templates }.to change { Integration.count }.from(0).to(Integration.available_services_names(include_project_specific: false).size)
total = Integration.available_integration_names(include_project_specific: false).size
expect { Integration.find_or_create_templates }.to change(Integration, :count).from(0).to(total)
end
it_behaves_like 'retrieves service templates'
......@@ -332,7 +336,9 @@ RSpec.describe Integration do
end
it 'creates the rest of the service templates' do
expect { Integration.find_or_create_templates }.to change { Integration.count }.from(1).to(Integration.available_services_names(include_project_specific: false).size)
total = Integration.available_integration_names(include_project_specific: false).size
expect { Integration.find_or_create_templates }.to change(Integration, :count).from(1).to(total)
end
it_behaves_like 'retrieves service templates'
......@@ -461,13 +467,15 @@ RSpec.describe Integration do
describe 'is prefilled for projects pushover service' do
it "has all fields prefilled" do
service = project.find_or_initialize_service('pushover')
expect(service.template).to eq(false)
expect(service.device).to eq('MyDevice')
expect(service.sound).to eq('mic')
expect(service.priority).to eq(4)
expect(service.api_key).to eq('123456789')
integration = project.find_or_initialize_integration('pushover')
expect(integration).to have_attributes(
template: eq(false),
device: eq('MyDevice'),
sound: eq('mic'),
priority: eq(4),
api_key: eq('123456789')
)
end
end
end
......@@ -896,37 +904,37 @@ RSpec.describe Integration do
end
end
describe '.available_services_names' do
describe '.available_integration_names' do
it 'calls the right methods' do
expect(described_class).to receive(:services_names).and_call_original
expect(described_class).to receive(:dev_services_names).and_call_original
expect(described_class).to receive(:project_specific_services_names).and_call_original
expect(described_class).to receive(:integration_names).and_call_original
expect(described_class).to receive(:dev_integration_names).and_call_original
expect(described_class).to receive(:project_specific_integration_names).and_call_original
described_class.available_services_names
described_class.available_integration_names
end
it 'does not call project_specific_services_names with include_project_specific false' do
expect(described_class).to receive(:services_names).and_call_original
expect(described_class).to receive(:dev_services_names).and_call_original
expect(described_class).not_to receive(:project_specific_services_names)
it 'does not call project_specific_integration_names with include_project_specific false' do
expect(described_class).to receive(:integration_names).and_call_original
expect(described_class).to receive(:dev_integration_names).and_call_original
expect(described_class).not_to receive(:project_specific_integration_names)
described_class.available_services_names(include_project_specific: false)
described_class.available_integration_names(include_project_specific: false)
end
it 'does not call dev_services_names with include_dev false' do
expect(described_class).to receive(:services_names).and_call_original
expect(described_class).not_to receive(:dev_services_names)
expect(described_class).to receive(:project_specific_services_names).and_call_original
expect(described_class).to receive(:integration_names).and_call_original
expect(described_class).not_to receive(:dev_integration_names)
expect(described_class).to receive(:project_specific_integration_names).and_call_original
described_class.available_services_names(include_dev: false)
described_class.available_integration_names(include_dev: false)
end
it { expect(described_class.available_services_names).to include('jenkins') }
it { expect(described_class.available_integration_names).to include('jenkins') }
end
describe '.project_specific_services_names' do
describe '.project_specific_integration_names' do
it do
expect(described_class.project_specific_services_names)
expect(described_class.project_specific_integration_names)
.to include(*described_class::PROJECT_SPECIFIC_INTEGRATION_NAMES)
end
end
......
......@@ -1565,7 +1565,7 @@ RSpec.describe Project, factory_default: :keep do
let(:integration) { :prometheus_integration }
it 'avoids n + 1' do
expect { described_class.with_service(integration).map(&integration) }
expect { described_class.with_integration(integration).map(&integration) }
.not_to exceed_query_limit(1)
end
end
......@@ -5841,53 +5841,53 @@ RSpec.describe Project, factory_default: :keep do
end
end
describe '#find_or_initialize_services' do
describe '#find_or_initialize_integrations' do
let_it_be(:subject) { create(:project) }
it 'avoids N+1 database queries' do
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_services }.count
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_integrations }.count
expect(control_count).to be <= 4
end
it 'avoids N+1 database queries with more available services' do
allow(Integration).to receive(:available_services_names).and_return(%w[pushover])
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_services }
it 'avoids N+1 database queries with more available integrations' do
allow(Integration).to receive(:available_integration_names).and_return(%w[pushover])
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_integrations }
allow(Integration).to receive(:available_services_names).and_call_original
expect { subject.find_or_initialize_services }.not_to exceed_query_limit(control_count)
allow(Integration).to receive(:available_integration_names).and_call_original
expect { subject.find_or_initialize_integrations }.not_to exceed_query_limit(control_count)
end
context 'with disabled services' do
context 'with disabled integrations' do
before do
allow(Integration).to receive(:available_services_names).and_return(%w[prometheus pushover teamcity])
allow(subject).to receive(:disabled_services).and_return(%w[prometheus])
allow(Integration).to receive(:available_integration_names).and_return(%w[prometheus pushover teamcity])
allow(subject).to receive(:disabled_integrations).and_return(%w[prometheus])
end
it 'returns only enabled services sorted' do
services = subject.find_or_initialize_services
expect(services.size).to eq(2)
expect(services.map(&:title)).to eq(['JetBrains TeamCity', 'Pushover'])
expect(subject.find_or_initialize_integrations).to match [
have_attributes(title: 'JetBrains TeamCity'),
have_attributes(title: 'Pushover')
]
end
end
end
describe '#find_or_initialize_service' do
describe '#find_or_initialize_integration' do
it 'avoids N+1 database queries' do
allow(Integration).to receive(:available_services_names).and_return(%w[prometheus pushover])
allow(Integration).to receive(:available_integration_names).and_return(%w[prometheus pushover])
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_service('prometheus') }.count
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_integration('prometheus') }.count
allow(Integration).to receive(:available_services_names).and_call_original
allow(Integration).to receive(:available_integration_names).and_call_original
expect { subject.find_or_initialize_service('prometheus') }.not_to exceed_query_limit(control_count)
expect { subject.find_or_initialize_integration('prometheus') }.not_to exceed_query_limit(control_count)
end
it 'returns nil if integration is disabled' do
allow(subject).to receive(:disabled_services).and_return(%w[prometheus])
allow(subject).to receive(:disabled_integrations).and_return(%w[prometheus])
expect(subject.find_or_initialize_service('prometheus')).to be_nil
expect(subject.find_or_initialize_integration('prometheus')).to be_nil
end
context 'with an existing integration' do
......@@ -5898,7 +5898,7 @@ RSpec.describe Project, factory_default: :keep do
end
it 'retrieves the integration' do
expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.project.com/')
expect(subject.find_or_initialize_integration('prometheus').api_url).to eq('https://prometheus.project.com/')
end
end
......@@ -5908,25 +5908,25 @@ RSpec.describe Project, factory_default: :keep do
create(:prometheus_integration, :template, api_url: 'https://prometheus.template.com/')
end
it 'builds the service from the instance if exists' do
expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.instance.com/')
it 'builds the service from the instance integration' do
expect(subject.find_or_initialize_integration('prometheus').api_url).to eq('https://prometheus.instance.com/')
end
end
context 'with an instance-level and template integrations' do
context 'with a template integration and no instance-level' do
before do
create(:prometheus_integration, :template, api_url: 'https://prometheus.template.com/')
end
it 'builds the service from the template if instance does not exists' do
expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.template.com/')
it 'builds the service from the template' do
expect(subject.find_or_initialize_integration('prometheus').api_url).to eq('https://prometheus.template.com/')
end
end
context 'without an exisiting integration, nor instance-level or template' do
it 'builds the service if instance or template does not exists' do
expect(subject.find_or_initialize_service('prometheus')).to be_a(::Integrations::Prometheus)
expect(subject.find_or_initialize_service('prometheus').api_url).to be_nil
context 'without an exisiting integration, or instance-level or template' do
it 'builds the service' do
expect(subject.find_or_initialize_integration('prometheus')).to be_a(::Integrations::Prometheus)
expect(subject.find_or_initialize_integration('prometheus').api_url).to be_nil
end
end
end
......
......@@ -42,7 +42,7 @@ RSpec.describe API::Services do
end
end
Integration.available_services_names.each do |service|
Integration.available_integration_names.each do |service|
describe "PUT /projects/:id/services/#{service.dasherize}" do
include_context service
......@@ -99,7 +99,7 @@ RSpec.describe API::Services do
include_context service
before do
initialize_service(service)
initialize_integration(service)
end
it "deletes #{service}" do
......@@ -114,7 +114,7 @@ RSpec.describe API::Services do
describe "GET /projects/:id/services/#{service.dasherize}" do
include_context service
let!(:initialized_service) { initialize_service(service, active: true) }
let!(:initialized_service) { initialize_integration(service, active: true) }
let_it_be(:project2) do
create(:project, creator_id: user.id, namespace: user.namespace)
......
......@@ -394,11 +394,11 @@ RSpec.describe Projects::Operations::UpdateService do
}
end
it 'uses Project#find_or_initialize_service to include instance defined defaults and pass them to Projects::UpdateService', :aggregate_failures do
it 'uses Project#find_or_initialize_integration to include instance defined defaults and pass them to Projects::UpdateService', :aggregate_failures do
project_update_service = double(Projects::UpdateService)
expect(project)
.to receive(:find_or_initialize_service)
.to receive(:find_or_initialize_integration)
.with('prometheus')
.and_return(prometheus_integration)
expect(Projects::UpdateService).to receive(:new) do |project_arg, user_arg, update_params_hash|
......@@ -413,13 +413,13 @@ RSpec.describe Projects::Operations::UpdateService do
end
end
context 'prometheus params were not passed into service' do
context 'when prometheus params are not passed into service' do
let(:params) { { something: :else } }
it 'does not pass any prometheus params into Projects::UpdateService', :aggregate_failures do
project_update_service = double(Projects::UpdateService)
expect(project).not_to receive(:find_or_initialize_service)
expect(project).not_to receive(:find_or_initialize_integration)
expect(Projects::UpdateService)
.to receive(:new)
.with(project, user, {})
......
# frozen_string_literal: true
Integration.available_services_names.each do |service|
Integration.available_integration_names.each do |service|
RSpec.shared_context service do
include JiraServiceHelper if service == 'jira'
......@@ -49,12 +49,12 @@ Integration.available_services_names.each do |service|
stub_jira_integration_test if service == 'jira'
end
def initialize_service(service, attrs = {})
service_item = project.find_or_initialize_service(service)
service_item.attributes = attrs
service_item.properties = service_attrs
service_item.save!
service_item
def initialize_integration(integration, attrs = {})
record = project.find_or_initialize_integration(integration)
record.attributes = attrs
record.properties = service_attrs
record.save!
record
end
private
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment