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:
- 'ee/spec/features/issues/form_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/services/user_activates_jira_spec.rb'
- 'ee/spec/features/registrations/welcome_spec.rb'
- 'ee/spec/features/security/project/internal_access_spec.rb'
- 'ee/spec/features/security/project/private_access_spec.rb'
......@@ -1151,6 +1150,7 @@ RSpec/AnyInstanceOf:
- 'spec/models/hooks/service_hook_spec.rb'
- 'spec/models/hooks/system_hook_spec.rb'
- 'spec/models/hooks/web_hook_spec.rb'
- 'spec/models/integrations/jira_spec.rb'
- 'spec/models/issue_spec.rb'
- 'spec/models/key_spec.rb'
- 'spec/models/member_spec.rb'
......@@ -1158,7 +1158,6 @@ RSpec/AnyInstanceOf:
- 'spec/models/merge_request_spec.rb'
- 'spec/models/note_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_spec.rb'
- 'spec/models/repository_spec.rb'
......@@ -1662,7 +1661,6 @@ Gitlab/NamespacedClass:
- 'app/models/project_services/irker_service.rb'
- 'app/models/project_services/issue_tracker_data.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/mattermost_service.rb'
- 'app/models/project_services/mattermost_slash_commands_service.rb'
......@@ -2918,7 +2916,6 @@ Style/RegexpLiteralMixedPreserve:
- 'ee/spec/features/groups/saml_enforcement_spec.rb'
- 'ee/spec/features/markdown/metrics_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'
- 'lib/api/invitations.rb'
- 'lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb'
......
......@@ -15,7 +15,7 @@ module Types
definition_methods do
def resolve_type(object, context)
if object.is_a?(::JiraService)
if object.is_a?(::Integrations::Jira)
Types::Projects::Services::JiraServiceType
else
Types::Projects::Services::BaseServiceType
......
......@@ -107,7 +107,7 @@ module ServicesHelper
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_id] = integration.jira_issue_transition_id
end
......
This diff is collapsed.
......@@ -193,6 +193,7 @@ class Project < ApplicationRecord
has_one :datadog_service, class_name: 'Integrations::Datadog'
has_one :emails_on_push_service, class_name: 'Integrations::EmailsOnPush'
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 :youtrack_service, class_name: 'Integrations::Youtrack'
has_one :discord_service
......@@ -209,7 +210,6 @@ class Project < ApplicationRecord
has_one :teamcity_service
has_one :pushover_service
has_one :jenkins_service
has_one :jira_service
has_one :external_wiki_service
has_one :prometheus_service, inverse_of: :project
has_one :mock_ci_service
......@@ -560,7 +560,7 @@ class Project < ApplicationRecord
scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct }
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_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_server, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: false)) }
scope :inc_routes, -> { includes(:route, namespace: :route) }
......
This diff is collapsed.
......@@ -43,9 +43,9 @@ module JiraImport
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
case deployment_type.upcase
when JiraService::DEPLOYMENT_TYPES[:server]
when Integrations::Jira::DEPLOYMENT_TYPES[:server]
ServerUsersMapperService.new(user, project, start_at)
when JiraService::DEPLOYMENT_TYPES[:cloud]
when Integrations::Jira::DEPLOYMENT_TYPES[:cloud]
CloudUsersMapperService.new(user, project, start_at)
else
raise ArgumentError
......
......@@ -302,7 +302,7 @@ It contains information about [integrations](../user/project/integrations/overvi
{
"severity":"ERROR",
"time":"2018-09-06T14:56:20.439Z",
"service_class":"JiraService",
"service_class":"Integrations::Jira",
"project_id":8,
"project_path":"h5bp/html5-boilerplate",
"message":"Error sending message",
......@@ -312,7 +312,7 @@ It contains information about [integrations](../user/project/integrations/overvi
{
"severity":"INFO",
"time":"2018-09-06T17:15:16.365Z",
"service_class":"JiraService",
"service_class":"Integrations::Jira",
"project_id":3,
"project_path":"namespace2/project2",
"message":"Successfully posted",
......
......@@ -54,13 +54,13 @@ module Projects
total_count: finder.total_count
)
::Integrations::Jira::IssueSerializer.new
::Integrations::JiraSerializers::IssueSerializer.new
.with_pagination(request, response)
.represent(jira_issues, project: project)
end
def issue_json
::Integrations::Jira::IssueDetailSerializer.new
::Integrations::JiraSerializers::IssueDetailSerializer.new
.represent(project.jira_service.find_issue(params[:id], rendered_fields: true), project: project)
end
......
......@@ -34,7 +34,7 @@ module Resolvers
def serialize_external_issue(external_issue, external_type)
case external_type
when 'jira'
::Integrations::Jira::IssueSerializer
::Integrations::JiraSerializers::IssueSerializer
.new
.represent(external_issue, project: object.vulnerability.project, only: %i[title references status external_tracker web_url created_at updated_at] )
end
......
......@@ -13,7 +13,7 @@ module EE
def integration_form_data(integration, group: nil)
form_data = super
if integration.is_a?(JiraService)
if integration.is_a?(Integrations::Jira)
form_data.merge!(
show_jira_issues_integration: @project&.jira_issues_integration_available?.to_s,
show_jira_vulnerabilities_integration: integration.jira_vulnerabilities_integration_available?.to_s,
......
......@@ -15,7 +15,7 @@ module VulnerabilitiesHelper
new_issue_url: new_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]),
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),
create_mr_url: create_vulnerability_feedback_merge_request_path(vulnerability.finding.project),
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
module Integrations
module Jira
class IssueDetailEntity < ::Integrations::Jira::IssueEntity
module JiraSerializers
class IssueDetailEntity < ::Integrations::JiraSerializers::IssueEntity
expose :description_html do |jira_issue|
jira_gfm_pipeline(jira_issue.renderedFields['description'])
end
......
# frozen_string_literal: true
module Integrations
module Jira
module JiraSerializers
class IssueDetailSerializer < BaseSerializer
entity ::Integrations::Jira::IssueDetailEntity
entity ::Integrations::JiraSerializers::IssueDetailEntity
end
end
end
# frozen_string_literal: true
module Integrations
module Jira
module JiraSerializers
class IssueEntity < Grape::Entity
include RequestAwareEntity
......
# frozen_string_literal: true
module Integrations
module Jira
module JiraSerializers
class IssueSerializer < BaseSerializer
include WithPagination
entity ::Integrations::Jira::IssueEntity
entity ::Integrations::JiraSerializers::IssueEntity
end
end
end
......@@ -567,7 +567,7 @@ module EE
min_id = minimum_id(JiraTrackerData.where(issues_enabled: true), :service_id)
max_id = maximum_id(JiraTrackerData.where(issues_enabled: true), :service_id)
# 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
# rubocop:enable CodeReuse/ActiveRecord
......
......@@ -46,7 +46,7 @@ module Sidebars
override :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
private
......
......@@ -71,7 +71,7 @@ RSpec.describe Projects::Integrations::Jira::IssuesController do
expect(finder).to receive(:execute).and_return(jira_issues)
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)
end
......@@ -203,11 +203,11 @@ RSpec.describe Projects::Integrations::Jira::IssuesController do
before do
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)
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)
end
end
......
......@@ -15,7 +15,9 @@ RSpec.describe 'User activates Jira', :js do
context 'when Jira connection test succeeds' do
before do
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')
fill_form
......
......@@ -184,7 +184,7 @@ RSpec.describe VulnerabilitiesHelper do
describe '#create_jira_issue_url_for' do
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
allow(helper).to receive(:can?).and_return(true)
......@@ -231,7 +231,7 @@ RSpec.describe VulnerabilitiesHelper do
subject
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)
subject
......
......@@ -12,7 +12,7 @@ RSpec.describe Sidebars::Projects::Menus::JiraMenu do
subject { described_class.new(context) }
describe 'render?' do
context 'when issue tracker is not a JiraService' do
context 'when issue tracker is not Jira' do
it 'returns false' do
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
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') }
context 'when issues integration is disabled' do
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe JiraService do
RSpec.describe Integrations::Jira do
let(:jira_service) { build(:jira_service, **options) }
let(:headers) { { 'Content-Type' => 'application/json' } }
......@@ -167,11 +167,11 @@ RSpec.describe JiraService do
end
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, /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, /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/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\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/issuetype\z}).to_return(body: issue_types_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, %r{api/2/issuetypescheme/mapping\?issueTypeSchemeId\=10126\z}).to_return(body: issue_type_mapping_response.to_json, headers: headers)
end
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
allow(jira_service.data_fields).to receive(:deployment_cloud?).and_return(false)
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, /api\/2\/issuetype\z/).to_return(body: issue_types_response.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, %r{api/2/issuetype\z}).to_return(body: issue_types_response.to_json, headers: headers)
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" }] }) }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Integrations::Jira::IssueDetailEntity do
RSpec.describe Integrations::JiraSerializers::IssueDetailEntity do
include JiraServiceHelper
let_it_be(:project) { create(:project) }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Integrations::Jira::IssueEntity do
RSpec.describe Integrations::JiraSerializers::IssueEntity do
include JiraServiceHelper
let_it_be(:project) { create(:project) }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Integrations::Jira::IssueSerializer do
RSpec.describe Integrations::JiraSerializers::IssueSerializer do
let_it_be(:project) { create(:project) }
let_it_be(:jira_service) { create(:jira_service, project: project) }
......
......@@ -102,7 +102,7 @@ RSpec.describe Vulnerabilities::FindingEntity do
before do
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')
end
end
......
......@@ -784,6 +784,7 @@ module API
::Integrations::Datadog,
::Integrations::EmailsOnPush,
::Integrations::Ewm,
::Integrations::Jira,
::Integrations::Redmine,
::Integrations::Youtrack,
::BuildkiteService,
......@@ -794,7 +795,6 @@ module API
::HangoutsChatService,
::IrkerService,
::JenkinsService,
::JiraService,
::MattermostSlashCommandsService,
::SlackSlashCommandsService,
::PackagistService,
......
......@@ -5,7 +5,7 @@ module Gitlab
class StiType < ActiveRecord::Type::String
NAMESPACED_INTEGRATIONS = Set.new(%w(
Asana Assembla Bamboo Bugzilla Campfire Confluence CustomIssueTracker Datadog
EmailsOnPush Ewm IssueTracker Redmine Youtrack
EmailsOnPush Ewm IssueTracker Jira Redmine Youtrack
)).freeze
def cast(value)
......
......@@ -227,7 +227,7 @@ module Gitlab
}
# 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|
# TODO: Simplify as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
service_url = service.data_fields&.url || (service.properties && service.properties['url'])
......
......@@ -18662,6 +18662,9 @@ msgstr ""
msgid "JiraService|GitLab for Jira Configuration"
msgstr ""
msgid "JiraService|IDs must be a list of numbers that can be split with , or ;"
msgstr ""
msgid "JiraService|If different from Web URL."
msgstr ""
......@@ -18677,10 +18680,10 @@ msgstr ""
msgid "JiraService|Jira Issues"
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 ""
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 ""
msgid "JiraService|Jira issue type"
......@@ -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}."
msgstr ""
msgid "JiraService|transition ids can have only numbers which can be split with , or ;"
msgstr ""
msgid "Job"
msgstr ""
......
......@@ -93,8 +93,8 @@ RSpec.describe Admin::IntegrationsController do
end
it 'deletes the integration and all inheriting integrations' do
expect { subject }.to change { JiraService.for_instance.count }.by(-1)
.and change { JiraService.inherit_from_id(integration.id).count }.by(-1)
expect { subject }.to change { Integrations::Jira.for_instance.count }.by(-1)
.and change { Integrations::Jira.inherit_from_id(integration.id).count }.by(-1)
end
end
end
......@@ -124,8 +124,8 @@ RSpec.describe Groups::Settings::IntegrationsController do
end
it 'deletes the integration and all inheriting integrations' do
expect { subject }.to change { JiraService.for_group(group.id).count }.by(-1)
.and change { JiraService.inherit_from_id(integration.id).count }.by(-1)
expect { subject }.to change { Integrations::Jira.for_group(group.id).count }.by(-1)
.and change { Integrations::Jira.inherit_from_id(integration.id).count }.by(-1)
end
end
end
......
......@@ -45,7 +45,7 @@ FactoryBot.define do
token { 'test' }
end
factory :jira_service do
factory :jira_service, class: 'Integrations::Jira' do
project
active { true }
type { 'JiraService' }
......
......@@ -43,7 +43,7 @@ RSpec.describe 'Edit 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
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
visit project_path(project)
......@@ -58,7 +58,7 @@ RSpec.describe 'Edit Project Settings' do
project.issues_enabled = false
project.save!
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
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe JiraService do
RSpec.describe Integrations::Jira do
include AssetsHelpers
let_it_be(:project) { create(:project, :repository) }
......@@ -493,7 +493,7 @@ RSpec.describe JiraService do
before do
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.
# 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)
......@@ -829,7 +829,7 @@ RSpec.describe JiraService do
context 'when disabled' 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 }
end
end
......@@ -847,7 +847,7 @@ RSpec.describe JiraService do
context 'when disabled' 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 }
end
end
......
......@@ -100,7 +100,7 @@ RSpec.describe DataFields do
context 'when service and data_fields are not persisted' do
let(:service) do
JiraService.new
Integrations::Jira.new
end
describe 'data_fields_present?' do
......
......@@ -17,14 +17,14 @@ RSpec.describe BulkUpdateIntegrationService do
let_it_be(:group) { create(:group) }
let_it_be(:subgroup) { create(:group, parent: group) }
let_it_be(:group_integration) do
JiraService.create!(
Integrations::Jira.create!(
group: group,
url: 'http://group.jira.com'
)
end
let_it_be(:subgroup_integration) do
JiraService.create!(
Integrations::Jira.create!(
inherit_from_id: group_integration.id,
group: subgroup,
url: 'http://subgroup.jira.com',
......@@ -33,7 +33,7 @@ RSpec.describe BulkUpdateIntegrationService do
end
let_it_be(:excluded_integration) do
JiraService.create!(
Integrations::Jira.create!(
group: create(:group),
url: 'http://another.jira.com',
push_events: false
......@@ -41,7 +41,7 @@ RSpec.describe BulkUpdateIntegrationService do
end
let_it_be(:integration) do
JiraService.create!(
Integrations::Jira.create!(
project: create(:project, group: subgroup),
inherit_from_id: subgroup_integration.id,
url: 'http://project.jira.com',
......
......@@ -181,7 +181,7 @@ RSpec.describe MergeRequests::MergeService do
commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
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)
end
......@@ -193,7 +193,7 @@ RSpec.describe MergeRequests::MergeService do
commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
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)
end
......
......@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe ProjectServiceWorker, '#perform' do
let(:worker) { described_class.new }
let(:service) { JiraService.new }
let(:service) { Integrations::Jira.new }
before do
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