summaryrefslogtreecommitdiff
path: root/app/services/notification_recipients/builder/default.rb
blob: 58b0cd510c94f4a359cda6b1b9be7fea1cd5dfb5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# frozen_string_literal: true

module NotificationRecipients
  module Builder
    class Default < Base
      MENTION_TYPE_ACTIONS = [:new_issue, :new_merge_request].freeze

      attr_reader :target
      attr_reader :current_user
      attr_reader :action
      attr_reader :previous_assignees
      attr_reader :skip_current_user

      def initialize(target, current_user, action:, custom_action: nil, previous_assignees: nil, skip_current_user: true)
        @target = target
        @current_user = current_user
        @action = action
        @custom_action = custom_action
        @previous_assignees = previous_assignees
        @skip_current_user = skip_current_user
      end

      def add_watchers
        add_project_watchers
      end

      def build!
        add_participants(current_user)
        add_watchers
        add_custom_notifications

        # Re-assign is considered as a mention of the new assignee
        case custom_action
        when :reassign_merge_request, :reassign_issue
          add_recipients(previous_assignees, :mention, nil)
          add_recipients(target.assignees, :mention, NotificationReason::ASSIGNED)
        when :change_reviewer_merge_request
          add_recipients(previous_assignees, :mention, nil)
          add_recipients(target.reviewers, :mention, NotificationReason::REVIEW_REQUESTED)
        end

        add_subscribed_users

        if self.class.mention_type_actions.include?(custom_action)
          # These will all be participants as well, but adding with the :mention
          # type ensures that users with the mention notification level will
          # receive them, too.
          add_mentions(current_user, target: target)

          # We use the `:participating` notification level in order to match existing legacy behavior as captured
          # in existing specs (notification_service_spec.rb ~ line 507)
          if target.is_a?(Issuable)
            add_recipients(target.assignees, :participating, NotificationReason::ASSIGNED)
          end

          add_labels_subscribers
        end
      end

      def acting_user
        current_user if skip_current_user
      end

      # Build event key to search on custom notification level
      # Check NotificationSetting.email_events
      def custom_action
        @custom_action ||= "#{action}_#{target.class.model_name.name.underscore}".to_sym
      end

      def self.mention_type_actions
        MENTION_TYPE_ACTIONS.dup
      end
    end
  end
end

NotificationRecipients::Builder::Default.prepend_mod_with('NotificationRecipients::Builder::Default')