From c88ba8e255d1a358ed5121fa645b165b28a4e25f Mon Sep 17 00:00:00 2001 From: Holger Just Date: Thu, 12 Oct 2023 19:08:16 +0200 Subject: [PATCH 1/2] Fix watcher handling on unsaved objects --- .../lib/acts_as_watchable.rb | 20 +++++++--- test/unit/watcher_test.rb | 37 +++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb index 907535ec7a..2bd13cedcf 100644 --- a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb +++ b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb @@ -44,17 +44,25 @@ def addable_watcher_users # 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 diff --git a/test/unit/watcher_test.rb b/test/unit/watcher_test.rb index 1e95be2f62..a9a7534a6c 100644 --- a/test/unit/watcher_test.rb +++ b/test/unit/watcher_test.rb @@ -124,6 +124,43 @@ def test_addable_watcher_users 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)) + refute 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)) + refute issue.persisted? + + issue.add_watcher(@user) + assert_equal [@user], issue.watcher_users + + issue.remove_watcher(@user) + refute 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)} -- 2.39.2