Commit 3ae483de authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'ee-5863-customize-notifications-for-new-epic' into 'master'

Backport of EE changes "Customize notifications for new epic - Web and API"

See merge request gitlab-org/gitlab-ce!20793
parents f271d9b0 f8ee861c
...@@ -48,6 +48,8 @@ Naming/FileName: ...@@ -48,6 +48,8 @@ Naming/FileName:
- 'qa/bin/*' - 'qa/bin/*'
- 'config/**/*' - 'config/**/*'
- 'lib/generators/**/*' - 'lib/generators/**/*'
- 'locale/unfound_translations.rb'
- 'ee/locale/unfound_translations.rb'
- 'ee/lib/generators/**/*' - 'ee/lib/generators/**/*'
IgnoreExecutableScripts: true IgnoreExecutableScripts: true
AllowedAcronyms: AllowedAcronyms:
......
...@@ -5,14 +5,14 @@ class NotificationSettingsController < ApplicationController ...@@ -5,14 +5,14 @@ class NotificationSettingsController < ApplicationController
return render_404 unless can_read?(resource) return render_404 unless can_read?(resource)
@notification_setting = current_user.notification_settings_for(resource) @notification_setting = current_user.notification_settings_for(resource)
@saved = @notification_setting.update(notification_setting_params) @saved = @notification_setting.update(notification_setting_params_for(resource))
render_response render_response
end end
def update def update
@notification_setting = current_user.notification_settings.find(params[:id]) @notification_setting = current_user.notification_settings.find(params[:id])
@saved = @notification_setting.update(notification_setting_params) @saved = @notification_setting.update(notification_setting_params_for(@notification_setting.source))
render_response render_response
end end
...@@ -42,8 +42,8 @@ class NotificationSettingsController < ApplicationController ...@@ -42,8 +42,8 @@ class NotificationSettingsController < ApplicationController
} }
end end
def notification_setting_params def notification_setting_params_for(source)
allowed_fields = NotificationSetting::EMAIL_EVENTS.dup allowed_fields = NotificationSetting.email_events(source).dup
allowed_fields << :level allowed_fields << :level
params.require(:notification_setting).permit(allowed_fields) params.require(:notification_setting).permit(allowed_fields)
end end
......
...@@ -83,21 +83,11 @@ module NotificationsHelper ...@@ -83,21 +83,11 @@ module NotificationsHelper
end end
def notification_event_name(event) def notification_event_name(event)
# All values from NotificationSetting::EMAIL_EVENTS # All values from NotificationSetting.email_events
case event case event
when :success_pipeline when :success_pipeline
s_('NotificationEvent|Successful pipeline') s_('NotificationEvent|Successful pipeline')
else else
N_('NotificationEvent|New note')
N_('NotificationEvent|New issue')
N_('NotificationEvent|Reopen issue')
N_('NotificationEvent|Close issue')
N_('NotificationEvent|Reassign issue')
N_('NotificationEvent|New merge request')
N_('NotificationEvent|Close merge request')
N_('NotificationEvent|Reassign merge request')
N_('NotificationEvent|Merge merge request')
N_('NotificationEvent|Failed pipeline')
s_(event.to_s.humanize) s_(event.to_s.humanize)
end end
end end
......
...@@ -45,6 +45,15 @@ class NotificationSetting < ActiveRecord::Base ...@@ -45,6 +45,15 @@ class NotificationSetting < ActiveRecord::Base
:success_pipeline :success_pipeline
].freeze ].freeze
# Update unfound_translations.rb when events are changed
def self.email_events(source = nil)
EMAIL_EVENTS
end
def email_events
self.class.email_events(source)
end
EXCLUDED_PARTICIPATING_EVENTS = [ EXCLUDED_PARTICIPATING_EVENTS = [
:success_pipeline :success_pipeline
].freeze ].freeze
......
...@@ -130,7 +130,7 @@ module NotificationRecipientService ...@@ -130,7 +130,7 @@ module NotificationRecipientService
end end
def add_project_watchers def add_project_watchers
add_recipients(project_watchers, :watch, nil) add_recipients(project_watchers, :watch, nil) if project
end end
def add_group_watchers def add_group_watchers
...@@ -220,6 +220,8 @@ module NotificationRecipientService ...@@ -220,6 +220,8 @@ module NotificationRecipientService
end end
class Default < Base class Default < Base
MENTION_TYPE_ACTIONS = [:new_issue, :new_merge_request].freeze
attr_reader :target attr_reader :target
attr_reader :current_user attr_reader :current_user
attr_reader :action attr_reader :action
...@@ -252,7 +254,7 @@ module NotificationRecipientService ...@@ -252,7 +254,7 @@ module NotificationRecipientService
add_subscribed_users add_subscribed_users
if [:new_issue, :new_merge_request].include?(custom_action) if self.class.mention_type_actions.include?(custom_action)
# These will all be participants as well, but adding with the :mention # These will all be participants as well, but adding with the :mention
# type ensures that users with the mention notification level will # type ensures that users with the mention notification level will
# receive them, too. # receive them, too.
...@@ -279,10 +281,14 @@ module NotificationRecipientService ...@@ -279,10 +281,14 @@ module NotificationRecipientService
end end
# Build event key to search on custom notification level # Build event key to search on custom notification level
# Check NotificationSetting::EMAIL_EVENTS # Check NotificationSetting.email_events
def custom_action def custom_action
@custom_action ||= "#{action}_#{target.class.model_name.name.underscore}".to_sym @custom_action ||= "#{action}_#{target.class.model_name.name.underscore}".to_sym
end end
def self.mention_type_actions
MENTION_TYPE_ACTIONS.dup
end
end end
class NewNote < Base class NewNote < Base
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
- paragraph = _('Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.') % { notification_link: notification_link.html_safe } - paragraph = _('Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.') % { notification_link: notification_link.html_safe }
#{ paragraph.html_safe } #{ paragraph.html_safe }
.col-lg-8 .col-lg-8
- NotificationSetting::EMAIL_EVENTS.each_with_index do |event, index| - notification_setting.email_events.each_with_index do |event, index|
- field_id = "#{notifications_menu_identifier("modal", notification_setting)}_notification_setting[#{event}]" - field_id = "#{notifications_menu_identifier("modal", notification_setting)}_notification_setting[#{event}]"
.form-group .form-group
.form-check{ class: ("prepend-top-0" if index == 0) } .form-check{ class: ("prepend-top-0" if index == 0) }
......
...@@ -15,7 +15,7 @@ mention ...@@ -15,7 +15,7 @@ mention
custom custom
``` ```
If the `custom` level is used, specific email events can be controlled. Notification email events are defined in the `NotificationSetting::EMAIL_EVENTS` model variable. Currently, these events are recognized: If the `custom` level is used, specific email events can be controlled. Available events are returned by `NotificationSetting.email_events`. Currently, these events are recognized:
``` ```
new_note new_note
......
...@@ -856,7 +856,7 @@ module API ...@@ -856,7 +856,7 @@ module API
class NotificationSetting < Grape::Entity class NotificationSetting < Grape::Entity
expose :level expose :level
expose :events, if: ->(notification_setting, _) { notification_setting.custom? } do expose :events, if: ->(notification_setting, _) { notification_setting.custom? } do
::NotificationSetting::EMAIL_EVENTS.each do |event| ::NotificationSetting.email_events.each do |event|
expose event expose event
end end
end end
......
...@@ -23,7 +23,7 @@ module API ...@@ -23,7 +23,7 @@ module API
params do params do
optional :level, type: String, desc: 'The global notification level' optional :level, type: String, desc: 'The global notification level'
optional :notification_email, type: String, desc: 'The email address to send notifications' optional :notification_email, type: String, desc: 'The email address to send notifications'
NotificationSetting::EMAIL_EVENTS.each do |event| NotificationSetting.email_events.each do |event|
optional event, type: Boolean, desc: 'Enable/disable this notification' optional event, type: Boolean, desc: 'Enable/disable this notification'
end end
end end
...@@ -50,7 +50,9 @@ module API ...@@ -50,7 +50,9 @@ module API
end end
end end
%w[group project].each do |source_type| [Group, Project].each do |source_class|
source_type = source_class.name.underscore
params do params do
requires :id, type: String, desc: "The #{source_type} ID" requires :id, type: String, desc: "The #{source_type} ID"
end end
...@@ -73,7 +75,7 @@ module API ...@@ -73,7 +75,7 @@ module API
end end
params do params do
optional :level, type: String, desc: "The #{source_type} notification level" optional :level, type: String, desc: "The #{source_type} notification level"
NotificationSetting::EMAIL_EVENTS.each do |event| NotificationSetting.email_events(source_class).each do |event|
optional event, type: Boolean, desc: 'Enable/disable this notification' optional event, type: Boolean, desc: 'Enable/disable this notification'
end end
end end
......
# frozen_string_literal: true
# Dynamic translations which needs to be marked by `N_` so they can be found by `rake gettext:find`, see:
# https://github.com/grosser/gettext_i18n_rails#unfound-translations-with-rake-gettextfind
# NotificationSetting.email_events
N_('NotificationEvent|New note')
N_('NotificationEvent|New issue')
N_('NotificationEvent|Reopen issue')
N_('NotificationEvent|Close issue')
N_('NotificationEvent|Reassign issue')
N_('NotificationEvent|New merge request')
N_('NotificationEvent|Close merge request')
N_('NotificationEvent|Reassign merge request')
N_('NotificationEvent|Merge merge request')
N_('NotificationEvent|Failed pipeline')
...@@ -21,10 +21,11 @@ describe NotificationSettingsController do ...@@ -21,10 +21,11 @@ describe NotificationSettingsController do
end end
context 'when authorized' do context 'when authorized' do
let(:notification_setting) { user.notification_settings_for(source) }
let(:custom_events) do let(:custom_events) do
events = {} events = {}
NotificationSetting::EMAIL_EVENTS.each do |event| NotificationSetting.email_events(source).each do |event|
events[event.to_s] = true events[event.to_s] = true
end end
...@@ -36,7 +37,7 @@ describe NotificationSettingsController do ...@@ -36,7 +37,7 @@ describe NotificationSettingsController do
end end
context 'for projects' do context 'for projects' do
let(:notification_setting) { user.notification_settings_for(project) } let(:source) { project }
it 'creates notification setting' do it 'creates notification setting' do
post :create, post :create,
...@@ -67,7 +68,7 @@ describe NotificationSettingsController do ...@@ -67,7 +68,7 @@ describe NotificationSettingsController do
end end
context 'for groups' do context 'for groups' do
let(:notification_setting) { user.notification_settings_for(group) } let(:source) { group }
it 'creates notification setting' do it 'creates notification setting' do
post :create, post :create,
...@@ -145,7 +146,7 @@ describe NotificationSettingsController do ...@@ -145,7 +146,7 @@ describe NotificationSettingsController do
let(:custom_events) do let(:custom_events) do
events = {} events = {}
NotificationSetting::EMAIL_EVENTS.each do |event| notification_setting.email_events.each do |event|
events[event] = "true" events[event] = "true"
end end
end end
......
...@@ -94,9 +94,39 @@ RSpec.describe NotificationSetting do ...@@ -94,9 +94,39 @@ RSpec.describe NotificationSetting do
end end
end end
context 'email events' do describe '.email_events' do
it 'includes EXCLUDED_WATCHER_EVENTS in EMAIL_EVENTS' do subject { described_class.email_events }
expect(described_class::EMAIL_EVENTS).to include(*described_class::EXCLUDED_WATCHER_EVENTS)
it 'returns email events' do
expect(subject).to include(
:new_note,
:new_issue,
:reopen_issue,
:close_issue,
:reassign_issue,
:new_merge_request,
:reopen_merge_request,
:close_merge_request,
:reassign_merge_request,
:merge_merge_request,
:failed_pipeline,
:success_pipeline
)
end
it 'includes EXCLUDED_WATCHER_EVENTS' do
expect(subject).to include(*described_class::EXCLUDED_WATCHER_EVENTS)
end
end
describe '#email_events' do
let(:source) { build(:group) }
subject { build(:notification_setting, source: source) }
it 'calls email_events' do
expect(described_class).to receive(:email_events).with(source)
subject.email_events
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment