Commit 9e616459e068f2ba65f90016a09387a192fe4cfc

Authored by Dmitriy Zaporozhets
1 parent 11d52a15

add watchers to email recipients list. Add emails for close/merge MR

app/observers/merge_request_observer.rb
... ... @@ -7,6 +7,12 @@ class MergeRequestObserver < BaseObserver
7 7  
8 8 def after_close(merge_request, transition)
9 9 Note.create_status_change_note(merge_request, current_user, merge_request.state)
  10 +
  11 + notification.close_mr(merge_request, current_user)
  12 + end
  13 +
  14 + def after_merge(merge_request, transition)
  15 + notification.merge_mr(merge_request, current_user)
10 16 end
11 17  
12 18 def after_reopen(merge_request, transition)
... ...
app/services/notification_service.rb
... ... @@ -17,7 +17,21 @@ class NotificationService
17 17 end
18 18 end
19 19  
20   - # TODO: When we close an issue we should send next emails:
  20 + # When create an issue we should send next emails:
  21 + #
  22 + # * issue assignee if his notification level is not Disabled
  23 + # * project team members with notification level higher then Participating
  24 + #
  25 + def new_issue(issue, current_user)
  26 + recipients = reject_muted_users([issue.assignee])
  27 + recipients = recipients.concat(project_watchers(issue.project)).uniq
  28 +
  29 + recipients.each do |recipient|
  30 + Notify.delay.new_issue_email(recipient.id, issue.id)
  31 + end
  32 + end
  33 +
  34 + # When we close an issue we should send next emails:
21 35 #
22 36 # * issue author if his notification level is not Disabled
23 37 # * issue assignee if his notification level is not Disabled
... ... @@ -26,6 +40,9 @@ class NotificationService
26 40 def close_issue(issue, current_user)
27 41 recipients = reject_muted_users([issue.author, issue.assignee])
28 42  
  43 + # Add watchers to email list
  44 + recipients = recipients.concat(project_watchers(issue.project)).uniq
  45 +
29 46 # Dont send email to me when I close an issue
30 47 recipients.delete(current_user)
31 48  
... ... @@ -43,30 +60,17 @@ class NotificationService
43 60 reassign_email(issue, current_user, 'reassigned_issue_email')
44 61 end
45 62  
46   - # When create an issue we should send next emails:
47   - #
48   - # * issue assignee if his notification level is not Disabled
49   - #
50   - def new_issue(issue, current_user)
51   -
52   - if issue.assignee && issue.assignee != current_user
53   - # skip if assignee notification disabled
54   - return true if issue.assignee.notification.disabled?
55   -
56   - Notify.delay.new_issue_email(issue.id)
57   - end
58   - end
59 63  
60 64 # When create a merge request we should send next emails:
61 65 #
62 66 # * mr assignee if his notification level is not Disabled
63 67 #
64 68 def new_merge_request(merge_request, current_user)
65   - if merge_request.assignee && merge_request.assignee != current_user
66   - # skip if assignee notification disabled
67   - return true if merge_request.assignee.notification.disabled?
  69 + recipients = reject_muted_users([merge_request.assignee])
  70 + recipients = recipients.concat(project_watchers(merge_request.project)).uniq
68 71  
69   - Notify.delay.new_merge_request_email(merge_request.id)
  72 + recipients.each do |recipient|
  73 + Notify.delay.new_merge_request_email(recipient.id, merge_request.id)
