Commit 54fb0f858949ea3fab68861fe74d05a40cd45cfe

Authored by Dmitriy Zaporozhets
2 parents f09e1599 839aa735

Merge branch 'notification_refactoring'

app/controllers/admin/users_controller.rb
... ... @@ -27,7 +27,6 @@ class Admin::UsersController < ApplicationController
27 27  
28 28 respond_to do |format|
29 29 if @admin_user.save
30   - Notify.new_user_email(@admin_user, params[:user][:password]).deliver
31 30 format.html { redirect_to [:admin, @admin_user], notice: 'User was successfully created.' }
32 31 format.json { render json: @admin_user, status: :created, location: @admin_user }
33 32 else
... ...
app/controllers/application_controller.rb
1 1 class ApplicationController < ActionController::Base
2 2 before_filter :authenticate_user!
  3 + before_filter :set_current_user_for_mailer
3 4 protect_from_forgery
4 5 helper_method :abilities, :can?
5 6  
... ... @@ -19,6 +20,10 @@ class ApplicationController &lt; ActionController::Base
19 20 end
20 21 end
21 22  
  23 + def set_current_user_for_mailer
  24 + MailerObserver.current_user = current_user
  25 + end
  26 +
22 27 def abilities
23 28 @abilities ||= Six.new
24 29 end
... ...
app/controllers/issues_controller.rb
... ... @@ -67,10 +67,7 @@ class IssuesController &lt; ApplicationController
67 67 def create
68 68 @issue = @project.issues.new(params[:issue])
69 69 @issue.author = current_user
70   -
71   - if @issue.save && @issue.assignee != current_user
72   - Notify.new_issue_email(@issue).deliver
73   - end
  70 + @issue.save
74 71  
75 72 respond_with(@issue)
76 73 end
... ...
app/controllers/notes_controller.rb
... ... @@ -12,10 +12,8 @@ class NotesController &lt; ApplicationController
12 12 def create
13 13 @note = @project.notes.new(params[:note])
14 14 @note.author = current_user
15   -
16   - if @note.save
17   - notify if params[:notify] == '1'
18   - end
  15 + @note.notify = true if params[:notify] == '1'
  16 + @note.save
19 17  
20 18 respond_to do |format|
21 19 format.html {redirect_to :back}
... ... @@ -35,22 +33,4 @@ class NotesController &lt; ApplicationController
35 33 end
36 34 end
37 35  
38   - protected
39   -
40   - def notify
41   - @project.users.reject { |u| u.id == current_user.id } .each do |u|
42   - case @note.noteable_type
43   - when "Commit" then
44   - Notify.note_commit_email(u, @note).deliver
45   - when "Issue" then
46   - Notify.note_issue_email(u, @note).deliver
47   - when "MergeRequest"
48   - true # someone should write email notification
49   - when "Snippet"
50   - true
51   - else
52   - Notify.note_wall_email(u, @note).deliver
53   - end
54   - end
55   - end
56 36 end
... ...
app/mailers/notify.rb
... ... @@ -30,6 +30,14 @@ class Notify &lt; ActionMailer::Base
30 30 @commit = @project.repo.commits(note.noteable_id).first
31 31 mail(:to => @user.email, :subject => "gitlab | #{@note.project.name} ")
32 32 end
  33 +
  34 + def note_merge_request_email(user, note)
  35 + @user = user
  36 + @note = note
  37 + @project = note.project
  38 + @merge_request = note.noteable
  39 + mail(:to => @user.email, :subject => "gitlab | #{@note.project.name} ")
  40 + end
33 41  
34 42 def note_issue_email(user, note)
35 43 @user = user
... ... @@ -38,4 +46,27 @@ class Notify &lt; ActionMailer::Base
38 46 @issue = note.noteable
39 47 mail(:to => @user.email, :subject => "gitlab | #{@note.project.name} ")
40 48 end
  49 +
  50 + def new_merge_request_email(merge_request)
  51 + @user = merge_request.assignee
  52 + @merge_request = merge_request
  53 + @project = merge_request.project
  54 + mail(:to => @user.email, :subject => "gitlab | #{@merge_request.title} ")
  55 + end
  56 +
  57 + def changed_merge_request_email(user, merge_request)
  58 + @user = user
  59 + @assignee_was ||= User.find(merge_request.assignee_id_was)
  60 + @merge_request = merge_request
  61 + @project = merge_request.project
  62 + mail(:to => @user.email, :subject => "gitlab | #{@merge_request.title} ")
  63 + end
  64 +
  65 + def changed_issue_email(user, issue)
  66 + @user = user
  67 + @assignee_was ||= User.find(issue.assignee_id_was)
  68 + @issue = issue
  69 + @project = issue.project
  70 + mail(:to => @user.email, :subject => "gitlab | #{@issue.title} ")
  71 + end
41 72 end
... ...
app/models/issue.rb
... ... @@ -59,5 +59,6 @@ end
59 59 # closed :boolean default(FALSE), not null
60 60 # position :integer default(0)
61 61 # critical :boolean default(FALSE), not null
  62 +# branch_name :string(255)
62 63 #
63 64  
... ...
app/models/mailer_observer.rb 0 → 100644
... ... @@ -0,0 +1,75 @@
  1 +class MailerObserver < ActiveRecord::Observer
  2 + observe :issue, :user, :note, :merge_request
  3 + cattr_accessor :current_user
  4 +
  5 + def after_create(model)
  6 + new_issue(model) if model.kind_of?(Issue)
  7 + new_user(model) if model.kind_of?(User)
  8 + new_note(model) if model.kind_of?(Note)
  9 + new_merge_request(model) if model.kind_of?(MergeRequest)
  10 + end
  11 +
  12 + def after_update(model)
  13 + changed_merge_request(model) if model.kind_of?(MergeRequest)
  14 + changed_issue(model) if model.kind_of?(Issue)
  15 + end
  16 +
  17 + protected
  18 +
  19 + def new_issue(issue)
  20 + if issue.assignee != current_user
  21 + Notify.new_issue_email(issue).deliver
  22 + end
  23 + end
  24 +
  25 + def new_user(user)
  26 + Notify.new_user_email(user, user.password).deliver
  27 + end
  28 +
  29 + def new_note(note)
  30 + return unless note.notify
  31 + note.project.users.reject { |u| u.id == current_user.id } .each do |u|
  32 + case note.noteable_type
  33 + when "Commit" then
  34 + Notify.note_commit_email(u, note).deliver
  35 + when "Issue" then
  36 + Notify.note_issue_email(u, note).deliver
  37 + when "MergeRequest" then
  38 + Notify.note_merge_request_email(u, note).deliver
  39 + when "Snippet"
  40 + true
  41 + else
  42 + Notify.note_wall_email(u, note).deliver
  43 + end
  44 + end
  45 + end
  46 +
  47 + def new_merge_request(merge_request)
  48 + if merge_request.assignee != current_user
  49 + Notify.new_merge_request_email(merge_request).deliver
  50 + end
  51 + end
  52 +
  53 + def changed_merge_request(merge_request)
  54 + if merge_request.assignee_id_changed?
  55 + recipients_ids = merge_request.assignee_id_was, merge_request.assignee_id
  56 + recipients_ids.delete current_user.id
  57 +
  58 + User.find(recipients_ids).each do |user|
  59 + Notify.changed_merge_request_email(user, merge_request).deliver
  60 + end
  61 + end
  62 + end
  63 +
  64 + def changed_issue(issue)
  65 + if issue.assignee_id_changed?
  66 + recipients_ids = issue.assignee_id_was, issue.assignee_id
  67 + recipients_ids.delete current_user.id
  68 +
  69 + User.find(recipients_ids).each do |user|
  70 + Notify.changed_issue_email(user, issue).deliver
  71 + end
  72 + end
  73 +
  74 + end
  75 +end
... ...
app/models/merge_request.rb
... ... @@ -44,3 +44,19 @@ class MergeRequest &lt; ActiveRecord::Base
44 44 project.commit(source_branch)
45 45 end
46 46 end
  47 +# == Schema Information
  48 +#
  49 +# Table name: merge_requests
  50 +#
  51 +# id :integer not null, primary key
  52 +# target_branch :string(255) not null
  53 +# source_branch :string(255) not null
  54 +# project_id :integer not null
  55 +# author_id :integer
  56 +# assignee_id :integer
  57 +# title :string(255)
  58 +# closed :boolean default(FALSE), not null
  59 +# created_at :datetime
  60 +# updated_at :datetime
  61 +#
  62 +
