Commit 9e616459e068f2ba65f90016a09387a192fe4cfc
1 parent
11d52a15
Exists in
master
and in
4 other branches
add watchers to email recipients list. Add emails for close/merge MR
Showing
5 changed files
with
196 additions
and
27 deletions
Show diff stats
app/observers/merge_request_observer.rb
@@ -7,6 +7,12 @@ class MergeRequestObserver < BaseObserver | @@ -7,6 +7,12 @@ class MergeRequestObserver < BaseObserver | ||
7 | 7 | ||
8 | def after_close(merge_request, transition) | 8 | def after_close(merge_request, transition) |
9 | Note.create_status_change_note(merge_request, current_user, merge_request.state) | 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 | end | 16 | end |
11 | 17 | ||
12 | def after_reopen(merge_request, transition) | 18 | def after_reopen(merge_request, transition) |
app/services/notification_service.rb
@@ -17,7 +17,21 @@ class NotificationService | @@ -17,7 +17,21 @@ class NotificationService | ||
17 | end | 17 | end |
18 | end | 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 | # * issue author if his notification level is not Disabled | 36 | # * issue author if his notification level is not Disabled |
23 | # * issue assignee if his notification level is not Disabled | 37 | # * issue assignee if his notification level is not Disabled |
@@ -26,6 +40,9 @@ class NotificationService | @@ -26,6 +40,9 @@ class NotificationService | ||
26 | def close_issue(issue, current_user) | 40 | def close_issue(issue, current_user) |
27 | recipients = reject_muted_users([issue.author, issue.assignee]) | 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 | # Dont send email to me when I close an issue | 46 | # Dont send email to me when I close an issue |
30 | recipients.delete(current_user) | 47 | recipients.delete(current_user) |
31 | 48 | ||
@@ -43,30 +60,17 @@ class NotificationService | @@ -43,30 +60,17 @@ class NotificationService | ||
43 | reassign_email(issue, current_user, 'reassigned_issue_email') | 60 | reassign_email(issue, current_user, 'reassigned_issue_email') |
44 | end | 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 | # When create a merge request we should send next emails: | 64 | # When create a merge request we should send next emails: |
61 | # | 65 | # |
62 | # * mr assignee if his notification level is not Disabled | 66 | # * mr assignee if his notification level is not Disabled |
63 | # | 67 | # |
64 | def new_merge_request(merge_request, current_user) | 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 | end | 74 | end |
71 | end | 75 | end |
72 | 76 | ||
@@ -79,6 +83,36 @@ class NotificationService | @@ -79,6 +83,36 @@ class NotificationService | ||
79 | reassign_email(merge_request, current_user, 'reassigned_merge_request_email') | 83 | reassign_email(merge_request, current_user, 'reassigned_merge_request_email') |
80 | end | 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 | # Notify new user with email after creation | 116 | # Notify new user with email after creation |
83 | def new_user(user) | 117 | def new_user(user) |
84 | # Dont email omniauth created users | 118 | # Dont email omniauth created users |
@@ -119,6 +153,11 @@ class NotificationService | @@ -119,6 +153,11 @@ class NotificationService | ||
119 | 153 | ||
120 | protected | 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 | # Remove users with disabled notifications from array | 161 | # Remove users with disabled notifications from array |
123 | # Also remove duplications and nil recipients | 162 | # Also remove duplications and nil recipients |
124 | def reject_muted_users(users) | 163 | def reject_muted_users(users) |
@@ -130,6 +169,9 @@ class NotificationService | @@ -130,6 +169,9 @@ class NotificationService | ||
130 | def reassign_email(target, current_user, method) | 169 | def reassign_email(target, current_user, method) |
131 | recipients = User.where(id: [target.assignee_id, target.assignee_id_was]) | 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 | # reject users with disabled notifications | 175 | # reject users with disabled notifications |
134 | recipients = reject_muted_users(recipients) | 176 | recipients = reject_muted_users(recipients) |
135 | 177 |
@@ -0,0 +1,9 @@ | @@ -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 | + |
@@ -0,0 +1,9 @@ | @@ -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,6 +23,10 @@ describe NotificationService do | ||
23 | describe 'Issues' do | 23 | describe 'Issues' do |
24 | let(:issue) { create :issue, assignee: create(:user) } | 24 | let(:issue) { create :issue, assignee: create(:user) } |
25 | 25 | ||
26 | + before do | ||
27 | + build_team(issue.project) | ||
28 | + end | ||
29 | + | ||
26 | describe :new_issue do | 30 | describe :new_issue do |
27 | it 'should sent email to issue assignee' do | 31 | it 'should sent email to issue assignee' do |
28 | Notify.should_receive(:new_issue_email).with(issue.id) | 32 | Notify.should_receive(:new_issue_email).with(issue.id) |
@@ -31,16 +35,41 @@ describe NotificationService do | @@ -31,16 +35,41 @@ describe NotificationService do | ||
31 | end | 35 | end |
32 | 36 | ||
33 | describe :reassigned_issue do | 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 | end | 53 | end |
38 | end | 54 | end |
39 | 55 | ||
40 | describe :close_issue do | 56 | describe :close_issue do |
41 | it 'should sent email to issue assignee and issue author' do | 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 | end | 73 | end |
45 | end | 74 | end |
46 | end | 75 | end |
@@ -48,16 +77,90 @@ describe NotificationService do | @@ -48,16 +77,90 @@ describe NotificationService do | ||
48 | describe 'Merge Requests' do | 77 | describe 'Merge Requests' do |
49 | let(:merge_request) { create :merge_request, assignee: create(:user) } | 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 | describe :new_merge_request do | 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 | Notify.should_receive(:new_merge_request_email).with(merge_request.id) | 94 | Notify.should_receive(:new_merge_request_email).with(merge_request.id) |
54 | - notification.new_merge_request(merge_request, merge_request.author) | ||
55 | end | 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 | Notify.should_not_receive(:new_merge_request_email).with(merge_request.id) | 98 | Notify.should_not_receive(:new_merge_request_email).with(merge_request.id) |
59 | - notification.new_merge_request(merge_request, merge_request.assignee) | ||
60 | end | 99 | end |
61 | end | 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 | end | 165 | end |
63 | end | 166 | end |