Update NotificationService to use NotificationSettings instead of membership
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
This commit is contained in:
parent
7ea1bcab45
commit
b8f3843790
|
@ -1,15 +0,0 @@
|
|||
# == Notifiable concern
|
||||
#
|
||||
# Contains notification functionality
|
||||
#
|
||||
module Notifiable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
validates :notification_level, inclusion: { in: Notification.project_notification_levels }, presence: true
|
||||
end
|
||||
|
||||
def notification
|
||||
@notification ||= Notification.new(self)
|
||||
end
|
||||
end
|
|
@ -27,6 +27,7 @@ class Group < Namespace
|
|||
has_many :users, through: :group_members
|
||||
has_many :project_group_links, dependent: :destroy
|
||||
has_many :shared_projects, through: :project_group_links, source: :project
|
||||
has_many :notification_settings, dependent: :destroy, as: :source
|
||||
|
||||
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
|
||||
validate :visibility_level_allowed_by_projects
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
class Member < ActiveRecord::Base
|
||||
include Sortable
|
||||
include Notifiable
|
||||
include Gitlab::Access
|
||||
|
||||
attr_accessor :raw_invite_token
|
||||
|
@ -170,6 +169,10 @@ class Member < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def notification
|
||||
@notification ||= user.notification_settings.find_by(source: source)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def send_invite
|
||||
|
|
|
@ -30,30 +30,12 @@ class Notification
|
|||
end
|
||||
end
|
||||
|
||||
delegate :disabled?, :participating?, :watch?, :global?, :mention?, to: :target
|
||||
|
||||
def initialize(target)
|
||||
@target = target
|
||||
end
|
||||
|
||||
def disabled?
|
||||
target.notification_level == N_DISABLED
|
||||
end
|
||||
|
||||
def participating?
|
||||
target.notification_level == N_PARTICIPATING
|
||||
end
|
||||
|
||||
def watch?
|
||||
target.notification_level == N_WATCH
|
||||
end
|
||||
|
||||
def global?
|
||||
target.notification_level == N_GLOBAL
|
||||
end
|
||||
|
||||
def mention?
|
||||
target.notification_level == N_MENTION
|
||||
end
|
||||
|
||||
def level
|
||||
target.notification_level
|
||||
end
|
||||
|
|
|
@ -154,6 +154,7 @@ class Project < ActiveRecord::Base
|
|||
has_many :project_group_links, dependent: :destroy
|
||||
has_many :invited_groups, through: :project_group_links, source: :group
|
||||
has_many :todos, dependent: :destroy
|
||||
has_many :notification_settings, dependent: :destroy, as: :source
|
||||
|
||||
has_one :import_data, dependent: :destroy, class_name: "ProjectImportData"
|
||||
|
||||
|
|
|
@ -193,6 +193,9 @@ class User < ActiveRecord::Base
|
|||
|
||||
# Notification level
|
||||
# Note: When adding an option, it MUST go on the end of the array.
|
||||
#
|
||||
# TODO: Add '_prefix: :notification' to enum when update to Rails 5. https://github.com/rails/rails/pull/19813
|
||||
# Because user.notification_disabled? is much better than user.disabled?
|
||||
enum notification_level: [:disabled, :participating, :watch, :global, :mention]
|
||||
|
||||
alias_attribute :private_token, :authentication_token
|
||||
|
|
|
@ -253,8 +253,8 @@ class NotificationService
|
|||
def project_watchers(project)
|
||||
project_members = project_member_notification(project)
|
||||
|
||||
users_with_project_level_global = project_member_notification(project, Notification::N_GLOBAL)
|
||||
users_with_group_level_global = group_member_notification(project, Notification::N_GLOBAL)
|
||||
users_with_project_level_global = project_member_notification(project, :global)
|
||||
users_with_group_level_global = group_member_notification(project, :global)
|
||||
users = users_with_global_level_watch([users_with_project_level_global, users_with_group_level_global].flatten.uniq)
|
||||
|
||||
users_with_project_setting = select_project_member_setting(project, users_with_project_level_global, users)
|
||||
|
@ -264,18 +264,16 @@ class NotificationService
|
|||
end
|
||||
|
||||
def project_member_notification(project, notification_level=nil)
|
||||
project_members = project.project_members
|
||||
|
||||
if notification_level
|
||||
project_members.where(notification_level: notification_level).pluck(:user_id)
|
||||
project.notification_settings.where(level: NotificationSetting.levels[notification_level]).pluck(:user_id)
|
||||
else
|
||||
project_members.pluck(:user_id)
|
||||
project.notification_settings.pluck(:user_id)
|
||||
end
|
||||
end
|
||||
|
||||
def group_member_notification(project, notification_level)
|
||||
if project.group
|
||||
project.group.group_members.where(notification_level: notification_level).pluck(:user_id)
|
||||
project.group.notification_settings.where(level: NotificationSetting.levels[notification_level]).pluck(:user_id)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
@ -284,13 +282,13 @@ class NotificationService
|
|||
def users_with_global_level_watch(ids)
|
||||
User.where(
|
||||
id: ids,
|
||||
notification_level: Notification::N_WATCH
|
||||
notification_level: NotificationSetting.levels[:watch]
|
||||
).pluck(:id)
|
||||
end
|
||||
|
||||
# Build a list of users based on project notifcation settings
|
||||
def select_project_member_setting(project, global_setting, users_global_level_watch)
|
||||
users = project_member_notification(project, Notification::N_WATCH)
|
||||
users = project_member_notification(project, :watch)
|
||||
|
||||
# If project setting is global, add to watch list if global setting is watch
|
||||
global_setting.each do |user_id|
|
||||
|
@ -304,7 +302,7 @@ class NotificationService
|
|||
|
||||
# Build a list of users based on group notification settings
|
||||
def select_group_member_setting(project, project_members, global_setting, users_global_level_watch)
|
||||
uids = group_member_notification(project, Notification::N_WATCH)
|
||||
uids = group_member_notification(project, :watch)
|
||||
|
||||
# Group setting is watch, add to users list if user is not project member
|
||||
users = []
|
||||
|
@ -351,20 +349,20 @@ class NotificationService
|
|||
users.reject do |user|
|
||||
next user.notification.send(method_name) unless project
|
||||
|
||||
member = project.project_members.find_by(user_id: user.id)
|
||||
setting = user.notification_settings.find_by(source: project)
|
||||
|
||||
if !member && project.group
|
||||
member = project.group.group_members.find_by(user_id: user.id)
|
||||
if !setting && project.group
|
||||
setting = user.notification_settings.find_by(source: group)
|
||||
end
|
||||
|
||||
# reject users who globally set mention notification and has no membership
|
||||
next user.notification.send(method_name) unless member
|
||||
# reject users who globally set mention notification and has no setting per project/group
|
||||
next user.notification.send(method_name) unless setting
|
||||
|
||||
# reject users who set mention notification in project
|
||||
next true if member.notification.send(method_name)
|
||||
next true if setting.send(method_name)
|
||||
|
||||
# reject users who have N_MENTION in project and disabled in global settings
|
||||
member.notification.global? && user.notification.send(method_name)
|
||||
# reject users who have mention level in project and disabled in global settings
|
||||
setting.global? && user.notification.send(method_name)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -89,11 +89,11 @@ describe NotificationService, services: true do
|
|||
note.project.group.add_user(@u_watcher, GroupMember::MASTER)
|
||||
note.project.save
|
||||
user_project = note.project.project_members.find_by_user_id(@u_watcher.id)
|
||||
user_project.notification_level = Notification::N_PARTICIPATING
|
||||
user_project.notification.level = :participating
|
||||
user_project.save
|
||||
group_member = note.project.group.group_members.find_by_user_id(@u_watcher.id)
|
||||
group_member.notification_level = Notification::N_GLOBAL
|
||||
group_member.save
|
||||
group_member.notification.level = :global
|
||||
group_member.notification.save
|
||||
ActionMailer::Base.deliveries.clear
|
||||
end
|
||||
|
||||
|
@ -215,7 +215,7 @@ describe NotificationService, services: true do
|
|||
end
|
||||
|
||||
it do
|
||||
@u_committer.update_attributes(notification_level: Notification::N_MENTION)
|
||||
@u_committer.update_attributes(notification_level: :mention)
|
||||
notification.new_note(note)
|
||||
should_not_email(@u_committer)
|
||||
end
|
||||
|
@ -246,7 +246,7 @@ describe NotificationService, services: true do
|
|||
end
|
||||
|
||||
it do
|
||||
issue.assignee.update_attributes(notification_level: Notification::N_MENTION)
|
||||
issue.assignee.update_attributes(notification_level: :mention)
|
||||
notification.new_issue(issue, @u_disabled)
|
||||
|
||||
should_not_email(issue.assignee)
|
||||
|
@ -596,13 +596,13 @@ describe NotificationService, services: true do
|
|||
end
|
||||
|
||||
def build_team(project)
|
||||
@u_watcher = create(:user, notification_level: Notification::N_WATCH)
|
||||
@u_participating = create(:user, notification_level: Notification::N_PARTICIPATING)
|
||||
@u_participant_mentioned = create(:user, username: 'participant', notification_level: Notification::N_PARTICIPATING)
|
||||
@u_disabled = create(:user, notification_level: Notification::N_DISABLED)
|
||||
@u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_MENTION)
|
||||
@u_watcher = create(:user, notification_level: :watch)
|
||||
@u_participating = create(:user, notification_level: :participating)
|
||||
@u_participant_mentioned = create(:user, username: 'participant', notification_level: :participating)
|
||||
@u_disabled = create(:user, notification_level: :disabled)
|
||||
@u_mentioned = create(:user, username: 'mention', notification_level: :mention)
|
||||
@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: :participating)
|
||||
@u_outsider_mentioned = create(:user, username: 'outsider')
|
||||
|
||||
project.team << [@u_watcher, :master]
|
||||
|
@ -617,8 +617,8 @@ describe NotificationService, services: true do
|
|||
def add_users_with_subscription(project, issuable)
|
||||
@subscriber = create :user
|
||||
@unsubscriber = create :user
|
||||
@subscribed_participant = create(:user, username: 'subscribed_participant', notification_level: Notification::N_PARTICIPATING)
|
||||
@watcher_and_subscriber = create(:user, notification_level: Notification::N_WATCH)
|
||||
@subscribed_participant = create(:user, username: 'subscribed_participant', notification_level: :participating)
|
||||
@watcher_and_subscriber = create(:user, notification_level: :watch)
|
||||
|
||||
project.team << [@subscribed_participant, :master]
|
||||
project.team << [@subscriber, :master]
|
||||
|
|
Loading…
Reference in New Issue