Merge pull request #136 from warpc/114-comment_notifications

Notifications and subscribtions about new comments in commit [Refs #114]
This commit is contained in:
Vladimir Sharshov 2012-02-01 11:12:24 -08:00
commit 8562b882da
26 changed files with 541 additions and 85 deletions

View File

@ -14,7 +14,7 @@ class CommentsController < ApplicationController
def create def create
@comment = @commentable.comments.build(params[:comment]) if @commentable.class == Issue @comment = @commentable.comments.build(params[:comment]) if @commentable.class == Issue
@comment = Comment.new(params[:comment].merge(:commentable_id => @commentable.id, :commentable_type => @commentable.class.name)) if @commentable.class == Grit::Commit @comment = Comment.new(params[:comment].merge(:commentable_id => @commentable.id, :commentable_type => @commentable.class.name, :project => @project)) if @commentable.class == Grit::Commit
@comment.user = current_user @comment.user = current_user
if @comment.save if @comment.save
flash[:notice] = I18n.t("flash.comment.saved") flash[:notice] = I18n.t("flash.comment.saved")
@ -75,7 +75,10 @@ class CommentsController < ApplicationController
def find_comment def find_comment
@comment = Comment.find(params[:id]) @comment = Comment.find(params[:id])
@comment.project = @project if @comment.commentable_type == 'Grit::Commit' if @comment.commentable_type == 'Grit::Commit'
@comment.project = @project
@comment.helper
end
end end
def find_project def find_project

View File

@ -0,0 +1,32 @@
# -*- encoding : utf-8 -*-
class CommitSubscribesController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource :project
before_filter :find_commit
def create
if Subscribe.subscribe_to_commit(@options)
flash[:notice] = I18n.t("flash.subscribe.commit.saved")
# TODO js
redirect_to commit_path(@project, @commit)
else
flash[:error] = I18n.t("flash.subscribe.saved_error")
redirect_to commit_path(@project, @commit)
end
end
def destroy
Subscribe.unsubscribe_from_commit(@options)
flash[:notice] = t("flash.subscribe.commit.destroyed")
redirect_to commit_path(@project, @commit)
end
protected
def find_commit
@commit = @project.git_repository.commit(params[:commit_id])
@options = {:project_id => @project.id, :subscribeable_id => @commit.id, :subscribeable_type => @commit.class.name, :user_id => current_user.id}
end
end

View File

@ -13,10 +13,10 @@ class Settings::NotifiersController < ApplicationController
def update def update
if @notifier.update_attributes(params[:settings_notifier]) if @notifier.update_attributes(params[:settings_notifier])
flash[:notice] = I18n.t("flash.settings.saved") flash[:notice] = I18n.t("flash.settings.saved")
redirect_to [@user, @notifier] redirect_to user_settings_notifier_path(@user)
else else
flash[:notice] = I18n.t("flash.settings.save_error") flash[:notice] = I18n.t("flash.settings.save_error")
redirect_to [@user, @notifier] redirect_to user_settings_notifier_path(@user)
end end
end end

View File

@ -13,15 +13,7 @@ class UserMailer < ActionMailer::Base
def new_comment_notification(comment, user) def new_comment_notification(comment, user)
@user = user @user = user
@comment = comment @comment = comment
mail(:to => user.email, :subject => I18n.t("notifications.subjects.new_comment_notification")) do |format| mail(:to => user.email, :subject => I18n.t("notifications.subjects.new_#{comment.commentable.class == Grit::Commit ? 'commit_' : ''}comment_notification")) do |format|
format.html
end
end
def new_comment_reply_notification(comment, user)
@user = user
@comment = comment
mail(:to => user.email, :subject => I18n.t("notifications.subjects.new_comment_reply_notification")) do |format|
format.html format.html
end end
end end

View File

@ -6,26 +6,35 @@ class Comment < ActiveRecord::Base
validates :body, :user_id, :commentable_id, :commentable_type, :presence => true validates :body, :user_id, :commentable_id, :commentable_type, :presence => true
# FIXME after_create :invoke_helper, :if => "commentable_type == 'Grit::Commit'"
after_create :subscribe_on_reply, :unless => "commentable_type == 'Grit::Commit'" after_create :subscribe_users
after_create :deliver_new_comment_notification, :unless => "commentable_type == 'Grit::Commit'" after_create {|comment| Subscribe.new_comment_notification(comment)}
def helper
class_eval "def commentable; project.git_repository.commit('#{commentable_id}'); end" if commentable_type == 'Grit::Commit'
end
def own_comment?(user)
user_id == user.id
end
protected protected
def deliver_new_comment_notification def invoke_helper
subscribes = self.commentable.subscribes self.helper
subscribes.each do |subscribe|
if self.user_id != subscribe.user_id && User.find(subscribe.user).notifier.new_comment_reply && User.find(subscribe.user).notifier.can_notify
if self.commentable.comments.exists?(:user_id => subscribe.user.id)
UserMailer.delay.new_comment_reply_notification(self, subscribe.user)
else
UserMailer.delay.new_comment_notification(self, subscribe.user)
end
end
end
end end
def subscribe_on_reply def subscribe_users
self.commentable.subscribes.create(:user_id => self.user_id) if !self.commentable.subscribes.exists?(:user_id => self.user_id) if self.commentable.class == Issue
self.commentable.subscribes.create(:user => self.user) if !self.commentable.subscribes.exists?(:user_id => self.user.id)
elsif self.commentable.class == Grit::Commit
recipients = self.project.relations.by_role('admin').where(:object_type => 'User').map &:object # admins
recipients << self.user << User.where(:email => self.commentable.committer.email).first # commentor and committer
recipients << self.project.owner if self.project.owner_type == 'User' # project owner
recipients.compact.uniq.each do |user|
options = {:project_id => self.project.id, :subscribeable_id => self.commentable.id, :subscribeable_type => self.commentable.class.name, :user_id => user.id}
Subscribe.subscribe_to_commit(options) if Subscribe.subscribed_to_commit?(self.project, user, self.commentable)
end
end
end end
end end

View File

@ -6,13 +6,9 @@ class Issue < ActiveRecord::Base
belongs_to :user belongs_to :user
has_many :comments, :as => :commentable, has_many :comments, :as => :commentable,
:finder_sql => proc { "comments.commentable_id = '#{self.id}' " + :finder_sql => proc { "comments.commentable_id = '#{self.id}' AND comments.commentable_type = '#{self.class.name}'"}
" AND comments.commentable_type = '#{self.class.name}'"} has_many :subscribes, :as => :subscribeable,
#'SELECT comments.* FROM comments ' + :finder_sql => proc { "subscribes.subscribeable_id = '#{self.id}' AND subscribes.subscribeable_type = '#{self.class.name}'"}
#'WHERE comments.commentable_id = \'#{self.id}\' ' +
#' AND comments.commentable_type = \'#{self.class.name}\' ' +
#'ORDER BY comments.created_at'
has_many :subscribes, :as => :subscribeable
validates :title, :body, :project_id, :presence => true validates :title, :body, :project_id, :presence => true

View File

@ -141,10 +141,14 @@ class Project < ActiveRecord::Base
class << self class << self
def commit_comments(commit, project) def commit_comments(commit, project)
comments = Comment.where(:commentable_id => commit.id, :commentable_type => 'Grit::Commit').order(:created_at) comments = Comment.where(:commentable_id => commit.id, :commentable_type => 'Grit::Commit').order(:created_at)
comments.each {|x| x.project = project} comments.each {|x| x.project = project; x.helper}
end end
end end
def owner?(user)
owner == user
end
protected protected
def build_path(dir) def build_path(dir)
@ -169,4 +173,5 @@ class Project < ActiveRecord::Base
self.srpm = nil; save # clear srpm self.srpm = nil; save # clear srpm
end end
end end
end end

View File

@ -2,4 +2,66 @@
class Subscribe < ActiveRecord::Base class Subscribe < ActiveRecord::Base
belongs_to :subscribeable, :polymorphic => true belongs_to :subscribeable, :polymorphic => true
belongs_to :user belongs_to :user
belongs_to :project
scope :finder_hack, order('') # FIXME .subscribes - error; .subscribes.finder_hack - success Oo
def subscribed?
status
end
def self.comment_subscribes(comment)
Subscribe.where(:subscribeable_id => comment.commentable.id, :subscribeable_type => comment.commentable.class.name, :project_id => comment.project)
end
def self.new_comment_notification(comment)
commentable_class = comment.commentable.class
Subscribe.new_comment_issue_notification(comment) if commentable_class == Issue
Subscribe.new_comment_commit_notification(comment) if commentable_class == Grit::Commit
end
def self.new_comment_issue_notification(comment)
comment.commentable.subscribes.finder_hack.each do |subscribe|
next if comment.own_comment?(subscribe.user) || !subscribe.user.notifier.can_notify
UserMailer.delay.new_comment_notification(comment, subscribe.user) if subscribe.user.notifier.new_comment_reply
end
end
def self.new_comment_commit_notification(comment)
subscribes = Subscribe.comment_subscribes(comment).where(:status => true)
subscribes.each do |subscribe|
next if comment.own_comment?(subscribe.user) || !subscribe.user.notifier.can_notify
UserMailer.delay.new_comment_notification(comment, subscribe.user)
end
end
def self.subscribed_to_commit?(project, user, commit)
subscribe = user.subscribes.where(:subscribeable_id => commit.id, :subscribeable_type => commit.class.name, :project_id => project.id).first
return subscribe.subscribed? if subscribe # return status if already subscribe present
# return status by settings
(project.owner?(user) && user.notifier.new_comment_commit_repo_owner) or
(user.commentor?(commit) && user.notifier.new_comment_commit_commentor) or
(user.committer?(commit) && user.notifier.new_comment_commit_owner)
end
def self.subscribe_to_commit(options)
Subscribe.set_subscribe_to_commit(options, true)
end
def self.unsubscribe_from_commit(options)
Subscribe.set_subscribe_to_commit(options, false)
end
private
def self.set_subscribe_to_commit(options, status)
if subscribe = Subscribe.where(options).first
subscribe.update_attribute(:status, status)
else
Subscribe.create(options.merge(:status => status))
end
end
end end

View File

@ -24,6 +24,9 @@ class User < ActiveRecord::Base
has_many :projects, :through => :targets, :source => :target, :source_type => 'Project', :autosave => true has_many :projects, :through => :targets, :source => :target, :source_type => 'Project', :autosave => true
has_many :platforms, :through => :targets, :source => :target, :source_type => 'Platform', :autosave => true has_many :platforms, :through => :targets, :source => :target, :source_type => 'Platform', :autosave => true
has_many :repositories, :through => :targets, :source => :target, :source_type => 'Repository', :autosave => true has_many :repositories, :through => :targets, :source => :target, :source_type => 'Repository', :autosave => true
has_many :subscribes, :foreign_key => :user_id, :dependent => :destroy
has_many :comments, :dependent => :destroy
include Modules::Models::PersonalRepository include Modules::Models::PersonalRepository
@ -84,6 +87,14 @@ class User < ActiveRecord::Base
result result
end end
def commentor?(commentable)
comments.exists?(:commentable_type => commentable.class.name, :commentable_id => commentable.id)
end
def committer?(commit)
email.downcase == commit.committer.email.downcase
end
private private
def create_settings_notifier def create_settings_notifier

View File

@ -30,3 +30,11 @@
- content_for :sidebar, render(:partial => 'git/shared/sidebar') - content_for :sidebar, render(:partial => 'git/shared/sidebar')
= render :partial => "comments/list", :locals => {:list => Project.commit_comments(@commit, @project), :project => @project, :commentable => @commit} = render :partial => "comments/list", :locals => {:list => Project.commit_comments(@commit, @project), :project => @project, :commentable => @commit}
%p
%b
= t('layout.issues.subscribe')
\:
- if Subscribe.subscribed_to_commit?(@project, current_user, @commit)
= link_to t('layout.commits.unsubscribe_btn'), unsubscribe_commit_path(@project, @commit), :method => :delete
- else
= link_to t('layout.commits.subscribe_btn'), subscribe_commit_path(@project, @commit), :method => :post

View File

@ -30,7 +30,6 @@
= t("activerecord.attributes.project.repository") = t("activerecord.attributes.project.repository")
\: \:
= git_repo_url @project.git_repo_name = git_repo_url @project.git_repo_name
.wat-cf .wat-cf
= link_to image_tag("web-app-theme/icons/application_edit.png", :alt => t("layout.edit")) + " " + t("layout.edit"), edit_project_path(@project), :class => "button" if can? :update, @project = link_to image_tag("web-app-theme/icons/application_edit.png", :alt => t("layout.edit")) + " " + t("layout.edit"), edit_project_path(@project), :class => "button" if can? :update, @project
= link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_path(@project), :method => "delete", :class => "button", :confirm => t("layout.projects.confirm_delete") if can? :destroy, @project = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_path(@project), :method => "delete", :class => "button", :confirm => t("layout.projects.confirm_delete") if can? :destroy, @project

View File

@ -18,6 +18,18 @@
= f.label :issue_assign, t('activerecord.attributes.settings.notifier.issue_assign'), :class => :label = f.label :issue_assign, t('activerecord.attributes.settings.notifier.issue_assign'), :class => :label
= f.check_box :issue_assign, :class => 'notify_cbx' = f.check_box :issue_assign, :class => 'notify_cbx'
.group
= f.label :new_comment_commit_owner, t('activerecord.attributes.settings.notifier.new_comment_commit_owner'), :class => :label
= f.check_box :new_comment_commit_owner, :class => 'notify_cbx'
.group
= f.label :new_comment_commit_repo_owner, t('activerecord.attributes.settings.notifier.new_comment_commit_repo_owner'), :class => :label
= f.check_box :new_comment_commit_repo_owner, :class => 'notify_cbx'
.group
= f.label :new_comment_commit_commentor, t('activerecord.attributes.settings.notifier.new_comment_commit_commentor'), :class => :label
= f.check_box :new_comment_commit_commentor, :class => 'notify_cbx'
.group.navform.wat-cf .group.navform.wat-cf
%button.button{:type => "submit"} %button.button{:type => "submit"}
= image_tag("web-app-theme/icons/tick.png", :alt => t("layout.save")) = image_tag("web-app-theme/icons/tick.png", :alt => t("layout.save"))

View File

@ -1,7 +1,12 @@
%p== Hello, #{@user.name}. %p== Hello, #{@user.name}.
- if @comment.commentable.class == Issue
%p To the issue #{ link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable] } added a comment. - link = link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable]
- object = 'issue'
- elsif @comment.commentable.class == Grit::Commit
- link = link_to @comment.commentable.message, commit_path(@comment.project, @comment.commentable_id)
- object = 'commit'
%p #{ link_to @comment.user.uname, user_path(@comment.user)} added new comment to #{object} #{link}.
%p "#{ @comment.body }" %p "#{ @comment.body }"

View File

@ -1,7 +1,12 @@
%p== Здравствуйте, #{@user.name}. %p== Здравствуйте, #{@user.name}.
- if @comment.commentable.class == Issue
%p К задаче #{ link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable] } был добавлен новый комментарий. - link = link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable]
- object = 'задаче'
- elsif @comment.commentable.class == Grit::Commit
- link = link_to @comment.commentable.message, commit_path(@comment.project, @comment.commentable_id)
- object = 'коммиту'
%p #{ link_to @comment.user.uname, user_path(@comment.user)} добавил комментарий к #{object} #{link}.
%p "#{ @comment.body }" %p "#{ @comment.body }"

View File

@ -1,9 +0,0 @@
%p== Здравствуйте, #{@user.name}.
%p На Ваш комментарий в задаче #{ link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable] } был дан ответ.
%p "#{ @comment.body }"
%p== Команда поддержки «ROSA Build System»

View File

@ -137,6 +137,10 @@ en:
subscribe_btn: Subscribe subscribe_btn: Subscribe
unsubscribe_btn: Unsubscribe unsubscribe_btn: Unsubscribe
commits:
subscribe_btn: Subscribe to commit
unsubscribe_btn: Unsubscribe from commit
comments: comments:
confirm_delete: Are you sure to delete the comment? confirm_delete: Are you sure to delete the comment?
new_header: New comment new_header: New comment
@ -377,7 +381,11 @@ en:
subscribe: subscribe:
saved: Subscription on notifications for this task is created saved: Subscription on notifications for this task is created
saved_error: Subscription create error
destroyed: Subscription on notifications for this task is cleaned destroyed: Subscription on notifications for this task is cleaned
commit:
saved: Subscription on notifications for this commit is created
destroyed: Subscription on notifications for this commit is cleaned
exception_message: Access violation to this page! exception_message: Access violation to this page!
@ -704,3 +712,4 @@ en:
new_issue_notification: New task added to project new_issue_notification: New task added to project
new_user_notification: Registered on project «%{ project_name }» new_user_notification: Registered on project «%{ project_name }»
issue_assign_notification: New task assigned issue_assign_notification: New task assigned
new_commit_comment_notification: New comment to commit

View File

@ -377,7 +377,11 @@ ru:
subscribe: subscribe:
saved: Вы подписаны на оповещения для этой задачи saved: Вы подписаны на оповещения для этой задачи
saved_error: При создании подписки произошла ошибка
destroyed: Подписка на оповещения для этой задачи убрана destroyed: Подписка на оповещения для этой задачи убрана
commit:
saved: Вы подписаны на оповещения для этого коммита
destroyed: Подписка на оповещения для этого коммита убрана
exception_message: У Вас нет доступа к этой странице! exception_message: У Вас нет доступа к этой странице!
@ -512,6 +516,9 @@ ru:
new_comment_reply: Оповещать о новом ответе на мой комментарий new_comment_reply: Оповещать о новом ответе на мой комментарий
new_issue: Оповещать о новых задачах в моих проектах new_issue: Оповещать о новых задачах в моих проектах
issue_assign: Оповещать, когда на меня выставляют задачу issue_assign: Оповещать, когда на меня выставляют задачу
new_comment_commit_owner: Оповещать о комментариях к моему коммиту
new_comment_commit_repo_owner: Оповещать о комментариях к коммитам в моем репозитории
new_comment_commit_commentor: Оповещать о комментариях к коммиту после моего
auto_build_list: auto_build_list:
project_id: Проект project_id: Проект
@ -691,15 +698,18 @@ ru:
status: Статус status: Статус
version: Версия version: Версия
build_list: Сборочный лист build_list: Сборочный лист
download: download:
name: Название name: Название
version: Версия version: Версия
distro: Дистрибутив distro: Дистрибутив
platform: Архитектура platform: Архитектура
counter: Закачки counter: Закачки
notifications: notifications:
subjects: subjects:
new_comment_notification: Новый комментарий к Вашей задаче new_comment_notification: Новый комментарий к Вашей задаче
new_issue_notification: Новая задача добавлена к проекту new_issue_notification: Новая задача добавлена к проекту
new_user_notification: Регистрация на проекте «%{ project_name }» new_user_notification: Регистрация на проекте «%{ project_name }»
issue_assign_notification: Вам назначили задачу issue_assign_notification: Вам назначили задачу
new_commit_comment_notification: Новый комментарий к коммиту

View File

@ -158,6 +158,9 @@ Rosa::Application.routes.draw do
match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :update, :as => :project_commit_comment, :via => :put match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :update, :as => :project_commit_comment, :via => :put
match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :destroy, :via => :delete match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :destroy, :via => :delete
match '/projects/:project_id/git/commit/:commit_id/comments(.:format)', :controller => "comments", :action => :create, :as => :project_commit_comments, :via => :post match '/projects/:project_id/git/commit/:commit_id/comments(.:format)', :controller => "comments", :action => :create, :as => :project_commit_comments, :via => :post
# Commits subscribe
match '/projects/:project_id/git/commit/:commit_id/subscribe', :controller => "commit_subscribes", :action => :create, :defaults => { :format => :html }, :as => :subscribe_commit, :via => :post
match '/projects/:project_id/git/commit/:commit_id/unsubscribe', :controller => "commit_subscribes", :action => :destroy, :defaults => { :format => :html }, :as => :unsubscribe_commit, :via => :delete
# Blobs # Blobs
match '/projects/:project_id/git/blob/:treeish/*path', :controller => "git/blobs", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blob match '/projects/:project_id/git/blob/:treeish/*path', :controller => "git/blobs", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blob
match '/projects/:project_id/git/commit/blob/:commit_hash/*path', :controller => "git/blobs", :action => :show, :project_name => /[0-9a-zA-Z_.\-]*/, :as => :blob_commit match '/projects/:project_id/git/commit/blob/:commit_hash/*path', :controller => "git/blobs", :action => :show, :project_name => /[0-9a-zA-Z_.\-]*/, :as => :blob_commit

View File

@ -0,0 +1,13 @@
class AddSettingsToSettingsNotifiers < ActiveRecord::Migration
def self.up
add_column :settings_notifiers, :new_comment_commit_owner, :boolean, :default => true
add_column :settings_notifiers, :new_comment_commit_repo_owner, :boolean, :default => true
add_column :settings_notifiers, :new_comment_commit_commentor, :boolean, :default => true
end
def self.down
remove_column :settings_notifiers, :new_comment_commit_owner
remove_column :settings_notifiers, :new_comment_commit_repo_owner
remove_column :settings_notifiers, :new_comment_commit_commentor
end
end

View File

@ -0,0 +1,9 @@
class AddStatusToSubscribe < ActiveRecord::Migration
def self.up
add_column :subscribes, :status, :boolean, :default => true
end
def self.down
remove_column :subscribes, :status
end
end

View File

@ -0,0 +1,9 @@
class AddProjectToSubscribe < ActiveRecord::Migration
def self.up
add_column :subscribes, :project_id, :integer
end
def self.down
remove_column :subscribes, :project_id
end
end

View File

@ -0,0 +1,9 @@
class ChangeSubscribeableToString < ActiveRecord::Migration
def self.up
change_column :subscribes, :subscribeable_id, :string
end
def self.down
change_column :subscribes, :subscribeable_id, :integer
end
end

View File

@ -301,14 +301,19 @@ ActiveRecord::Schema.define(:version => 20120131124517) do
t.boolean "issue_assign", :default => true t.boolean "issue_assign", :default => true
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.boolean "new_comment_commit_owner", :default => true
t.boolean "new_comment_commit_repo_owner", :default => true
t.boolean "new_comment_commit_commentor", :default => true
end end
create_table "subscribes", :force => true do |t| create_table "subscribes", :force => true do |t|
t.integer "subscribeable_id" t.string "subscribeable_id"
t.string "subscribeable_type" t.string "subscribeable_type"
t.integer "user_id" t.integer "user_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.integer "project_id"
t.boolean "status", :default => true
end end
create_table "users", :force => true do |t| create_table "users", :force => true do |t|

View File

@ -78,8 +78,9 @@ describe CommentsController do
%x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ? %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ?
@commit = @project.git_repository.commits.first @commit = @project.git_repository.commits.first
@comment = Factory(:comment) @comment = Factory(:commit_comment, :project => @project,
@comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) :commentable_type => @commit.class.name, :commentable_id => @commit.id)
@comment.helper
@create_params = {:comment => {:body => 'I am a comment!'}, :project_id => @project.id, :commit_id => @commit.id} @create_params = {:comment => {:body => 'I am a comment!'}, :project_id => @project.id, :commit_id => @commit.id}
@update_params = {:comment => {:body => 'updated'}, :project_id => @project.id, :commit_id => @commit.id} @update_params = {:comment => {:body => 'updated'}, :project_id => @project.id, :commit_id => @commit.id}

