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 | 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 | ... | ... |
... | ... | @@ -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 @@ |
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 | ... | ... |