Commit 2c7cdd52 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'mention-notification-level' into 'master'

Mention notification level

It does disable all emails expect system one or when you was @mentioned.

Fixes #1724

See merge request !1359
parents 6aec286f 0d8118c6
...@@ -4,7 +4,7 @@ v 7.7.0 ...@@ -4,7 +4,7 @@ v 7.7.0
- Add Jetbrains Teamcity CI service (Jason Lippert) - Add Jetbrains Teamcity CI service (Jason Lippert)
- -
- -
- - Mention notification level
- -
- -
- OAuth applications feature - OAuth applications feature
......
...@@ -6,12 +6,13 @@ class Notification ...@@ -6,12 +6,13 @@ class Notification
N_PARTICIPATING = 1 N_PARTICIPATING = 1
N_WATCH = 2 N_WATCH = 2
N_GLOBAL = 3 N_GLOBAL = 3
N_MENTION = 4
attr_accessor :target attr_accessor :target
class << self class << self
def notification_levels def notification_levels
[N_DISABLED, N_PARTICIPATING, N_WATCH] [N_DISABLED, N_PARTICIPATING, N_WATCH, N_MENTION]
end end
def options_with_labels def options_with_labels
...@@ -19,12 +20,13 @@ class Notification ...@@ -19,12 +20,13 @@ class Notification
disabled: N_DISABLED, disabled: N_DISABLED,
participating: N_PARTICIPATING, participating: N_PARTICIPATING,
watch: N_WATCH, watch: N_WATCH,
mention: N_MENTION,
global: N_GLOBAL global: N_GLOBAL
} }
end end
def project_notification_levels def project_notification_levels
[N_DISABLED, N_PARTICIPATING, N_WATCH, N_GLOBAL] [N_DISABLED, N_PARTICIPATING, N_WATCH, N_GLOBAL, N_MENTION]
end end
end end
...@@ -48,6 +50,10 @@ class Notification ...@@ -48,6 +50,10 @@ class Notification
target.notification_level == N_GLOBAL target.notification_level == N_GLOBAL
end end
def mention?
target.notification_level == N_MENTION
end
def level def level
target.notification_level target.notification_level
end end
......
...@@ -144,6 +144,10 @@ class NotificationService ...@@ -144,6 +144,10 @@ class NotificationService
# Merge project watchers # Merge project watchers
recipients = recipients.concat(project_watchers(note.project)).compact.uniq recipients = recipients.concat(project_watchers(note.project)).compact.uniq
# Reject mention users unless mentioned in comment
recipients = reject_mention_users(recipients - note.mentioned_users, note.project)
recipients = recipients + note.mentioned_users
# Reject mutes users # Reject mutes users
recipients = reject_muted_users(recipients, note.project) recipients = reject_muted_users(recipients, note.project)
...@@ -285,13 +289,39 @@ class NotificationService ...@@ -285,13 +289,39 @@ class NotificationService
end end
end end
# Remove users with notification level 'Mentioned'
def reject_mention_users(users, project = nil)
users = users.to_a.compact.uniq
users.reject do |user|
next user.notification.mention? unless project
tm = project.project_members.find_by(user_id: user.id)
if !tm && project.group
tm = project.group.group_members.find_by(user_id: user.id)
end
# reject users who globally set mention notification and has no membership
next user.notification.mention? unless tm
# reject users who set mention notification in project
next true if tm.notification.mention?
# reject users who have N_MENTION in project and disabled in global settings
tm.notification.global? && user.notification.mention?
end
end
def new_resource_email(target, project, method) def new_resource_email(target, project, method)
if target.respond_to?(:participants) if target.respond_to?(:participants)
recipients = target.participants recipients = target.participants
else else
recipients = [] recipients = []
end end
recipients = reject_muted_users(recipients, project) recipients = reject_muted_users(recipients, project)
recipients = reject_mention_users(recipients, project)
recipients = recipients.concat(project_watchers(project)).uniq recipients = recipients.concat(project_watchers(project)).uniq
recipients.delete(target.author) recipients.delete(target.author)
...@@ -302,6 +332,7 @@ class NotificationService ...@@ -302,6 +332,7 @@ class NotificationService
def close_resource_email(target, project, current_user, method) def close_resource_email(target, project, current_user, method)
recipients = reject_muted_users([target.author, target.assignee], project) recipients = reject_muted_users([target.author, target.assignee], project)
recipients = reject_mention_users(recipients, project)
recipients = recipients.concat(project_watchers(project)).uniq recipients = recipients.concat(project_watchers(project)).uniq
recipients.delete(current_user) recipients.delete(current_user)
...@@ -320,6 +351,7 @@ class NotificationService ...@@ -320,6 +351,7 @@ class NotificationService
# reject users with disabled notifications # reject users with disabled notifications
recipients = reject_muted_users(recipients, project) recipients = reject_muted_users(recipients, project)
recipients = reject_mention_users(recipients, project)
# Reject me from recipients if I reassign an item # Reject me from recipients if I reassign an item
recipients.delete(current_user) recipients.delete(current_user)
...@@ -331,6 +363,7 @@ class NotificationService ...@@ -331,6 +363,7 @@ class NotificationService
def reopen_resource_email(target, project, current_user, method, status) def reopen_resource_email(target, project, current_user, method, status)
recipients = reject_muted_users([target.author, target.assignee], project) recipients = reject_muted_users([target.author, target.assignee], project)
recipients = reject_mention_users(recipients, project)
recipients = recipients.concat(project_watchers(project)).uniq recipients = recipients.concat(project_watchers(project)).uniq
recipients.delete(current_user) recipients.delete(current_user)
......
...@@ -15,6 +15,13 @@ ...@@ -15,6 +15,13 @@
Disabled Disabled
%p You will not get any notifications via email %p You will not get any notifications via email
.radio
= label_tag nil, class: '' do
= radio_button_tag :notification_level, Notification::N_MENTION, @notification.mention?, class: 'trigger-submit'
.level-title
Mention
%p You will receive notifications only for comments where you was @mentioned
.radio .radio
= label_tag nil, class: '' do = label_tag nil, class: '' do
= radio_button_tag :notification_level, Notification::N_PARTICIPATING, @notification.participating?, class: 'trigger-submit' = radio_button_tag :notification_level, Notification::N_PARTICIPATING, @notification.participating?, class: 'trigger-submit'
......
...@@ -116,6 +116,7 @@ describe NotificationService do ...@@ -116,6 +116,7 @@ describe NotificationService do
should_email(note.noteable.assignee_id) should_email(note.noteable.assignee_id)
should_not_email(note.author_id) should_not_email(note.author_id)
should_not_email(@u_mentioned.id)
should_not_email(@u_disabled.id) should_not_email(@u_disabled.id)
should_not_email(@u_not_mentioned.id) should_not_email(@u_not_mentioned.id)
notification.new_note(note) notification.new_note(note)
...@@ -168,6 +169,12 @@ describe NotificationService do ...@@ -168,6 +169,12 @@ describe NotificationService do
notification.new_note(note) notification.new_note(note)
end end
it do
@u_committer.update_attributes(notification_level: Notification::N_MENTION)
should_not_email(@u_committer.id, note)
notification.new_note(note)
end
def should_email(user_id, n) def should_email(user_id, n)
Notify.should_receive(:note_commit_email).with(user_id, n.id) Notify.should_receive(:note_commit_email).with(user_id, n.id)
end end
...@@ -190,11 +197,18 @@ describe NotificationService do ...@@ -190,11 +197,18 @@ describe NotificationService do
it do it do
should_email(issue.assignee_id) should_email(issue.assignee_id)
should_email(@u_watcher.id) should_email(@u_watcher.id)
should_not_email(@u_mentioned.id)
should_not_email(@u_participating.id) should_not_email(@u_participating.id)
should_not_email(@u_disabled.id) should_not_email(@u_disabled.id)
notification.new_issue(issue, @u_disabled) notification.new_issue(issue, @u_disabled)
end end
it do
issue.assignee.update_attributes(notification_level: Notification::N_MENTION)
should_not_email(issue.assignee_id)
notification.new_issue(issue, @u_disabled)
end
def should_email(user_id) def should_email(user_id)
Notify.should_receive(:new_issue_email).with(user_id, issue.id) Notify.should_receive(:new_issue_email).with(user_id, issue.id)
end end
...@@ -391,7 +405,7 @@ describe NotificationService do ...@@ -391,7 +405,7 @@ describe NotificationService do
@u_watcher = create(:user, notification_level: Notification::N_WATCH) @u_watcher = create(:user, notification_level: Notification::N_WATCH)
@u_participating = create(:user, notification_level: Notification::N_PARTICIPATING) @u_participating = create(:user, notification_level: Notification::N_PARTICIPATING)
@u_disabled = create(:user, notification_level: Notification::N_DISABLED) @u_disabled = create(:user, notification_level: Notification::N_DISABLED)
@u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_PARTICIPATING) @u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_MENTION)
@u_committer = create(:user, username: 'committer') @u_committer = create(:user, username: 'committer')
@u_not_mentioned = create(:user, username: 'regular', notification_level: Notification::N_PARTICIPATING) @u_not_mentioned = create(:user, username: 'regular', notification_level: Notification::N_PARTICIPATING)
......
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