70 74 end
71 75 end
72 76  
... ... @@ -79,6 +83,36 @@ class NotificationService
79 83 reassign_email(merge_request, current_user, 'reassigned_merge_request_email')
80 84 end
81 85  
  86 + # When we close a merge request we should send next emails:
  87 + #
  88 + # * merge_request author if his notification level is not Disabled
  89 + # * merge_request assignee if his notification level is not Disabled
  90 + # * project team members with notification level higher then Participating
  91 + #
  92 + def close_mr(merge_request)
  93 + recipients = reject_muted_users([merge_request.author, merge_request.assignee])
  94 + recipients = recipients.concat(project_watchers(merge_request.project)).uniq
  95 +
  96 + recipients.each do |recipient|
  97 + Notify.delay.closed_merge_request_email(recipient.id, merge_request.id)
  98 + end
  99 + end
  100 +
  101 + # When we merge a merge request we should send next emails:
  102 + #
  103 + # * merge_request author if his notification level is not Disabled
  104 + # * merge_request assignee if his notification level is not Disabled
  105 + # * project team members with notification level higher then Participating
  106 + #
  107 + def merge_mr(merge_request)
  108 + recipients = reject_muted_users([merge_request.author, merge_request.assignee])
  109 + recipients = recipients.concat(project_watchers(merge_request.project)).uniq
  110 +
  111 + recipients.each do |recipient|
  112 + Notify.delay.merged_merge_request_email(recipient.id, merge_request.id)
  113 + end
  114 + end
  115 +
82 116 # Notify new user with email after creation
83 117 def new_user(user)
84 118 # Dont email omniauth created users
... ... @@ -119,6 +153,11 @@ class NotificationService
119 153  
120 154 protected
121 155  
  156 + # Get project users with WATCH notification level
  157 + def project_watchers(project)
  158 + project.users.where(notification_level: Notification::N_WATCH)
  159 + end
  160 +
122 161 # Remove users with disabled notifications from array
123 162 # Also remove duplications and nil recipients
124 163 def reject_muted_users(users)
... ... @@ -130,6 +169,9 @@ class NotificationService
130 169 def reassign_email(target, current_user, method)
131 170 recipients = User.where(id: [target.assignee_id, target.assignee_id_was])
132 171  
  172 + # Add watchers to email list
  173 + recipients = recipients.concat(project_watchers(target.project))
  174 +
133 175 # reject users with disabled notifications
134 176 recipients = reject_muted_users(recipients)
135 177  
... ...
app/views/notify/closed_merge_request_email.html.haml 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +%p
  2 + = "Merge Request #{@merge_request.id} was closed"
  3 +%p
  4 + = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request)
  5 +%p
  6 + Branches: #{@merge_request.source_branch} → #{@merge_request.target_branch}
  7 +%p
  8 + Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name}
  9 +
... ...
app/views/notify/merged_merge_request_email.html.haml 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +%p
  2 + = "Merge Request #{@merge_request.id} was merged"
  3 +%p
  4 + = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request)
  5 +%p
  6 + Branches: #{@merge_request.source_branch} → #{@merge_request.target_branch}
  7 +%p
  8 + Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name}
  9 +
... ...
spec/services/notification_service_spec.rb
... ... @@ -23,6 +23,10 @@ describe NotificationService do
23 23 describe 'Issues' do
24 24 let(:issue) { create :issue, assignee: create(:user) }
25 25  
  26 + before do
  27 + build_team(issue.project)
  28 + end
  29 +
26 30 describe :new_issue do
27 31 it 'should sent email to issue assignee' do
28 32 Notify.should_receive(:new_issue_email).with(issue.id)
... ... @@ -31,16 +35,41 @@ describe NotificationService do
31 35 end
32 36  
33 37 describe :reassigned_issue do
34   - it 'should sent email to issue old assignee and new issue assignee' do
35   - Notify.should_receive(:reassigned_issue_email)
36   - notification.reassigned_issue(issue, issue.author)
  38 + it 'should email new assignee' do
  39 + should_email(issue.assignee_id)
  40 + should_email(@u_watcher.id)
  41 + should_not_email(@u_participating.id)
  42 + should_not_email(@u_disabled.id)
  43 +
  44 + notification.reassigned_issue(issue, @u_disabled)
  45 + end
  46 +
  47 + def should_email(user_id)
  48 + Notify.should_receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id)
  49 + end
  50 +
  51 + def should_not_email(user_id)
  52 + Notify.should_not_receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id)
