Browse Source

Fix watcher handling on unsaved objects (#39186).

Patch by Holger Just.


git-svn-id: https://svn.redmine.org/redmine/trunk@22349 e93f8b46-1217-0410-a6f0-8f06a7374b81
tags/5.1.0
Go MAEDA 8 months ago
parent
commit
fd132a8e82
2 changed files with 53 additions and 6 deletions
  1. 16
    6
      lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb
  2. 37
    0
      test/unit/watcher_test.rb

+ 16
- 6
lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb View File

@@ -11,6 +11,7 @@ module Redmine
module ClassMethods
def acts_as_watchable(options = {})
return if self.included_modules.include?(Redmine::Acts::Watchable::InstanceMethods)

class_eval do
has_many :watchers, :as => :watchable, :dependent => :delete_all
has_many :watcher_users, :through => :watchers, :source => :user, :validate => false
@@ -44,17 +45,26 @@ module Redmine

# Adds user as a watcher
def add_watcher(user)
# Rails does not reset the has_many :through association
watcher_users.reset
self.watchers << Watcher.new(:user => user)
if persisted?
# Rails does not reset the has_many :through association
watcher_users.reset
self.watchers << Watcher.new(:user => user)
else
self.watcher_users << user
end
end

# Removes user from the watchers list
def remove_watcher(user)
return nil unless user && (user.is_a?(User) || user.is_a?(Group))
# Rails does not reset the has_many :through association
watcher_users.reset
watchers.where(:user_id => user.id).delete_all

if persisted?
# Rails does not reset the has_many :through association
watcher_users.reset
watchers.where(:user_id => user.id).delete_all
else
watcher_users.delete(user)
end
end

# Adds/removes watcher

+ 37
- 0
test/unit/watcher_test.rb View File

@@ -126,6 +126,43 @@ class WatcherTest < ActiveSupport::TestCase
end
end

def test_add_watcher_with_unsaved_object
issue = Issue.new(project: Project.find(1), tracker_id: 1, subject: "test", author: User.find(2))
assert_not issue.persisted?

issue.add_watcher(@user)
assert issue.watched_by?(@user)

assert_equal [@user.id], issue.watcher_user_ids
assert_equal [@user], issue.watcher_users

assert_equal [nil], issue.watcher_ids
assert_equal 1, issue.watchers.size

issue.save!
assert 1, Watcher.where(watchable: issue).count
end

def test_remove_watcher_with_unsaved_object
issue = Issue.new(project: Project.find(1), tracker_id: 1, subject: "test", author: User.find(2))
assert_not issue.persisted?

issue.add_watcher(@user)
assert_equal [@user], issue.watcher_users

issue.remove_watcher(@user)
assert_not issue.watched_by?(@user)

assert_equal [], issue.watcher_user_ids
assert_equal [], issue.watcher_users

assert_equal [], issue.watcher_ids
assert_equal [], issue.watchers

issue.save!
assert 0, Watcher.where(watchable: issue).count
end

def test_addable_watcher_users_should_not_include_user_that_cannot_view_the_object
issue = Issue.new(:project => Project.find(1), :is_private => true)
assert_nil issue.addable_watcher_users.detect {|user| user.is_a?(User) && !issue.visible?(user)}

Loading…
Cancel
Save