... ...
app/models/note.rb
... ... @@ -13,6 +13,7 @@ class Note &lt; ActiveRecord::Base
13 13 :prefix => true
14 14  
15 15 attr_protected :author, :author_id
  16 + attr_accessor :notify
16 17  
17 18 validates_presence_of :project
18 19  
... ... @@ -35,6 +36,10 @@ class Note &lt; ActiveRecord::Base
35 36 scope :inc_author, includes(:author)
36 37  
37 38 mount_uploader :attachment, AttachmentUploader
  39 +
  40 + def notify
  41 + @notify ||= false
  42 + end
38 43 end
39 44 # == Schema Information
40 45 #
... ...
app/models/project.rb
... ... @@ -247,14 +247,15 @@ end
247 247 #
248 248 # Table name: projects
249 249 #
250   -# id :integer not null, primary key
251   -# name :string(255)
252   -# path :string(255)
253   -# description :text
254   -# created_at :datetime
255   -# updated_at :datetime
256   -# private_flag :boolean default(TRUE), not null
257   -# code :string(255)
258   -# owner_id :integer
  250 +# id :integer not null, primary key
  251 +# name :string(255)
  252 +# path :string(255)
  253 +# description :text
  254 +# created_at :datetime
  255 +# updated_at :datetime
  256 +# private_flag :boolean default(TRUE), not null
  257 +# code :string(255)
  258 +# owner_id :integer
  259 +# default_branch :string(255) default("master"), not null
259 260 #
260 261  
... ...
app/models/users_project.rb
... ... @@ -23,13 +23,12 @@ end
23 23 #
24 24 # Table name: users_projects
25 25 #
26   -# id :integer not null, primary key
27   -# user_id :integer not null
28   -# project_id :integer not null
29   -# read :boolean default(FALSE)
30   -# write :boolean default(FALSE)
31   -# admin :boolean default(FALSE)
32   -# created_at :datetime
33   -# updated_at :datetime
  26 +# id :integer not null, primary key
  27 +# user_id :integer not null
  28 +# project_id :integer not null
  29 +# created_at :datetime
  30 +# updated_at :datetime
  31 +# repo_access :integer default(0), not null
  32 +# project_access :integer default(0), not null
34 33 #
35 34  
... ...
app/views/notify/changed_issue_email.html.haml 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
  2 + %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
  3 + %tr
  4 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  5 + %td{:align => "left", :style => "padding: 20px 0 0;"}
  6 + %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
  7 + Reassigned Issue
  8 + = link_to truncate(@issue.title, :length => 16), project_issue_url(@project, @issue)
  9 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  10 + %tr
  11 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  12 + %td{:style => "padding: 15px 0 15px;", :valign => "top"}
  13 + %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
  14 + Assignee changed from #{@assignee_was.name} to #{@issue.assignee.name}
  15 + %td
  16 +
... ...
app/views/notify/changed_merge_request_email.html.haml 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
  2 + %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
  3 + %tr
  4 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  5 + %td{:align => "left", :style => "padding: 20px 0 0;"}
  6 + %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
  7 + Reassigned Merge Request
  8 + = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@project, @merge_request)
  9 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  10 + %tr
  11 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  12 + %td{:style => "padding: 15px 0 15px;", :valign => "top"}
  13 + %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
  14 + Assignee changed from #{@assignee_was.name} to #{@merge_request.assignee.name}
  15 + %td
  16 +
... ...
app/views/notify/new_issue_email.html.haml
... ... @@ -4,7 +4,7 @@
4 4 %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
5 5 %td{:align => "left", :style => "padding: 20px 0 0;"}
6 6 %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
7   - Hi #{@user.name}! New Issue was created and assigned to you.
  7 + New Issue was created and assigned to you.
8 8 %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
9 9 %tr
10 10 %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
... ...
app/views/notify/new_merge_request_email.html.haml 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
  2 + %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
  3 + %tr
  4 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  5 + %td{:align => "left", :style => "padding: 20px 0 0;"}
  6 + %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
  7 + New Merge Request
  8 + = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@project, @merge_request)
  9 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  10 + %tr
  11 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  12 + %td{:style => "padding: 15px 0 15px;", :valign => "top"}
  13 + %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
  14 + Branches: #{@merge_request.source_branch} &rarr; #{@merge_request.target_branch}
  15 +
  16 + %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
  17 + Asignee: #{@merge_request.author.name} &rarr; #{@merge_request.assignee.name}
  18 +
  19 + %td
  20 +
