Commit d454486f authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch '201855-rename-project_services_to_integrations-4' into 'master'

Move Jira integration model to `Integrations::` namespace [RUN AS-IF-FOSS] [RUN ALL RSPEC]

See merge request gitlab-org/gitlab!61743
parents 6c203b47 eade74bf
...@@ -872,7 +872,6 @@ RSpec/AnyInstanceOf: ...@@ -872,7 +872,6 @@ RSpec/AnyInstanceOf:
- 'ee/spec/features/issues/form_spec.rb' - 'ee/spec/features/issues/form_spec.rb'
- 'ee/spec/features/merge_request/user_creates_merge_request_spec.rb' - 'ee/spec/features/merge_request/user_creates_merge_request_spec.rb'
- 'ee/spec/features/projects/new_project_spec.rb' - 'ee/spec/features/projects/new_project_spec.rb'
- 'ee/spec/features/projects/services/user_activates_jira_spec.rb'
- 'ee/spec/features/registrations/welcome_spec.rb' - 'ee/spec/features/registrations/welcome_spec.rb'
- 'ee/spec/features/security/project/internal_access_spec.rb' - 'ee/spec/features/security/project/internal_access_spec.rb'
- 'ee/spec/features/security/project/private_access_spec.rb' - 'ee/spec/features/security/project/private_access_spec.rb'
...@@ -1151,6 +1150,7 @@ RSpec/AnyInstanceOf: ...@@ -1151,6 +1150,7 @@ RSpec/AnyInstanceOf:
- 'spec/models/hooks/service_hook_spec.rb' - 'spec/models/hooks/service_hook_spec.rb'
- 'spec/models/hooks/system_hook_spec.rb' - 'spec/models/hooks/system_hook_spec.rb'
- 'spec/models/hooks/web_hook_spec.rb' - 'spec/models/hooks/web_hook_spec.rb'
- 'spec/models/integrations/jira_spec.rb'
- 'spec/models/issue_spec.rb' - 'spec/models/issue_spec.rb'
- 'spec/models/key_spec.rb' - 'spec/models/key_spec.rb'
- 'spec/models/member_spec.rb' - 'spec/models/member_spec.rb'
...@@ -1158,7 +1158,6 @@ RSpec/AnyInstanceOf: ...@@ -1158,7 +1158,6 @@ RSpec/AnyInstanceOf:
- 'spec/models/merge_request_spec.rb' - 'spec/models/merge_request_spec.rb'
- 'spec/models/note_spec.rb' - 'spec/models/note_spec.rb'
- 'spec/models/project_import_state_spec.rb' - 'spec/models/project_import_state_spec.rb'
- 'spec/models/project_services/jira_service_spec.rb'
- 'spec/models/project_services/mattermost_slash_commands_service_spec.rb' - 'spec/models/project_services/mattermost_slash_commands_service_spec.rb'
- 'spec/models/project_spec.rb' - 'spec/models/project_spec.rb'
- 'spec/models/repository_spec.rb' - 'spec/models/repository_spec.rb'
...@@ -1662,7 +1661,6 @@ Gitlab/NamespacedClass: ...@@ -1662,7 +1661,6 @@ Gitlab/NamespacedClass:
- 'app/models/project_services/irker_service.rb' - 'app/models/project_services/irker_service.rb'
- 'app/models/project_services/issue_tracker_data.rb' - 'app/models/project_services/issue_tracker_data.rb'
- 'app/models/project_services/jenkins_service.rb' - 'app/models/project_services/jenkins_service.rb'
- 'app/models/project_services/jira_service.rb'
- 'app/models/project_services/jira_tracker_data.rb' - 'app/models/project_services/jira_tracker_data.rb'
- 'app/models/project_services/mattermost_service.rb' - 'app/models/project_services/mattermost_service.rb'
- 'app/models/project_services/mattermost_slash_commands_service.rb' - 'app/models/project_services/mattermost_slash_commands_service.rb'
...@@ -2918,7 +2916,6 @@ Style/RegexpLiteralMixedPreserve: ...@@ -2918,7 +2916,6 @@ Style/RegexpLiteralMixedPreserve:
- 'ee/spec/features/groups/saml_enforcement_spec.rb' - 'ee/spec/features/groups/saml_enforcement_spec.rb'
- 'ee/spec/features/markdown/metrics_spec.rb' - 'ee/spec/features/markdown/metrics_spec.rb'
- 'ee/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb' - 'ee/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb'
- 'ee/spec/models/project_services/jira_service_spec.rb'
- 'ee/spec/services/jira/requests/issues/list_service_spec.rb' - 'ee/spec/services/jira/requests/issues/list_service_spec.rb'
- 'lib/api/invitations.rb' - 'lib/api/invitations.rb'
- 'lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb' - 'lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb'
......
...@@ -15,7 +15,7 @@ module Types ...@@ -15,7 +15,7 @@ module Types
definition_methods do definition_methods do
def resolve_type(object, context) def resolve_type(object, context)
if object.is_a?(::JiraService) if object.is_a?(::Integrations::Jira)
Types::Projects::Services::JiraServiceType Types::Projects::Services::JiraServiceType
else else
Types::Projects::Services::BaseServiceType Types::Projects::Services::BaseServiceType
......
...@@ -107,7 +107,7 @@ module ServicesHelper ...@@ -107,7 +107,7 @@ module ServicesHelper
reset_path: scoped_reset_integration_path(integration, group: group) reset_path: scoped_reset_integration_path(integration, group: group)
} }
if integration.is_a?(JiraService) if integration.is_a?(Integrations::Jira)
form_data[:jira_issue_transition_automatic] = integration.jira_issue_transition_automatic form_data[:jira_issue_transition_automatic] = integration.jira_issue_transition_automatic
form_data[:jira_issue_transition_id] = integration.jira_issue_transition_id form_data[:jira_issue_transition_id] = integration.jira_issue_transition_id
end end
......
This diff is collapsed.
...@@ -193,6 +193,7 @@ class Project < ApplicationRecord ...@@ -193,6 +193,7 @@ class Project < ApplicationRecord
has_one :datadog_service, class_name: 'Integrations::Datadog' has_one :datadog_service, class_name: 'Integrations::Datadog'
has_one :emails_on_push_service, class_name: 'Integrations::EmailsOnPush' has_one :emails_on_push_service, class_name: 'Integrations::EmailsOnPush'
has_one :ewm_service, class_name: 'Integrations::Ewm' has_one :ewm_service, class_name: 'Integrations::Ewm'
has_one :jira_service, class_name: 'Integrations::Jira'
has_one :redmine_service, class_name: 'Integrations::Redmine' has_one :redmine_service, class_name: 'Integrations::Redmine'
has_one :youtrack_service, class_name: 'Integrations::Youtrack' has_one :youtrack_service, class_name: 'Integrations::Youtrack'
has_one :discord_service has_one :discord_service
...@@ -209,7 +210,6 @@ class Project < ApplicationRecord ...@@ -209,7 +210,6 @@ class Project < ApplicationRecord
has_one :teamcity_service has_one :teamcity_service
has_one :pushover_service has_one :pushover_service
has_one :jenkins_service has_one :jenkins_service
has_one :jira_service
has_one :external_wiki_service has_one :external_wiki_service
has_one :prometheus_service, inverse_of: :project has_one :prometheus_service, inverse_of: :project
has_one :mock_ci_service has_one :mock_ci_service
...@@ -560,7 +560,7 @@ class Project < ApplicationRecord ...@@ -560,7 +560,7 @@ class Project < ApplicationRecord
scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct } scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct }
scope :with_push, -> { joins(:events).merge(Event.pushed_action) } scope :with_push, -> { joins(:events).merge(Event.pushed_action) }
scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') } scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') }
scope :with_active_jira_services, -> { joins(:integrations).merge(::JiraService.active) } # rubocop:disable CodeReuse/ServiceClass scope :with_active_jira_services, -> { joins(:integrations).merge(::Integrations::Jira.active) } # rubocop:disable CodeReuse/ServiceClass
scope :with_jira_dvcs_cloud, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: true)) } scope :with_jira_dvcs_cloud, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: true)) }
scope :with_jira_dvcs_server, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: false)) } scope :with_jira_dvcs_server, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: false)) }
scope :inc_routes, -> { includes(:route, namespace: :route) } scope :inc_routes, -> { includes(:route, namespace: :route) }
......
This diff is collapsed.
...@@ -43,9 +43,9 @@ module JiraImport ...@@ -43,9 +43,9 @@ module JiraImport
def user_mapper_service_factory def user_mapper_service_factory
# TODO: use deployment_type enum from jira service when https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37003 is merged # TODO: use deployment_type enum from jira service when https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37003 is merged
case deployment_type.upcase case deployment_type.upcase
when JiraService::DEPLOYMENT_TYPES[:server] when Integrations::Jira::DEPLOYMENT_TYPES[:server]
ServerUsersMapperService.new(user, project, start_at) ServerUsersMapperService.new(user, project, start_at)
when JiraService::DEPLOYMENT_TYPES[:cloud] when Integrations::Jira::DEPLOYMENT_TYPES[:cloud]
CloudUsersMapperService.new(user, project, start_at) CloudUsersMapperService.new(user, project, start_at)
else else
raise ArgumentError raise ArgumentError
......
...@@ -302,7 +302,7 @@ It contains information about [integrations](../user/project/integrations/overvi ...@@ -302,7 +302,7 @@ It contains information about [integrations](../user/project/integrations/overvi
{ {
"severity":"ERROR", "severity":"ERROR",
"time":"2018-09-06T14:56:20.439Z", "time":"2018-09-06T14:56:20.439Z",
"service_class":"JiraService", "service_class":"Integrations::Jira",
"project_id":8, "project_id":8,
"project_path":"h5bp/html5-boilerplate", "project_path":"h5bp/html5-boilerplate",
"message":"Error sending message", "message":"Error sending message",
...@@ -312,7 +312,7 @@ It contains information about [integrations](../user/project/integrations/overvi ...@@ -312,7 +312,7 @@ It contains information about [integrations](../user/project/integrations/overvi
{ {
"severity":"INFO", "severity":"INFO",
"time":"2018-09-06T17:15:16.365Z", "time":"2018-09-06T17:15:16.365Z",
"service_class":"JiraService", "service_class":"Integrations::Jira",
"project_id":3, "project_id":3,
"project_path":"namespace2/project2", "project_path":"namespace2/project2",
"message":"Successfully posted", "message":"Successfully posted",
......
...@@ -54,13 +54,13 @@ module Projects ...@@ -54,13 +54,13 @@ module Projects
total_count: finder.total_count total_count: finder.total_count
) )
::Integrations::Jira::IssueSerializer.new ::Integrations::JiraSerializers::IssueSerializer.new
.with_pagination(request, response) .with_pagination(request, response)
.represent(jira_issues, project: project) .represent(jira_issues, project: project)
end end
def issue_json def issue_json
::Integrations::Jira::IssueDetailSerializer.new ::Integrations::JiraSerializers::IssueDetailSerializer.new
.represent(project.jira_service.find_issue(params[:id], rendered_fields: true), project: project) .represent(project.jira_service.find_issue(params[:id], rendered_fields: true), project: project)
end end
......
...@@ -34,7 +34,7 @@ module Resolvers ...@@ -34,7 +34,7 @@ module Resolvers
def serialize_external_issue(external_issue, external_type) def serialize_external_issue(external_issue, external_type)
case external_type case external_type
when 'jira' when 'jira'
::Integrations::Jira::IssueSerializer ::Integrations::JiraSerializers::IssueSerializer
.new .new
.represent(external_issue, project: object.vulnerability.project, only: %i[title references status external_tracker web_url created_at updated_at] ) .represent(external_issue, project: object.vulnerability.project, only: %i[title references status external_tracker web_url created_at updated_at] )
end end
......
...@@ -13,7 +13,7 @@ module EE ...@@ -13,7 +13,7 @@ module EE
def integration_form_data(integration, group: nil) def integration_form_data(integration, group: nil)
form_data = super form_data = super
if integration.is_a?(JiraService) if integration.is_a?(Integrations::Jira)
form_data.merge!( form_data.merge!(
show_jira_issues_integration: @project&.jira_issues_integration_available?.to_s, show_jira_issues_integration: @project&.jira_issues_integration_available?.to_s,
show_jira_vulnerabilities_integration: integration.jira_vulnerabilities_integration_available?.to_s, show_jira_vulnerabilities_integration: integration.jira_vulnerabilities_integration_available?.to_s,
......
...@@ -15,7 +15,7 @@ module VulnerabilitiesHelper ...@@ -15,7 +15,7 @@ module VulnerabilitiesHelper
new_issue_url: new_issue_url_for(vulnerability), new_issue_url: new_issue_url_for(vulnerability),
create_jira_issue_url: create_jira_issue_url_for(vulnerability), create_jira_issue_url: create_jira_issue_url_for(vulnerability),
related_jira_issues_path: project_integrations_jira_issues_path(vulnerability.project, vulnerability_ids: [vulnerability.id]), related_jira_issues_path: project_integrations_jira_issues_path(vulnerability.project, vulnerability_ids: [vulnerability.id]),
jira_integration_settings_path: edit_project_service_path(vulnerability.project, ::JiraService), jira_integration_settings_path: edit_project_service_path(vulnerability.project, ::Integrations::Jira),
has_mr: !!vulnerability.finding.merge_request_feedback.try(:merge_request_id), has_mr: !!vulnerability.finding.merge_request_feedback.try(:merge_request_id),
create_mr_url: create_vulnerability_feedback_merge_request_path(vulnerability.finding.project), create_mr_url: create_vulnerability_feedback_merge_request_path(vulnerability.finding.project),
discussions_url: discussions_project_security_vulnerability_path(vulnerability.project, vulnerability), discussions_url: discussions_project_security_vulnerability_path(vulnerability.project, vulnerability),
......
# frozen_string_literal: true
module EE
module Integrations
module Jira
extend ActiveSupport::Concern
MAX_URL_LENGTH = 4000
prepended do
validates :project_key, presence: true, if: :project_key_required?
validates :vulnerabilities_issuetype, presence: true, if: :vulnerabilities_enabled
end
def jira_vulnerabilities_integration_available?
parent.present? ? parent.licensed_feature_available?(:jira_vulnerabilities_integration) : License.feature_available?(:jira_vulnerabilities_integration)
end
def jira_vulnerabilities_integration_enabled?
jira_vulnerabilities_integration_available? && vulnerabilities_enabled
end
def configured_to_create_issues_from_vulnerabilities?
strong_memoize(:configured_to_create_issues_from_vulnerabilities) do
active? && project_key.present? && vulnerabilities_issuetype.present? && jira_vulnerabilities_integration_enabled?
end
end
def test(_)
super.then do |result|
next result unless result[:success]
next result unless project.jira_vulnerabilities_integration_enabled?
result.merge(data: { issuetypes: issue_types })
end
end
def new_issue_url_with_predefined_fields(summary, description)
escaped_summary = CGI.escape(summary)
escaped_description = CGI.escape(description)
"#{url}/secure/CreateIssueDetails!init.jspa?pid=#{jira_project_id}&issuetype=#{vulnerabilities_issuetype}&summary=#{escaped_summary}&description=#{escaped_description}"[0..MAX_URL_LENGTH]
end
def create_issue(summary, description, current_user)
return if client_url.blank?
jira_request do
issue = client.Issue.build
issue.save(
fields: {
project: { id: jira_project_id },
issuetype: { id: vulnerabilities_issuetype },
summary: summary,
description: description
}
)
log_usage(:create_issue, current_user)
issue
end
end
private
def project_key_required?
strong_memoize(:project_key_required) do
issues_enabled || vulnerabilities_enabled
end
end
# Returns internal JIRA Project ID
#
# @return [String, nil] the internal JIRA ID of the Project
def jira_project_id
jira_project&.id
end
# Returns JIRA Project for selected Project Key
#
# @return [JIRA::Resource::Project, nil] the object that represents JIRA Projects
def jira_project
strong_memoize(:jira_project) do
client_url.present? ? jira_request { client.Project.find(project_key) } : nil
end
end
# Returns list of Issue Type Scheme IDs in selected JIRA Project
#
# @return [Array] the array of IDs
def project_issuetype_scheme_ids
raise NotImplementedError unless data_fields.deployment_cloud?
query_url = Addressable::URI.join("#{client.options[:rest_base_path]}/", 'issuetypescheme/', 'project')
query_url.query_values = { 'projectId' => jira_project_id }
client
.get(query_url.to_s)
.fetch('values', [])
.map { |schemes| schemes.dig('issueTypeScheme', 'id') }
end
# Returns list of Issue Type IDs available in active Issue Type Scheme in selected JIRA Project
#
# @return [Array] the array of IDs
def project_issuetype_ids
strong_memoize(:project_issuetype_ids) do
if data_fields.deployment_server?
query_url = Addressable::URI.join("#{client.options[:rest_base_path]}/", 'project/', project_key)
client
.get(query_url.to_s)
.fetch('issueTypes', [])
.map { |issue_type| issue_type['id'] }
elsif data_fields.deployment_cloud?
query_url = Addressable::URI.join("#{client.options[:rest_base_path]}/", 'issuetypescheme/', 'mapping')
query_url.query_values = { 'issueTypeSchemeId' => project_issuetype_scheme_ids }
client
.get(query_url.to_s)
.fetch('values', [])
.map { |schemes| schemes['issueTypeId'] }
else
raise NotImplementedError
end
end
end
# Returns list of available Issue tTpes in selected JIRA Project
#
# @return [Array] the array of objects with JIRA Issuetype ID, Name and Description
def issue_types
return [] if jira_project.blank?
client
.Issuetype
.all
.select { |issue_type| issue_type.id.in?(project_issuetype_ids) }
.reject { |issue_type| issue_type.subtask }
.map { |issue_type| { id: issue_type.id, name: issue_type.name, description: issue_type.description } }
end
end
end
end
# frozen_string_literal: true
module EE
module JiraService
extend ActiveSupport::Concern
MAX_URL_LENGTH = 4000
prepended do
validates :project_key, presence: true, if: :project_key_required?
validates :vulnerabilities_issuetype, presence: true, if: :vulnerabilities_enabled
end
def jira_vulnerabilities_integration_available?
parent.present? ? parent.licensed_feature_available?(:jira_vulnerabilities_integration) : License.feature_available?(:jira_vulnerabilities_integration)
end
def jira_vulnerabilities_integration_enabled?
jira_vulnerabilities_integration_available? && vulnerabilities_enabled
end
def configured_to_create_issues_from_vulnerabilities?
strong_memoize(:configured_to_create_issues_from_vulnerabilities) do
active? && project_key.present? && vulnerabilities_issuetype.present? && jira_vulnerabilities_integration_enabled?
end
end
def test(_)
super.then do |result|
next result unless result[:success]
next result unless project.jira_vulnerabilities_integration_enabled?
result.merge(data: { issuetypes: issue_types })
end
end
def new_issue_url_with_predefined_fields(summary, description)
escaped_summary = CGI.escape(summary)
escaped_description = CGI.escape(description)
"#{url}/secure/CreateIssueDetails!init.jspa?pid=#{jira_project_id}&issuetype=#{vulnerabilities_issuetype}&summary=#{escaped_summary}&description=#{escaped_description}"[0..MAX_URL_LENGTH]
end
def create_issue(summary, description, current_user)
return if client_url.blank?
jira_request do
issue = client.Issue.build
issue.save(
fields: {
project: { id: jira_project_id },
issuetype: { id: vulnerabilities_issuetype },
summary: summary,
description: description
}
)
log_usage(:create_issue, current_user)
issue
end
end
private
def project_key_required?
strong_memoize(:project_key_required) do
issues_enabled || vulnerabilities_enabled
end
end
# Returns internal JIRA Project ID
#
# @return [String, nil] the internal JIRA ID of the Project
def jira_project_id
jira_project&.id
end
# Returns JIRA Project for selected Project Key
#
# @return [JIRA::Resource::Project, nil] the object that represents JIRA Projects
def jira_project
strong_memoize(:jira_project) do
client_url.present? ? jira_request { client.Project.find(project_key) } : nil
end
end
# Returns list of Issue Type Scheme IDs in selected JIRA Project
#
# @return [Array] the array of IDs
def project_issuetype_scheme_ids
raise NotImplementedError unless data_fields.deployment_cloud?
query_url = Addressable::URI.join("#{client.options[:rest_base_path]}/", 'issuetypescheme/', 'project')
query_url.query_values = { 'projectId' => jira_project_id }
client
.get(query_url.to_s)
.fetch('values', [])
.map { |schemes| schemes.dig('issueTypeScheme', 'id') }
end
# Returns list of Issue Type IDs available in active Issue Type Scheme in selected JIRA Project
#
# @return [Array] the array of IDs
def project_issuetype_ids
strong_memoize(:project_issuetype_ids) do
if data_fields.deployment_server?
query_url = Addressable::URI.join("#{client.options[:rest_base_path]}/", 'project/', project_key)
client
.get(query_url.to_s)
.fetch('issueTypes', [])
.map { |issue_type| issue_type['id'] }
elsif data_fields.deployment_cloud?
query_url = Addressable::URI.join("#{client.options[:rest_base_path]}/", 'issuetypescheme/', 'mapping')
query_url.query_values = { 'issueTypeSchemeId' => project_issuetype_scheme_ids }
client
.get(query_url.to_s)
.fetch('values', [])
.map { |schemes| schemes['issueTypeId'] }
else
raise NotImplementedError
end
end
end
# Returns list of available Issue tTpes in selected JIRA Project
#
# @return [Array] the array of objects with JIRA Issuetype ID, Name and Description
def issue_types
return [] if jira_project.blank?
client
.Issuetype
.all
.select { |issue_type| issue_type.id.in?(project_issuetype_ids) }
.reject { |issue_type| issue_type.subtask }
.map { |issue_type| { id: issue_type.id, name: issue_type.name, description: issue_type.description } }
end
end
end
# frozen_string_literal: true # frozen_string_literal: true
module Integrations module Integrations
module Jira module JiraSerializers
class IssueDetailEntity < ::Integrations::Jira::IssueEntity class IssueDetailEntity < ::Integrations::JiraSerializers::IssueEntity
expose :description_html do |jira_issue| expose :description_html do |jira_issue|
jira_gfm_pipeline(jira_issue.renderedFields['description']) jira_gfm_pipeline(jira_issue.renderedFields['description'])
end end
......
# frozen_string_literal: true # frozen_string_literal: true
module Integrations module Integrations
module Jira module JiraSerializers
class IssueDetailSerializer < BaseSerializer class IssueDetailSerializer < BaseSerializer
entity ::Integrations::Jira::IssueDetailEntity entity ::Integrations::JiraSerializers::IssueDetailEntity
end end
end end
end end
# frozen_string_literal: true # frozen_string_literal: true
module Integrations module Integrations
module Jira module JiraSerializers
class IssueEntity < Grape::Entity class IssueEntity < Grape::Entity
include RequestAwareEntity include RequestAwareEntity
......
# frozen_string_literal: true # frozen_string_literal: true
module Integrations module Integrations
module Jira module JiraSerializers
class IssueSerializer < BaseSerializer class IssueSerializer < BaseSerializer
include WithPagination include WithPagination
entity ::Integrations::Jira::IssueEntity entity ::Integrations::JiraSerializers::IssueEntity
end end
end end
end end
...@@ -567,7 +567,7 @@ module EE ...@@ -567,7 +567,7 @@ module EE
min_id = minimum_id(JiraTrackerData.where(issues_enabled: true), :service_id) min_id = minimum_id(JiraTrackerData.where(issues_enabled: true), :service_id)
max_id = maximum_id(JiraTrackerData.where(issues_enabled: true), :service_id) max_id = maximum_id(JiraTrackerData.where(issues_enabled: true), :service_id)
# rubocop: enable UsageData/LargeTable: # rubocop: enable UsageData/LargeTable:
count(::JiraService.active.includes(:jira_tracker_data).where(jira_tracker_data: { issues_enabled: true }), start: min_id, finish: max_id) count(::Integrations::Jira.active.includes(:jira_tracker_data).where(jira_tracker_data: { issues_enabled: true }), start: min_id, finish: max_id)
end end
# rubocop:enable CodeReuse/ActiveRecord # rubocop:enable CodeReuse/ActiveRecord
......
...@@ -46,7 +46,7 @@ module Sidebars ...@@ -46,7 +46,7 @@ module Sidebars
override :render? override :render?
def render? def render?
external_issue_tracker.is_a?(JiraService) && context.jira_issues_integration external_issue_tracker.is_a?(Integrations::Jira) && context.jira_issues_integration
end end
private private
......
...@@ -71,7 +71,7 @@ RSpec.describe Projects::Integrations::Jira::IssuesController do ...@@ -71,7 +71,7 @@ RSpec.describe Projects::Integrations::Jira::IssuesController do
expect(finder).to receive(:execute).and_return(jira_issues) expect(finder).to receive(:execute).and_return(jira_issues)
end end
expect_next_instance_of(Integrations::Jira::IssueSerializer) do |serializer| expect_next_instance_of(Integrations::JiraSerializers::IssueSerializer) do |serializer|
expect(serializer).to receive(:represent).with(jira_issues, project: project) expect(serializer).to receive(:represent).with(jira_issues, project: project)
end end
...@@ -203,11 +203,11 @@ RSpec.describe Projects::Integrations::Jira::IssuesController do ...@@ -203,11 +203,11 @@ RSpec.describe Projects::Integrations::Jira::IssuesController do
before do before do
stub_licensed_features(jira_issues_integration: true) stub_licensed_features(jira_issues_integration: true)
expect_next_found_instance_of(JiraService) do |service| expect_next_found_instance_of(Integrations::Jira) do |service|
expect(service).to receive(:find_issue).with('1', rendered_fields: true).and_return(jira_issue) expect(service).to receive(:find_issue).with('1', rendered_fields: true).and_return(jira_issue)
end end
expect_next_instance_of(Integrations::Jira::IssueDetailSerializer) do |serializer| expect_next_instance_of(Integrations::JiraSerializers::IssueDetailSerializer) do |serializer|
expect(serializer).to receive(:represent).with(jira_issue, project: project).and_return(issue_json) expect(serializer).to receive(:represent).with(jira_issue, project: project).and_return(issue_json)
end end
end end
......
...@@ -15,7 +15,9 @@ RSpec.describe 'User activates Jira', :js do ...@@ -15,7 +15,9 @@ RSpec.describe 'User activates Jira', :js do
context 'when Jira connection test succeeds' do context 'when Jira connection test succeeds' do
before do before do
stub_licensed_features(jira_issues_integration: true) stub_licensed_features(jira_issues_integration: true)
allow_any_instance_of(JiraService).to receive(:issues_enabled) { true } allow_next_instance_of(Integrations::Jira) do |instance|
allow(instance).to receive(:issues_enabled) { true }
end
visit_project_integration('Jira') visit_project_integration('Jira')
fill_form fill_form
......
...@@ -184,7 +184,7 @@ RSpec.describe VulnerabilitiesHelper do ...@@ -184,7 +184,7 @@ RSpec.describe VulnerabilitiesHelper do
describe '#create_jira_issue_url_for' do describe '#create_jira_issue_url_for' do
subject { helper.vulnerability_details(vulnerability, pipeline) } subject { helper.vulnerability_details(vulnerability, pipeline) }
let(:jira_service) { double('JiraService', new_issue_url_with_predefined_fields: 'https://jira.example.com/new') } let(:jira_service) { double('Integrations::Jira', new_issue_url_with_predefined_fields: 'https://jira.example.com/new') }
before do before do
allow(helper).to receive(:can?).and_return(true) allow(helper).to receive(:can?).and_return(true)
...@@ -231,7 +231,7 @@ RSpec.describe VulnerabilitiesHelper do ...@@ -231,7 +231,7 @@ RSpec.describe VulnerabilitiesHelper do
subject subject
end end
it 'delegates rendering URL to JiraService' do it 'delegates rendering URL to Integrations::Jira' do
expect(jira_service).to receive(:new_issue_url_with_predefined_fields).with("Investigate vulnerability: #{vulnerability.title}", expected_jira_issue_description) expect(jira_service).to receive(:new_issue_url_with_predefined_fields).with("Investigate vulnerability: #{vulnerability.title}", expected_jira_issue_description)
subject subject
......
...@@ -12,7 +12,7 @@ RSpec.describe Sidebars::Projects::Menus::JiraMenu do ...@@ -12,7 +12,7 @@ RSpec.describe Sidebars::Projects::Menus::JiraMenu do
subject { described_class.new(context) } subject { described_class.new(context) }
describe 'render?' do describe 'render?' do
context 'when issue tracker is not a JiraService' do context 'when issue tracker is not Jira' do
it 'returns false' do it 'returns false' do
create(:custom_issue_tracker_service, active: true, project: project, project_url: 'http://test.com') create(:custom_issue_tracker_service, active: true, project: project, project_url: 'http://test.com')
...@@ -20,7 +20,7 @@ RSpec.describe Sidebars::Projects::Menus::JiraMenu do ...@@ -20,7 +20,7 @@ RSpec.describe Sidebars::Projects::Menus::JiraMenu do
end end
end end
context 'when issue tracker is a JiraService' do context 'when issue tracker is Jira' do
let!(:jira) { create(:jira_service, project: project, project_key: 'GL') } let!(:jira) { create(:jira_service, project: project, project_key: 'GL') }
context 'when issues integration is disabled' do context 'when issues integration is disabled' do
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe JiraService do RSpec.describe Integrations::Jira do
let(:jira_service) { build(:jira_service, **options) } let(:jira_service) { build(:jira_service, **options) }
let(:headers) { { 'Content-Type' => 'application/json' } } let(:headers) { { 'Content-Type' => 'application/json' } }
...@@ -167,11 +167,11 @@ RSpec.describe JiraService do ...@@ -167,11 +167,11 @@ RSpec.describe JiraService do
end end
before do before do
WebMock.stub_request(:get, /api\/2\/project\/GL/).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).to_return(body: project_info_result.to_json ) WebMock.stub_request(:get, %r{api/2/project/GL}).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).to_return(body: project_info_result.to_json )
WebMock.stub_request(:get, /api\/2\/project\/GL\z/).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).to_return(body: { 'id' => '10000' }.to_json, headers: headers) WebMock.stub_request(:get, %r{api/2/project/GL\z}).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).to_return(body: { 'id' => '10000' }.to_json, headers: headers)
WebMock.stub_request(:get, /api\/2\/issuetype\z/).to_return(body: issue_types_response.to_json, headers: headers) WebMock.stub_request(:get, %r{api/2/issuetype\z}).to_return(body: issue_types_response.to_json, headers: headers)
WebMock.stub_request(:get, /api\/2\/issuetypescheme\/project\?projectId\=10000\z/).to_return(body: issue_type_scheme_response.to_json, headers: headers) WebMock.stub_request(:get, %r{api/2/issuetypescheme/project\?projectId\=10000\z}).to_return(body: issue_type_scheme_response.to_json, headers: headers)
WebMock.stub_request(:get, /api\/2\/issuetypescheme\/mapping\?issueTypeSchemeId\=10126\z/).to_return(body: issue_type_mapping_response.to_json, headers: headers) WebMock.stub_request(:get, %r{api/2/issuetypescheme/mapping\?issueTypeSchemeId\=10126\z}).to_return(body: issue_type_mapping_response.to_json, headers: headers)
end end
it { is_expected.to eq(success: true, result: { jira: true }, data: { issuetypes: [{ id: '10001', name: 'Bug', description: 'Jira Bug' }] }) } it { is_expected.to eq(success: true, result: { jira: true }, data: { issuetypes: [{ id: '10001', name: 'Bug', description: 'Jira Bug' }] }) }
...@@ -236,8 +236,8 @@ RSpec.describe JiraService do ...@@ -236,8 +236,8 @@ RSpec.describe JiraService do
allow(jira_service.data_fields).to receive(:deployment_cloud?).and_return(false) allow(jira_service.data_fields).to receive(:deployment_cloud?).and_return(false)
allow(jira_service.data_fields).to receive(:deployment_server?).and_return(true) allow(jira_service.data_fields).to receive(:deployment_server?).and_return(true)
WebMock.stub_request(:get, /api\/2\/project\/GL/).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).to_return(body: project_info_result.to_json, headers: headers) WebMock.stub_request(:get, %r{api/2/project/GL}).with(basic_auth: %w(gitlab_jira_username gitlab_jira_password)).to_return(body: project_info_result.to_json, headers: headers)
WebMock.stub_request(:get, /api\/2\/issuetype\z/).to_return(body: issue_types_response.to_json, headers: headers) WebMock.stub_request(:get, %r{api/2/issuetype\z}).to_return(body: issue_types_response.to_json, headers: headers)
end end
it { is_expected.to eq(success: true, result: { jira: true }, data: { issuetypes: [{ description: "A task that needs to be done.", id: "10003", name: "Task" }, { description: "Created by Jira Software - do not edit or delete. Issue type for a user story.", id: "10002", name: "Story" }, { description: "A problem which impairs or prevents the functions of the product.", id: "10004", name: "Bug" }, { description: "Created by Jira Software - do not edit or delete. Issue type for a big user story that needs to be broken down.", id: "10001", name: "Epic" }] }) } it { is_expected.to eq(success: true, result: { jira: true }, data: { issuetypes: [{ description: "A task that needs to be done.", id: "10003", name: "Task" }, { description: "Created by Jira Software - do not edit or delete. Issue type for a user story.", id: "10002", name: "Story" }, { description: "A problem which impairs or prevents the functions of the product.", id: "10004", name: "Bug" }, { description: "Created by Jira Software - do not edit or delete. Issue type for a big user story that needs to be broken down.", id: "10001", name: "Epic" }] }) }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Integrations::Jira::IssueDetailEntity do RSpec.describe Integrations::JiraSerializers::IssueDetailEntity do
include JiraServiceHelper include JiraServiceHelper
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Integrations::Jira::IssueEntity do RSpec.describe Integrations::JiraSerializers::IssueEntity do
include JiraServiceHelper include JiraServiceHelper
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Integrations::Jira::IssueSerializer do RSpec.describe Integrations::JiraSerializers::IssueSerializer do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let_it_be(:jira_service) { create(:jira_service, project: project) } let_it_be(:jira_service) { create(:jira_service, project: project) }
......
...@@ -102,7 +102,7 @@ RSpec.describe Vulnerabilities::FindingEntity do ...@@ -102,7 +102,7 @@ RSpec.describe Vulnerabilities::FindingEntity do
before do before do
stub_licensed_features(jira_vulnerabilities_integration: true) stub_licensed_features(jira_vulnerabilities_integration: true)
allow_next_found_instance_of(JiraService) do |jira| allow_next_found_instance_of(Integrations::Jira) do |jira|
allow(jira).to receive(:jira_project_id).and_return('11223') allow(jira).to receive(:jira_project_id).and_return('11223')
end end
end end
......
...@@ -784,6 +784,7 @@ module API ...@@ -784,6 +784,7 @@ module API
::Integrations::Datadog, ::Integrations::Datadog,
::Integrations::EmailsOnPush, ::Integrations::EmailsOnPush,
::Integrations::Ewm, ::Integrations::Ewm,
::Integrations::Jira,
::Integrations::Redmine, ::Integrations::Redmine,
::Integrations::Youtrack, ::Integrations::Youtrack,
::BuildkiteService, ::BuildkiteService,
...@@ -794,7 +795,6 @@ module API ...@@ -794,7 +795,6 @@ module API
::HangoutsChatService, ::HangoutsChatService,
::IrkerService, ::IrkerService,
::JenkinsService, ::JenkinsService,
::JiraService,
::MattermostSlashCommandsService, ::MattermostSlashCommandsService,
::SlackSlashCommandsService, ::SlackSlashCommandsService,
::PackagistService, ::PackagistService,
......
...@@ -5,7 +5,7 @@ module Gitlab ...@@ -5,7 +5,7 @@ module Gitlab
class StiType < ActiveRecord::Type::String class StiType < ActiveRecord::Type::String
NAMESPACED_INTEGRATIONS = Set.new(%w( NAMESPACED_INTEGRATIONS = Set.new(%w(
Asana Assembla Bamboo Bugzilla Campfire Confluence CustomIssueTracker Datadog Asana Assembla Bamboo Bugzilla Campfire Confluence CustomIssueTracker Datadog
EmailsOnPush Ewm IssueTracker Redmine Youtrack EmailsOnPush Ewm IssueTracker Jira Redmine Youtrack
)).freeze )).freeze
def cast(value) def cast(value)
......
...@@ -227,7 +227,7 @@ module Gitlab ...@@ -227,7 +227,7 @@ module Gitlab
} }
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
JiraService.active.includes(:jira_tracker_data).find_in_batches(batch_size: 100) do |services| ::Integrations::Jira.active.includes(:jira_tracker_data).find_in_batches(batch_size: 100) do |services|
counts = services.group_by do |service| counts = services.group_by do |service|
# TODO: Simplify as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 # TODO: Simplify as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
service_url = service.data_fields&.url || (service.properties && service.properties['url']) service_url = service.data_fields&.url || (service.properties && service.properties['url'])
......
...@@ -18662,6 +18662,9 @@ msgstr "" ...@@ -18662,6 +18662,9 @@ msgstr ""
msgid "JiraService|GitLab for Jira Configuration" msgid "JiraService|GitLab for Jira Configuration"
msgstr "" msgstr ""
msgid "JiraService|IDs must be a list of numbers that can be split with , or ;"
msgstr ""
msgid "JiraService|If different from Web URL." msgid "JiraService|If different from Web URL."
msgstr "" msgstr ""
...@@ -18677,10 +18680,10 @@ msgstr "" ...@@ -18677,10 +18680,10 @@ msgstr ""
msgid "JiraService|Jira Issues" msgid "JiraService|Jira Issues"
msgstr "" msgstr ""
msgid "JiraService|Jira comments will be created when an issue gets referenced in a commit." msgid "JiraService|Jira comments are created when an issue is referenced in a commit."
msgstr "" msgstr ""
msgid "JiraService|Jira comments will be created when an issue gets referenced in a merge request." msgid "JiraService|Jira comments are created when an issue is referenced in a merge request."
msgstr "" msgstr ""
msgid "JiraService|Jira issue type" msgid "JiraService|Jira issue type"
...@@ -18770,9 +18773,6 @@ msgstr "" ...@@ -18770,9 +18773,6 @@ msgstr ""
msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}." msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
msgstr "" msgstr ""
msgid "JiraService|transition ids can have only numbers which can be split with , or ;"
msgstr ""
msgid "Job" msgid "Job"
msgstr "" msgstr ""
......
...@@ -93,8 +93,8 @@ RSpec.describe Admin::IntegrationsController do ...@@ -93,8 +93,8 @@ RSpec.describe Admin::IntegrationsController do
end end
it 'deletes the integration and all inheriting integrations' do it 'deletes the integration and all inheriting integrations' do
expect { subject }.to change { JiraService.for_instance.count }.by(-1) expect { subject }.to change { Integrations::Jira.for_instance.count }.by(-1)
.and change { JiraService.inherit_from_id(integration.id).count }.by(-1) .and change { Integrations::Jira.inherit_from_id(integration.id).count }.by(-1)
end end
end end
end end
...@@ -124,8 +124,8 @@ RSpec.describe Groups::Settings::IntegrationsController do ...@@ -124,8 +124,8 @@ RSpec.describe Groups::Settings::IntegrationsController do
end end
it 'deletes the integration and all inheriting integrations' do it 'deletes the integration and all inheriting integrations' do
expect { subject }.to change { JiraService.for_group(group.id).count }.by(-1) expect { subject }.to change { Integrations::Jira.for_group(group.id).count }.by(-1)
.and change { JiraService.inherit_from_id(integration.id).count }.by(-1) .and change { Integrations::Jira.inherit_from_id(integration.id).count }.by(-1)
end end
end end
end end
......
...@@ -45,7 +45,7 @@ FactoryBot.define do ...@@ -45,7 +45,7 @@ FactoryBot.define do
token { 'test' } token { 'test' }
end end
factory :jira_service do factory :jira_service, class: 'Integrations::Jira' do
project project
active { true } active { true }
type { 'JiraService' } type { 'JiraService' }
......
...@@ -43,7 +43,7 @@ RSpec.describe 'Edit Project Settings' do ...@@ -43,7 +43,7 @@ RSpec.describe 'Edit Project Settings' do
context 'When external issue tracker is enabled and issues enabled on project settings' do context 'When external issue tracker is enabled and issues enabled on project settings' do
it 'does not hide issues tab and hides labels tab' do it 'does not hide issues tab and hides labels tab' do
allow_next_instance_of(Project) do |instance| allow_next_instance_of(Project) do |instance|
allow(instance).to receive(:external_issue_tracker).and_return(JiraService.new) allow(instance).to receive(:external_issue_tracker).and_return(Integrations::Jira.new)
end end
visit project_path(project) visit project_path(project)
...@@ -58,7 +58,7 @@ RSpec.describe 'Edit Project Settings' do ...@@ -58,7 +58,7 @@ RSpec.describe 'Edit Project Settings' do
project.issues_enabled = false project.issues_enabled = false
project.save! project.save!
allow_next_instance_of(Project) do |instance| allow_next_instance_of(Project) do |instance|
allow(instance).to receive(:external_issue_tracker).and_return(JiraService.new) allow(instance).to receive(:external_issue_tracker).and_return(Integrations::Jira.new)
end end
end end
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe JiraService do RSpec.describe Integrations::Jira do
include AssetsHelpers include AssetsHelpers
let_it_be(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
...@@ -493,7 +493,7 @@ RSpec.describe JiraService do ...@@ -493,7 +493,7 @@ RSpec.describe JiraService do
before do before do
jira_service.jira_issue_transition_id = '999' jira_service.jira_issue_transition_id = '999'
# These stubs are needed to test JiraService#close_issue. # 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. # 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. # 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_service.client, attrs: issue_fields.deep_stringify_keys)
...@@ -829,7 +829,7 @@ RSpec.describe JiraService do ...@@ -829,7 +829,7 @@ RSpec.describe JiraService do
context 'when disabled' do context 'when disabled' do
before do before do
allow_next_instance_of(JiraService) do |instance| allow_next_instance_of(described_class) do |instance|
allow(instance).to receive(:commit_events) { false } allow(instance).to receive(:commit_events) { false }
end end
end end
...@@ -847,7 +847,7 @@ RSpec.describe JiraService do ...@@ -847,7 +847,7 @@ RSpec.describe JiraService do
context 'when disabled' do context 'when disabled' do
before do before do
allow_next_instance_of(JiraService) do |instance| allow_next_instance_of(described_class) do |instance|
allow(instance).to receive(:merge_requests_events) { false } allow(instance).to receive(:merge_requests_events) { false }
end end
end end
......
...@@ -100,7 +100,7 @@ RSpec.describe DataFields do ...@@ -100,7 +100,7 @@ RSpec.describe DataFields do
context 'when service and data_fields are not persisted' do context 'when service and data_fields are not persisted' do
let(:service) do let(:service) do
JiraService.new Integrations::Jira.new
end end
describe 'data_fields_present?' do describe 'data_fields_present?' do
......
...@@ -17,14 +17,14 @@ RSpec.describe BulkUpdateIntegrationService do ...@@ -17,14 +17,14 @@ RSpec.describe BulkUpdateIntegrationService do
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let_it_be(:subgroup) { create(:group, parent: group) } let_it_be(:subgroup) { create(:group, parent: group) }
let_it_be(:group_integration) do let_it_be(:group_integration) do
JiraService.create!( Integrations::Jira.create!(
group: group, group: group,
url: 'http://group.jira.com' url: 'http://group.jira.com'
) )
end end
let_it_be(:subgroup_integration) do let_it_be(:subgroup_integration) do
JiraService.create!( Integrations::Jira.create!(
inherit_from_id: group_integration.id, inherit_from_id: group_integration.id,
group: subgroup, group: subgroup,
url: 'http://subgroup.jira.com', url: 'http://subgroup.jira.com',
...@@ -33,7 +33,7 @@ RSpec.describe BulkUpdateIntegrationService do ...@@ -33,7 +33,7 @@ RSpec.describe BulkUpdateIntegrationService do
end end
let_it_be(:excluded_integration) do let_it_be(:excluded_integration) do
JiraService.create!( Integrations::Jira.create!(
group: create(:group), group: create(:group),
url: 'http://another.jira.com', url: 'http://another.jira.com',
push_events: false push_events: false
...@@ -41,7 +41,7 @@ RSpec.describe BulkUpdateIntegrationService do ...@@ -41,7 +41,7 @@ RSpec.describe BulkUpdateIntegrationService do
end end
let_it_be(:integration) do let_it_be(:integration) do
JiraService.create!( Integrations::Jira.create!(
project: create(:project, group: subgroup), project: create(:project, group: subgroup),
inherit_from_id: subgroup_integration.id, inherit_from_id: subgroup_integration.id,
url: 'http://project.jira.com', url: 'http://project.jira.com',
......
...@@ -181,7 +181,7 @@ RSpec.describe MergeRequests::MergeService do ...@@ -181,7 +181,7 @@ RSpec.describe MergeRequests::MergeService do
commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}") commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
allow(merge_request).to receive(:commits).and_return([commit]) allow(merge_request).to receive(:commits).and_return([commit])
expect_any_instance_of(JiraService).to receive(:close_issue).with(merge_request, jira_issue, user).once expect_any_instance_of(Integrations::Jira).to receive(:close_issue).with(merge_request, jira_issue, user).once
service.execute(merge_request) service.execute(merge_request)
end end
...@@ -193,7 +193,7 @@ RSpec.describe MergeRequests::MergeService do ...@@ -193,7 +193,7 @@ RSpec.describe MergeRequests::MergeService do
commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}") commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
allow(merge_request).to receive(:commits).and_return([commit]) allow(merge_request).to receive(:commits).and_return([commit])
expect_any_instance_of(JiraService).not_to receive(:close_issue) expect_any_instance_of(Integrations::Jira).not_to receive(:close_issue)
service.execute(merge_request) service.execute(merge_request)
end end
......
...@@ -3,7 +3,7 @@ require 'spec_helper' ...@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe ProjectServiceWorker, '#perform' do RSpec.describe ProjectServiceWorker, '#perform' do
let(:worker) { described_class.new } let(:worker) { described_class.new }
let(:service) { JiraService.new } let(:service) { Integrations::Jira.new }
before do before do
allow(Integration).to receive(:find).and_return(service) allow(Integration).to receive(:find).and_return(service)
......
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