Commit ab79e34a authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch 'issue_299084-allow_to_save_inherited_templates' into 'master'

Allow to save and apply inherited templates on service desk issues

See merge request gitlab-org/gitlab!67786
parents dff0f9da 1b8efb79
...@@ -24,24 +24,31 @@ class Projects::ServiceDeskController < Projects::ApplicationController ...@@ -24,24 +24,31 @@ class Projects::ServiceDeskController < Projects::ApplicationController
private private
def setting_params def setting_params
params.permit(:issue_template_key, :outgoing_name, :project_key) params.permit(*allowed_update_attributes)
end
def allowed_update_attributes
%i(issue_template_key outgoing_name project_key)
end
def service_desk_attributes
service_desk_settings = project.service_desk_setting
{
service_desk_address: project.service_desk_address,
service_desk_enabled: project.service_desk_enabled,
issue_template_key: service_desk_settings&.issue_template_key,
template_file_missing: service_desk_settings&.issue_template_missing?,
outgoing_name: service_desk_settings&.outgoing_name,
project_key: service_desk_settings&.project_key
}
end end
def json_response def json_response
respond_to do |format| respond_to do |format|
service_desk_settings = project.service_desk_setting
service_desk_attributes =
{
service_desk_address: project.service_desk_address,
service_desk_enabled: project.service_desk_enabled,
issue_template_key: service_desk_settings&.issue_template_key,
template_file_missing: service_desk_settings&.issue_template_missing?,
outgoing_name: service_desk_settings&.outgoing_name,
project_key: service_desk_settings&.project_key
}
format.json { render json: service_desk_attributes } format.json { render json: service_desk_attributes }
end end
end end
end end
Projects::ServiceDeskController.prepend_mod
...@@ -19,7 +19,11 @@ class ServiceDeskSetting < ApplicationRecord ...@@ -19,7 +19,11 @@ class ServiceDeskSetting < ApplicationRecord
strong_memoize(:issue_template_content) do strong_memoize(:issue_template_content) do
next unless issue_template_key.present? next unless issue_template_key.present?
Gitlab::Template::IssueTemplate.find(issue_template_key, project).content TemplateFinder.new(
:issues, project,
name: issue_template_key,
source_template_project: source_template_project
).execute.content
rescue ::Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError rescue ::Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError
end end
end end
...@@ -42,6 +46,10 @@ class ServiceDeskSetting < ApplicationRecord ...@@ -42,6 +46,10 @@ class ServiceDeskSetting < ApplicationRecord
private private
def source_template_project
nil
end
def projects_with_same_slug_and_key_exists? def projects_with_same_slug_and_key_exists?
return false unless project_key return false unless project_key
...@@ -53,3 +61,5 @@ class ServiceDeskSetting < ApplicationRecord ...@@ -53,3 +61,5 @@ class ServiceDeskSetting < ApplicationRecord
end end
end end
end end
ServiceDeskSetting.prepend_mod
# frozen_string_literal: true
module EE
module Projects
module ServiceDeskController
extend ::Gitlab::Utils::Override
protected
override :allowed_update_attributes
def allowed_update_attributes
super + %i(file_template_project_id)
end
override :service_desk_attributes
def service_desk_attributes
service_desk_settings = project.service_desk_setting
super.merge(file_template_project_id: service_desk_settings&.file_template_project_id)
end
end
end
end
# frozen_string_literal: true
module EE
module ServiceDeskSetting
extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
prepended do
belongs_to :file_template_project, class_name: "Project", foreign_key: 'file_template_project_id'
end
override :source_template_project
def source_template_project
file_template_project
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Email::Handler::ServiceDeskHandler do
include_context :email_shared_context
before do
stub_incoming_email_setting(enabled: true, address: "incoming+%{key}@appmail.adventuretime.ooo")
stub_config_setting(host: 'localhost')
end
let(:email_raw) { email_fixture('emails/service_desk.eml') }
let_it_be_with_refind(:group) { create(:group, :private, name: "email") }
let(:expected_description) do
"Service desk stuff!\n\n```\na = b\n```\n\n`/label ~label1`\n`/assign @user1`\n`/close`"
end
context 'service desk is enabled for the project' do
let_it_be(:project) { create(:project, :repository, :private, group: group, path: 'test', service_desk_enabled: true) }
before do
allow(Gitlab::ServiceDesk).to receive(:supported?).and_return(true)
end
context 'when everything is fine' do
context 'when using inherited issue templates' do
let_it_be_with_reload(:settings) { create(:service_desk_setting, project: project) }
let_it_be(:project_with_instance_template) { create(:project, :custom_repo, files: { '.gitlab/issue_templates/inherited_instance_template.md' => 'instance template' }) }
context 'from instance' do
before do
stub_licensed_features(custom_file_templates: true)
stub_ee_application_setting(file_template_project: project_with_instance_template)
end
it 'appends instance issue description template' do
settings.update!(issue_template_key: 'inherited_instance_template')
receiver.execute
issue_description = Issue.last.description
expect(issue_description).to include(expected_description)
expect(issue_description.lines.last).to eq('instance template')
end
end
context 'from groups' do
let_it_be(:project_with_group_template) { create(:project, :custom_repo, files: { '.gitlab/issue_templates/inherited_group_template.md' => 'group template' }) }
before do
stub_licensed_features(custom_file_templates_for_namespace: true)
end
it 'appends group issue description template' do
create(:project_group_link, project: project_with_group_template, group: group)
group.update!(file_template_project_id: project_with_group_template.id)
settings.update!(issue_template_key: 'inherited_group_template')
receiver.execute
issue_description = Issue.last.description
expect(issue_description).to include(expected_description)
expect(issue_description.lines.last).to eq('group template')
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ServiceDeskSetting do
let_it_be_with_refind(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
let_it_be(:project_with_group_template) { create(:project, :custom_repo, files: { '.gitlab/issue_templates/inherited_group_template.md' => 'group template' }) }
let_it_be(:project_with_instance_template) { create(:project, :custom_repo, files: { '.gitlab/issue_templates/inherited_instance_template.md' => 'instance template' }) }
before_all do
create(:project_group_link, project: project_with_group_template, group: group)
end
subject { build(:service_desk_setting) }
describe '.issue_template_content' do
context 'when file_template_project_id is present' do
context 'for group templates' do
before do
stub_licensed_features(custom_file_templates_for_namespace: true)
group.update!(file_template_project_id: project_with_group_template.id)
end
it 'returns template content' do
settings =
build(:service_desk_setting,
project: project,
file_template_project_id:
project_with_group_template.id,
issue_template_key: 'inherited_group_template'
)
expect(settings.issue_template_content).to eq('group template')
end
end
context 'for instance templates' do
before do
stub_licensed_features(custom_file_templates: true)
stub_ee_application_setting(file_template_project: project_with_instance_template)
end
it 'returns template content' do
settings = build(:service_desk_setting, project: project, file_template_project_id: project_with_instance_template.id, issue_template_key: 'inherited_instance_template')
expect(settings.issue_template_content).to eq('instance template')
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::ServiceDeskController do
let_it_be(:project) do
create(:project, :private, :custom_repo, service_desk_enabled: true,
files: { '.gitlab/issue_templates/service_desk.md' => 'template' })
end
let_it_be(:template_project) { create(:project) }
let_it_be(:user) { create(:user) }
before do
project.add_maintainer(user)
sign_in(user)
end
describe 'PUT service desk properties' do
it 'sets file_template_project_id', :aggregate_failures do
params = {
namespace_id: project.namespace.to_param,
project_id: project,
issue_template_key: 'service_desk',
file_template_project_id: template_project.id,
format: :json
}
put namespace_project_service_desk_refresh_path(params)
settings = project.service_desk_setting
expect(settings).to be_present
expect(settings.issue_template_key).to eq('service_desk')
expect(json_response['template_file_missing']).to eq(false)
expect(json_response['issue_template_key']).to eq('service_desk')
expect(json_response['file_template_project_id']).to eq(template_project.id)
end
end
end
...@@ -56,32 +56,17 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do ...@@ -56,32 +56,17 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do
let(:templates) do let(:templates) do
{ {
"" => [ "" => [
{ name: "another_issue_template", id: "another_issue_template" }, { name: "another_issue_template", id: "another_issue_template", project_id: project.id },
{ name: "custom_issue_template", id: "custom_issue_template" } { name: "custom_issue_template", id: "custom_issue_template", project_id: project.id }
] ]
} }
end end
it 'returns project templates only' do it 'returns project templates' do
expect(helper.issuable_templates_names(Issue.new)).to eq(%w[another_issue_template custom_issue_template]) expect(helper.issuable_templates_names(Issue.new)).to eq(%w[another_issue_template custom_issue_template])
end end
end end
context 'without matching project templates' do
let(:templates) do
{
"Project Templates" => [
{ name: "another_issue_template", id: "another_issue_template", project_id: non_existing_record_id },
{ name: "custom_issue_template", id: "custom_issue_template", project_id: non_existing_record_id }
]
}
end
it 'returns empty array' do
expect(helper.issuable_templates_names(Issue.new)).to eq([])
end
end
context 'when there are not templates in the project' do context 'when there are not templates in the project' do
let(:templates) { {} } let(:templates) { {} }
......
...@@ -353,13 +353,4 @@ RSpec.describe Gitlab::Email::Handler::ServiceDeskHandler do ...@@ -353,13 +353,4 @@ RSpec.describe Gitlab::Email::Handler::ServiceDeskHandler do
expect { receiver.execute rescue nil }.not_to change { Issue.count } expect { receiver.execute rescue nil }.not_to change { Issue.count }
end end
end end
def email_fixture(path)
fixture_file(path).gsub('project_id', project.project_id.to_s)
end
def service_desk_fixture(path, slug: nil, key: 'mykey')
slug ||= project.full_path_slug.to_s
fixture_file(path).gsub('project_slug', slug).gsub('project_key', key)
end
end end
...@@ -771,3 +771,5 @@ push_rule: ...@@ -771,3 +771,5 @@ push_rule:
- group - group
bulk_import_export: bulk_import_export:
- group - group
service_desk_setting:
- file_template_project
...@@ -18,6 +18,15 @@ RSpec.shared_context :email_shared_context do ...@@ -18,6 +18,15 @@ RSpec.shared_context :email_shared_context do
end end
end end
def email_fixture(path)
fixture_file(path).gsub('project_id', project.project_id.to_s)
end
def service_desk_fixture(path, slug: nil, key: 'mykey')
slug ||= project.full_path_slug.to_s
fixture_file(path).gsub('project_slug', slug).gsub('project_key', key)
end
RSpec.shared_examples :reply_processing_shared_examples do RSpec.shared_examples :reply_processing_shared_examples do
context 'when the user could not be found' do context 'when the user could not be found' do
before do before do
......
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