View File

@ -4,3 +4,11 @@ Factory.define(:comment) do |p|
p.association :user, :factory => :user p.association :user, :factory => :user
p.association :commentable, :factory => :issue p.association :commentable, :factory => :issue
end end
Factory.define(:commit_comment, :class => 'Comment') do |p|
p.body { Factory.next(:string) }
p.association :user, :factory => :user
p.commentable_type 'Grit::Commit'
p.commentable_id 'asdf'
p.project nil
end

View File

@ -5,7 +5,7 @@ require "cancan/matchers"
def set_comments_data_for_commit def set_comments_data_for_commit
@ability = Ability.new(@user) @ability = Ability.new(@user)
@project = Factory(:project) @project = Factory(:project, :owner => @user)
%x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ? %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ?
@commit = @project.git_repository.commits.first @commit = @project.git_repository.commits.first
@ -33,10 +33,6 @@ describe Comment do
@ability.should be_able_to(:create, Comment.new(@create_params)) @ability.should be_able_to(:create, Comment.new(@create_params))
end end
pending "sends an e-mail" do
ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == true
end
it 'should update comment' do it 'should update comment' do
@ability.should be_able_to(:update, @comment) @ability.should be_able_to(:update, @comment)
end end
@ -60,8 +56,7 @@ describe Comment do
@stranger = Factory(:user) @stranger = Factory(:user)
set_comments_data_for_commit set_comments_data_for_commit
#~ #@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin')
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin')
end end
it 'should create comment' do it 'should create comment' do
@ -79,21 +74,93 @@ describe Comment do
it 'should not destroy comment' do it 'should not destroy comment' do
@ability.should_not be_able_to(:destroy, @comment) @ability.should_not be_able_to(:destroy, @comment)
end end
context 'for default settings' do
it 'should send an e-mail' do
ActionMailer::Base.deliveries = []
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@user.email).should == true
end
end
context 'for disabled notify setting new_comment_commit_repo_owner' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :new_comment_commit_repo_owner, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
context 'for disabled notify setting new_comment_commit_owner' do
it 'should send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :new_comment_commit_owner, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@user.email).should == true
end
end
context 'for disabled notify setting new_comment_commit_commentor' do
it 'should send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :new_comment_commit_commentor, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@user.email).should == true
end
end
context 'for disabled all notify setting expect global' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :new_comment_commit_repo_owner, false
@user.notifier.update_attribute :new_comment_commit_owner, false
@user.notifier.update_attribute :new_comment_commit_commentor, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
context 'for unsubscribe commit' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
Subscribe.unsubscribe_from_commit(:project_id => @project.id, :subscribeable_id => @commit.id, :subscribeable_type => @commit.class.name, :user_id => @user.id)
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0 # cache project.commit_comments_subscribes ...
end
end
context 'for disabled global notify setting' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :can_notify, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
end end
context 'for project owner user' do context 'for project owner user' do
before(:each) do before(:each) do
@user = Factory(:user) @user = Factory(:user)
@stranger = Factory(:user) @stranger = Factory(:user)
set_comments_data_for_commit set_comments_data_for_commit
@project.update_attribute(:owner, @user) @project.update_attribute(:owner, @user)
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin')
end end
it 'should create comment' do it 'should create comment' do
@ability.should be_able_to(:create, Comment.new(@create_params)) @ability.should be_able_to(:create, Comment.create(@create_params))
end end
it 'should update comment' do it 'should update comment' do
@ -107,18 +174,110 @@ describe Comment do
it 'should not destroy comment' do it 'should not destroy comment' do
@ability.should_not be_able_to(:destroy, @comment) @ability.should_not be_able_to(:destroy, @comment)
end end
context 'for default enabled settings' do
it 'should send an e-mail by default settings' do
ActionMailer::Base.deliveries = []
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@project.owner.email).should == true
end
end
context 'for disabled notify setting new_comment_commit_repo_owner' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :new_comment_commit_repo_owner, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
context 'for disabled notify setting new_comment_commit_owner' do
it 'should send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :new_comment_commit_owner, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@user.email).should == true
end
end
context 'for disabled notify setting new_comment_commit_commentor' do
it 'should send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :new_comment_commit_commentor, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@user.email).should == true
end
end
context 'for disabled all notify setting expect global' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :new_comment_commit_repo_owner, false
@user.notifier.update_attribute :new_comment_commit_owner, false
@user.notifier.update_attribute :new_comment_commit_commentor, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
context 'for unsubscribe project' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
Subscribe.unsubscribe_from_commit(:project_id => @project.id, :subscribeable_id => @commit.id, :subscribeable_type => @commit.class.name, :user_id => @user.id)
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
context 'for disabled global notify setting' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
@user.notifier.update_attribute :can_notify, false
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
context 'for own commit' do
it 'should send a one e-mail' do
ActionMailer::Base.deliveries = []
@project.owner.update_attribute :email, 'code@tpope.net'
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@project.owner.email).should == true
end
end
end end
context 'for simple user' do context 'for simple user' do
before(:each) do before(:each) do
@user = Factory(:user) @user = Factory(:user)
@simple = Factory(:user)
@stranger = Factory(:user) @stranger = Factory(:user)
set_comments_data_for_commit set_comments_data_for_commit
@create_params = {:commentable_type => @commit.class.name, :commentable_id => @commit.id,
:user => @simple, :project => @project}
@comment = Factory(:comment, :user => @simple)
@comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id)
@ability = Ability.new(@simple)
end end
it 'should create comment' do it 'should create comment' do
@ability.should be_able_to(:create, Comment.new(@create_params)) @ability.should be_able_to(:create, Comment.create(@create_params))
end end
it 'should update comment' do it 'should update comment' do
@ -132,5 +291,96 @@ describe Comment do
it 'should not destroy comment' do it 'should not destroy comment' do
@ability.should_not be_able_to(:destroy, @comment) @ability.should_not be_able_to(:destroy, @comment)
end end
context 'for default enabled settings' do
it 'should not send an e-mail' do
ActionMailer::Base.deliveries = []
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == false
end
it 'should send an e-mail for comments after his comment' do
comment = Comment.create(:user => @simple, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries = []
comment = Comment.create(:user => @user, :body => 'owner comment', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@simple.email).should == true
end
it 'should send an e-mail when subscribed to project' do
ActionMailer::Base.deliveries = []
@project.owner.notifier.update_attribute :can_notify, false
@stranger.notifier.update_attribute :new_comment_commit_repo_owner, false
@stranger.notifier.update_attribute :new_comment_commit_owner, false
Subscribe.subscribe_to_commit(:project_id => @project.id, :subscribeable_id => @commit.id, :subscribeable_type => @commit.class.name, :user_id => @stranger.id)
comment = Comment.create(:user => @project.owner, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == true
end
it 'should not send an e-mail for own comment' do
ActionMailer::Base.deliveries = []
Subscribe.subscribe_to_commit(:project_id => @project.id, :subscribeable_id => @commit.id, :subscribeable_type => @commit.class.name, :user_id => @stranger.id)
comment = Comment.create(:user => @owner, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
context 'for committer' do
it 'should send an e-mail' do
ActionMailer::Base.deliveries = []
@stranger.update_attribute :email, 'code@tpope.net'
comment = Comment.create(:user => @user, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == true
end
it 'should send a one e-mail when subscribed to commit' do
ActionMailer::Base.deliveries = []
Subscribe.subscribe_to_commit(:project_id => @project.id, :subscribeable_id => @commit.id, :subscribeable_type => @commit.class.name, :user_id => @stranger.id)
@stranger.update_attribute :email, 'code@tpope.net'
comment = Comment.create(:user => @user, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == true
end
it 'should not send an e-mail for own comment' do
ActionMailer::Base.deliveries = []
@stranger.update_attribute :email, 'code@tpope.net'
comment = Comment.create(:user => @stranger, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 1
ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == false
end
it 'should not send an e-mail if global notify off' do
ActionMailer::Base.deliveries = []
@project.owner.notifier.update_attribute :can_notify, false
@stranger.update_attribute :email, 'code@tpope.net'
@stranger.notifier.update_attribute :can_notify, false
comment = Comment.create(:user => @user, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
it 'should not send an e-mail if notify for my commits off' do
ActionMailer::Base.deliveries = []
@stranger.notifier.update_attribute :new_comment_commit_owner, false
@stranger.update_attribute :email, 'code@tpope.net'
comment = Comment.create(:user => @user, :body => 'hello!', :project => @project,
:commentable_type => @commit.class.name, :commentable_id => @commit.id)
ActionMailer::Base.deliveries.count.should == 0
end
end
end end
end end