Users who create/reply a topic are automatically added as watchers but are now able to unwatch the topic. git-svn-id: http://redmine.rubyforge.org/svn/trunk@1878 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/0.8.0-RC1
@@ -24,7 +24,7 @@ class MessagesController < ApplicationController | |||
verify :method => :post, :only => [ :reply, :destroy ], :redirect_to => { :action => :show } | |||
verify :xhr => true, :only => :quote | |||
helper :watchers | |||
helper :attachments | |||
include AttachmentsHelper | |||
@@ -33,11 +33,14 @@ class Message < ActiveRecord::Base | |||
{:id => o.parent_id, :anchor => "message-#{o.id}"})} | |||
acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]} | |||
acts_as_watchable | |||
attr_protected :locked, :sticky | |||
validates_presence_of :subject, :content | |||
validates_length_of :subject, :maximum => 255 | |||
after_create :add_author_as_watcher | |||
def validate_on_create | |||
# Can not reply to a locked topic | |||
errors.add_to_base 'Topic is locked' if root.locked? && self != root | |||
@@ -68,4 +71,10 @@ class Message < ActiveRecord::Base | |||
def project | |||
board.project | |||
end | |||
private | |||
def add_author_as_watcher | |||
Watcher.create(:watchable => self.root, :user => author) | |||
end | |||
end |
@@ -17,8 +17,9 @@ | |||
class MessageObserver < ActiveRecord::Observer | |||
def after_create(message) | |||
# send notification to the authors of the thread | |||
recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author && m.author.active?} | |||
recipients = [] | |||
# send notification to the topic watchers | |||
recipients += message.root.watcher_recipients | |||
# send notification to the board watchers | |||
recipients += message.board.watcher_recipients | |||
# send notification to project members who want to be notified |
@@ -2,6 +2,7 @@ | |||
link_to(h(@board.name), {:controller => 'boards', :action => 'show', :project_id => @project, :id => @board}) %> | |||
<div class="contextual"> | |||
<%= watcher_tag(@topic, User.current) %> | |||
<%= link_to_remote_if_authorized l(:button_quote), { :url => {:action => 'quote', :id => @topic} }, :class => 'icon icon-comment' %> | |||
<%= link_to_if_authorized l(:button_edit), {:action => 'edit', :id => @topic}, :class => 'icon icon-edit' %> | |||
<%= link_to_if_authorized l(:button_delete), {:action => 'destroy', :id => @topic}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del' %> |
@@ -0,0 +1,14 @@ | |||
class SetTopicAuthorsAsWatchers < ActiveRecord::Migration | |||
def self.up | |||
# Sets active users who created/replied a topic as watchers of the topic | |||
# so that the new watch functionality at topic level doesn't affect notifications behaviour | |||
Message.connection.execute("INSERT INTO watchers (watchable_type, watchable_id, user_id)" + | |||
" SELECT DISTINCT 'Message', COALESCE(messages.parent_id, messages.id), messages.author_id FROM messages, users" + | |||
" WHERE messages.author_id = users.id AND users.status = 1") | |||
end | |||
def self.down | |||
# Removes all message watchers | |||
Watcher.delete_all("watchable_type = 'Message'") | |||
end | |||
end |
@@ -3,4 +3,8 @@ watchers_001: | |||
watchable_type: Issue | |||
watchable_id: 2 | |||
user_id: 3 | |||
watchers_002: | |||
watchable_type: Message | |||
watchable_id: 1 | |||
user_id: 1 | |||
@@ -1,7 +1,7 @@ | |||
require File.dirname(__FILE__) + '/../test_helper' | |||
class MessageTest < Test::Unit::TestCase | |||
fixtures :projects, :boards, :messages | |||
fixtures :projects, :boards, :messages, :users, :watchers | |||
def setup | |||
@board = Board.find(1) | |||
@@ -20,6 +20,8 @@ class MessageTest < Test::Unit::TestCase | |||
# messages count incremented | |||
assert_equal messages_count+1, @board[:messages_count] | |||
assert_equal message, @board.last_message | |||
# author should be watching the message | |||
assert message.watched_by?(@user) | |||
end | |||
def test_reply | |||
@@ -28,7 +30,8 @@ class MessageTest < Test::Unit::TestCase | |||
@message = Message.find(1) | |||
replies_count = @message.replies_count | |||
reply = Message.new(:board => @board, :subject => 'Test reply', :content => 'Test reply content', :parent => @message, :author => @user) | |||
reply_author = User.find(2) | |||
reply = Message.new(:board => @board, :subject => 'Test reply', :content => 'Test reply content', :parent => @message, :author => reply_author) | |||
assert reply.save | |||
@board.reload | |||
# same topics count | |||
@@ -40,13 +43,18 @@ class MessageTest < Test::Unit::TestCase | |||
# replies count incremented | |||
assert_equal replies_count+1, @message[:replies_count] | |||
assert_equal reply, @message.last_reply | |||
# author should be watching the message | |||
assert @message.watched_by?(reply_author) | |||
end | |||
def test_destroy_topic | |||
message = Message.find(1) | |||
board = message.board | |||
topics_count, messages_count = board.topics_count, board.messages_count | |||
assert message.destroy | |||
assert_difference('Watcher.count', -1) do | |||
assert message.destroy | |||
end | |||
board.reload | |||
# Replies deleted | |||
@@ -54,6 +62,7 @@ class MessageTest < Test::Unit::TestCase | |||
# Checks counters | |||
assert_equal topics_count - 1, board.topics_count | |||
assert_equal messages_count - 3, board.messages_count | |||
# Watchers removed | |||
end | |||
def test_destroy_reply |