37 53 end
38 54 end
39 55  
40 56 describe :close_issue do
41 57 it 'should sent email to issue assignee and issue author' do
42   - Notify.should_receive(:issue_status_changed_email)
43   - notification.close_issue(issue, issue.author)
  58 + should_email(issue.assignee_id)
  59 + should_email(issue.author_id)
  60 + should_email(@u_watcher.id)
  61 + should_not_email(@u_participating.id)
  62 + should_not_email(@u_disabled.id)
  63 +
  64 + notification.close_issue(issue, @u_disabled)
  65 + end
  66 +
  67 + def should_email(user_id)
  68 + Notify.should_receive(:issue_status_changed_email).with(user_id, issue.id, issue.assignee_id)
  69 + end
  70 +
  71 + def should_not_email(user_id)
  72 + Notify.should_not_receive(:issue_status_changed_email).with(user_id, issue.id, issue.assignee_id)
44 73 end
45 74 end
46 75 end
... ... @@ -48,16 +77,90 @@ describe NotificationService do
48 77 describe 'Merge Requests' do
49 78 let(:merge_request) { create :merge_request, assignee: create(:user) }
50 79  
  80 + before do
  81 + build_team(merge_request.project)
  82 + end
  83 +
51 84 describe :new_merge_request do
52   - it 'should send email to merge_request assignee' do
  85 + it do
  86 + should_email(merge_request.assignee_id)
  87 + should_email(@u_watcher.id)
  88 + should_not_email(@u_participating.id)
  89 + should_not_email(@u_disabled.id)
  90 + notification.new_merge_request(merge_request, @u_disabled)
  91 + end
  92 +
  93 + def should_email(user_id)
53 94 Notify.should_receive(:new_merge_request_email).with(merge_request.id)
54   - notification.new_merge_request(merge_request, merge_request.author)
55 95 end
56 96  
57   - it 'should not send email to merge_request assignee if he is current_user' do
  97 + def should_not_email(user_id)
58 98 Notify.should_not_receive(:new_merge_request_email).with(merge_request.id)
59   - notification.new_merge_request(merge_request, merge_request.assignee)
60 99 end
61 100 end
  101 +
  102 + describe :reassigned_merge_request do
  103 + it do
  104 + should_email(merge_request.assignee_id)
  105 + should_email(@u_watcher.id)
  106 + should_not_email(@u_participating.id)
  107 + should_not_email(@u_disabled.id)
  108 + notification.reassigned_merge_request(merge_request, merge_request.author)
  109 + end
  110 +
  111 + def should_email(user_id)
  112 + Notify.should_receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id)
  113 + end
  114 +
  115 + def should_not_email(user_id)
  116 + Notify.should_not_receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id)
  117 + end
  118 + end
  119 +
  120 + describe :closed_merge_request do
  121 + it do
  122 + should_email(merge_request.assignee_id)
  123 + should_email(@u_watcher.id)
  124 + should_not_email(@u_participating.id)
  125 + should_not_email(@u_disabled.id)
  126 + notification.close_mr(merge_request)
  127 + end
  128 +
  129 + def should_email(user_id)
  130 + Notify.should_receive(:closed_merge_request_email).with(user_id, merge_request.id)
  131 + end
  132 +
  133 + def should_not_email(user_id)
  134 + Notify.should_not_receive(:closed_merge_request_email).with(user_id, merge_request.id)
  135 + end
  136 + end
  137 +
  138 + describe :merged_merge_request do
  139 + it do
  140 + should_email(merge_request.assignee_id)
  141 + should_email(@u_watcher.id)
  142 + should_not_email(@u_participating.id)
  143 + should_not_email(@u_disabled.id)
  144 + notification.merge_mr(merge_request)
  145 + end
  146 +
  147 + def should_email(user_id)
  148 + Notify.should_receive(:merged_merge_request_email).with(user_id, merge_request.id)
  149 + end
  150 +
  151 + def should_not_email(user_id)
  152 + Notify.should_not_receive(:merged_merge_request_email).with(user_id, merge_request.id)
  153 + end
  154 + end
  155 + end
  156 +
  157 + def build_team(project)
  158 + @u_watcher = create(:user, notification_level: Notification::N_WATCH)
  159 + @u_participating = create(:user, notification_level: Notification::N_PARTICIPATING)
  160 + @u_disabled = create(:user, notification_level: Notification::N_DISABLED)
  161 +
  162 + project.team << [@u_watcher, :master]
  163 + project.team << [@u_participating, :master]
  164 + project.team << [@u_disabled, :master]
62 165 end
63 166 end
... ...