Commit 95d968b8 authored by Alex Kalderimis's avatar Alex Kalderimis

Merge branch '330300-general-methods' into 'master'

Rename general integration methods [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!64501
parents a043914a 694666cf
......@@ -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 Types
class ServiceTypeEnum < BaseEnum
graphql_name 'ServiceType'
::Integration.available_services_types(include_dev: false).each do |type|
::Integration.available_integration_types(include_dev: false).each do |type|
value type.underscore.upcase, value: type, description: "#{type} type"
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
......
......@@ -108,9 +108,9 @@ class Integration < ApplicationRecord
scope :by_active_flag, -> (flag) { where(active: flag) }
scope :inherit_from_id, -> (id) { where(inherit_from_id: id) }
scope :inherit, -> { where.not(inherit_from_id: nil) }
scope :for_group, -> (group) { where(group_id: group, type: available_services_types(include_project_specific: false)) }
scope :for_template, -> { where(template: true, type: available_services_types(include_project_specific: false)) }
scope :for_instance, -> { where(instance: true, type: available_services_types(include_project_specific: false)) }
scope :for_group, -> (group) { where(group_id: group, type: available_integration_types(include_project_specific: false)) }
scope :for_template, -> { where(template: true, type: available_integration_types(include_project_specific: false)) }
scope :for_instance, -> { where(instance: true, type: available_integration_types(include_project_specific: false)) }
scope :push_hooks, -> { where(push_events: true, active: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
......@@ -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
......@@ -238,19 +238,19 @@ class Integration < ApplicationRecord
def self.nonexistent_services_types_for(scope)
# Using #map instead of #pluck to save one query count. This is because
# ActiveRecord loaded the object here, so we don't need to query again later.
available_services_types(include_project_specific: false) - scope.map(&:type)
available_integration_types(include_project_specific: false) - scope.map(&:type)
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)
names = integration_names
names += project_specific_integration_names if include_project_specific
names += dev_integration_names if include_dev
service_names.sort_by(&:downcase)
names.sort_by(&:downcase)
end
def self.integration_names
......@@ -261,21 +261,21 @@ 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.
# Returns a list of available integration 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|
integration_name_to_type(service_name)
def self.available_integration_types(include_project_specific: true, include_dev: true)
available_integration_names(include_project_specific: include_project_specific, include_dev: include_dev).map do
integration_name_to_type(_1)
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)
......
......@@ -550,7 +550,7 @@ class Project < ApplicationRecord
scope :with_namespace, -> { includes(:namespace) }
scope :with_import_state, -> { includes(:import_state) }
scope :include_project_feature, -> { includes(:project_feature) }
scope :with_service, ->(service) { joins(service).eager_load(service) }
scope :with_integration, ->(integration) { joins(integration).eager_load(integration) }
scope :with_shared_runners, -> { where(shared_runners_enabled: true) }
scope :with_container_registry, -> { where(container_registry_enabled: true) }
scope :inside_path, ->(path) do
......@@ -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
......
......@@ -15,7 +15,7 @@ module Clusters
raise cluster_missing_error(integration_name) unless cluster
integration = ::Project.integration_association_name(integration_name).to_sym
cluster.all_projects.with_service(integration).find_each do |project|
cluster.all_projects.with_integration(integration).find_each do |project|
project.public_send(integration).update!(active: false) # rubocop:disable GitlabSecurity/PublicSend
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 integration.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 }
......
......@@ -8,6 +8,6 @@ RSpec.describe GitlabSchema.types['ServiceType'] do
end
def available_services_enum
::Integration.available_services_types(include_dev: false).map(&:underscore).map(&:upcase)
::Integration.available_integration_types(include_dev: false).map(&:underscore).map(&:upcase)
end
end
......@@ -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 }
......
......@@ -140,10 +140,10 @@ RSpec.describe Integration do
end
describe "Test Button" do
let(:service) { build(:service, project: project) }
let(:integration) { build(:service, project: project) }
describe '#can_test?' do
subject { service.can_test? }
subject { integration.can_test? }
context 'when repository is not empty' do
let(:project) { build(:project, :repository) }
......@@ -158,9 +158,9 @@ RSpec.describe Integration do
end
context 'when instance-level service' do
Integration.available_services_types.each do |service_type|
let(:service) do
described_class.send(:integration_type_to_model, service_type).new(instance: true)
Integration.available_integration_types.each do |type|
let(:integration) do
described_class.send(:integration_type_to_model, type).new(instance: true)
end
it { is_expected.to be_falsey }
......@@ -168,9 +168,9 @@ RSpec.describe Integration do
end
context 'when group-level service' do
Integration.available_services_types.each do |service_type|
let(:service) do
described_class.send(:integration_type_to_model, service_type).new(group_id: group.id)
Integration.available_integration_types.each do |type|
let(:integration) do
described_class.send(:integration_type_to_model, type).new(group_id: group.id)
end
it { is_expected.to be_falsey }
......@@ -185,9 +185,9 @@ RSpec.describe Integration do
let(:project) { build(:project, :repository) }
it 'test runs execute' do
expect(service).to receive(:execute).with(data)
expect(integration).to receive(:execute).with(data)
service.test(data)
integration.test(data)
end
end
......@@ -195,9 +195,9 @@ RSpec.describe Integration do
let(:project) { build(:project) }
it 'test runs execute' do
expect(service).to receive(:execute).with(data)
expect(integration).to receive(:execute).with(data)
service.test(data)
integration.test(data)
end
end
end
......@@ -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
......@@ -264,7 +266,7 @@ RSpec.describe Integration do
context 'with all existing instances' do
before do
Integration.insert_all(
Integration.available_services_types(include_project_specific: false).map { |type| { instance: true, type: type } }
Integration.available_integration_types(include_project_specific: false).map { |type| { instance: true, type: type } }
)
end
......@@ -292,13 +294,15 @@ RSpec.describe Integration do
describe 'template' do
shared_examples 'retrieves service templates' do
it 'returns the available service templates' do
expect(Integration.find_or_create_templates.pluck(:type)).to match_array(Integration.available_services_types(include_project_specific: false))
expect(Integration.find_or_create_templates.pluck(:type)).to match_array(Integration.available_integration_types(include_project_specific: false))
end
end
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'
......@@ -306,7 +310,7 @@ RSpec.describe Integration do
context 'with all existing templates' do
before do
Integration.insert_all(
Integration.available_services_types(include_project_specific: false).map { |type| { template: true, type: type } }
Integration.available_integration_types(include_project_specific: false).map { |type| { template: true, type: type } }
)
end
......@@ -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
......
......@@ -1557,13 +1557,16 @@ RSpec.describe Project, factory_default: :keep do
end
end
describe '.with_service' do
describe '.with_integration' do
before do
create_list(:prometheus_project, 2)
end
it 'avoid n + 1' do
expect { described_class.with_service(:prometheus_integration).map(&:prometheus_integration) }.not_to exceed_query_limit(1)
let(:integration) { :prometheus_integration }
it 'avoids n + 1' do
expect { described_class.with_integration(integration).map(&integration) }
.not_to exceed_query_limit(1)
end
end
......@@ -5838,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
......@@ -5895,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
......@@ -5905,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
......
......@@ -24,11 +24,11 @@ RSpec.describe API::Services do
expect(response).to have_gitlab_http_status(:forbidden)
end
context 'project with services' do
context 'with integrations' do
let!(:active_integration) { create(:emails_on_push_integration, project: project, active: true) }
let!(:integration) { create(:custom_issue_tracker_integration, project: project, active: false) }
it "returns a list of all active services" do
it "returns a list of all active integrations" do
get api("/projects/#{project.id}/services", user)
aggregate_failures 'expect successful response with all active services' do
......@@ -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)
......@@ -141,7 +141,7 @@ RSpec.describe API::Services do
expect(json_response['properties'].keys).to match_array(service_instance.api_field_names)
end
it "returns all properties of inactive service #{service}" do
it "returns all properties of inactive integration #{service}" do
deactive_service!
get api("/projects/#{project.id}/services/#{dashed_service}", user)
......@@ -151,16 +151,16 @@ RSpec.describe API::Services do
expect(json_response['properties'].keys).to match_array(service_instance.api_field_names)
end
it "returns not found if service does not exist" do
it "returns not found if integration does not exist" do
get api("/projects/#{project2.id}/services/#{dashed_service}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Service Not Found')
end
it "returns not found if service exists but is in `Project#disabled_services`" do
it "returns not found if service exists but is in `Project#disabled_integrations`" do
expect_next_found_instance_of(Project) do |project|
expect(project).to receive(:disabled_services).at_least(:once).and_return([service])
expect(project).to receive(:disabled_integrations).at_least(:once).and_return([service])
end
get api("/projects/#{project.id}/services/#{dashed_service}", user)
......
......@@ -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
......@@ -66,7 +66,7 @@ Integration.available_services_names.each do |service|
return unless licensed_feature
stub_licensed_features(licensed_feature => true)
project.clear_memoization(:disabled_services)
project.clear_memoization(:disabled_integrations)
end
end
end
......
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