... ...
app/views/notify/note_merge_request_email.html.haml 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
  2 + %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
  3 + %tr
  4 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  5 + %td{:align => "left", :style => "padding: 20px 0 0;"}
  6 + %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
  7 + New comment for Merge Request
  8 + = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@project, @merge_request, :anchor => "note_#{@note.id}")
  9 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  10 + %tr
  11 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  12 + %td{:style => "padding: 15px 0 15px;", :valign => "top"}
  13 + %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
  14 + %a{:href => "#", :style => "color: #0eb6ce; text-decoration: none;"} #{@note.author.name}
  15 + left next message:
  16 + %br
  17 + %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
  18 + %tr
  19 + %td{:valign => "top"}
  20 + %cite{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
  21 + = @note.note
  22 + %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
  23 +
... ...
config/application.rb
... ... @@ -23,7 +23,7 @@ module Gitlab
23 23 # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
24 24  
25 25 # Activate observers that should always be running.
26   - # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
  26 + config.active_record.observers = :mailer_observer
27 27  
28 28 # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
29 29 # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
... ...
spec/models/issue_spec.rb
... ... @@ -39,5 +39,6 @@ end
39 39 # closed :boolean default(FALSE), not null
40 40 # position :integer default(0)
41 41 # critical :boolean default(FALSE), not null
  42 +# branch_name :string(255)
42 43 #
43 44  
... ...
spec/models/merge_request_spec.rb
... ... @@ -26,3 +26,19 @@ describe MergeRequest do
26 26 :assignee => Factory(:user),
27 27 :project => Factory.create(:project)).should be_valid }
28 28 end
  29 +# == Schema Information
  30 +#
  31 +# Table name: merge_requests
  32 +#
  33 +# id :integer not null, primary key
  34 +# target_branch :string(255) not null
  35 +# source_branch :string(255) not null
  36 +# project_id :integer not null
  37 +# author_id :integer
  38 +# assignee_id :integer
  39 +# title :string(255)
  40 +# closed :boolean default(FALSE), not null
  41 +# created_at :datetime
  42 +# updated_at :datetime
  43 +#
  44 +
... ...
spec/models/project_spec.rb
... ... @@ -168,14 +168,15 @@ end
168 168 #
169 169 # Table name: projects
170 170 #
171   -# id :integer not null, primary key
172   -# name :string(255)
173   -# path :string(255)
174   -# description :text
175   -# created_at :datetime
176   -# updated_at :datetime
177   -# private_flag :boolean default(TRUE), not null
178   -# code :string(255)
179   -# owner_id :integer
  171 +# id :integer not null, primary key
  172 +# name :string(255)
  173 +# path :string(255)
  174 +# description :text
  175 +# created_at :datetime
  176 +# updated_at :datetime
  177 +# private_flag :boolean default(TRUE), not null
  178 +# code :string(255)
  179 +# owner_id :integer
  180 +# default_branch :string(255) default("master"), not null
180 181 #
181 182  
... ...
spec/models/users_project_spec.rb
... ... @@ -20,13 +20,12 @@ end
20 20 #
21 21 # Table name: users_projects
22 22 #
23   -# id :integer not null, primary key
24   -# user_id :integer not null
25   -# project_id :integer not null
26   -# read :boolean default(FALSE)
27   -# write :boolean default(FALSE)
28   -# admin :boolean default(FALSE)
29   -# created_at :datetime
30   -# updated_at :datetime
  23 +# id :integer not null, primary key
  24 +# user_id :integer not null
  25 +# project_id :integer not null
  26 +# created_at :datetime
  27 +# updated_at :datetime
  28 +# repo_access :integer default(0), not null
  29 +# project_access :integer default(0), not null
31 30 #
32 31  
... ...
spec/requests/issues_spec.rb
... ... @@ -147,13 +147,12 @@ describe &quot;Issues&quot; do
147 147 click_button "Save"
148 148 end
149 149  
150   - it "should send valid email to user with email & password" do
  150 + it "should send valid email to user" do
151 151 click_button "Save"
152 152 issue = Issue.last
153 153 email = ActionMailer::Base.deliveries.last
154 154 email.subject.should have_content("New Issue was created")
155 155 email.body.should have_content(issue.title)
156   - email.body.should have_content(issue.assignee.name)
157 156 end
158 157  
159 158 end
... ...