Project

General

Profile

Patch #44681 » 0001-Extract-the-auto-watch-logic-shared-by-Issue-and-Jou.patch

Marius BĂLTEANU, 2026-10-26 23:14

View differences:

app/models/concerns/issue/auto_watchable.rb
1
# frozen_string_literal: true
2

  
3
# Redmine - project management software
4
# Copyright (C) 2006-  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19

  
20
module Issue::AutoWatchable
21
  extend ActiveSupport::Concern
22

  
23
  # Adds user as a watcher if the given auto watch option is enabled
24
  # in their preferences and they are allowed to watch the issue
25
  def auto_watch(user, option)
26
    return unless user.is_a?(User) && user.active? && user.pref.auto_watch_on?(option)
27
    return unless user.allowed_to?(:add_issue_watchers, project)
28
    return if !valid_watcher?(user) || watched_by?(user)
29

  
30
    add_watcher(user)
31
  end
32

  
33
  private
34

  
35
  # Called after_create_commit
36
  def add_auto_watcher
37
    auto_watch(author, 'issue_created')
38
    auto_watch(assigned_to, 'issue_assigned_to_me')
39
  end
40
end
app/models/issue.rb
62 62
  acts_as_mentionable :attributes => ['description']
63 63
  acts_as_webhookable
64 64
  include Issue::Webhookable
65
  include Issue::AutoWatchable
65 66
  DONE_RATIO_OPTIONS = %w(issue_field issue_status)
......
2109 2110
    end
2110 2111
  end
2111
  def add_auto_watcher
2112
    if author.is_a?(User) &&
2113
        author.pref.auto_watch_on?('issue_created') &&
2114
        auto_watcher?(author)
2115
      self.set_watcher(author, true)
2116
    end
2117

  
2118
    if assigned_to.is_a?(User) &&
2119
        assigned_to.pref.auto_watch_on?('issue_assigned_to_me') &&
2120
        auto_watcher?(assigned_to)
2121
      self.set_watcher(assigned_to, true)
2122
    end
2123
  end
2124

  
2125
  def auto_watcher?(user)
2126
    user.active? &&
2127
      user.allowed_to?(:add_issue_watchers, project) &&
2128
      valid_watcher?(user) &&
2129
      !watched_by?(user)
2130
  end
2131

  
2132 2112
  def send_notification
2133 2113
    if notify? && Setting.notified_events.include?('issue_added')
2134 2114
      Mailer.deliver_issue_add(self)
app/models/journal.rb
354 354
  end
355 355
  def add_watcher
356
    if user.is_a?(User) &&
357
       user.pref.auto_watch_on?('issue_contributed_to') &&
358
       valid_watcher?(user)
359
      journalized.set_watcher(user, true)
360
    end
361

  
362
    assignee = journalized.assigned_to
363
    if assignee.is_a?(User) &&
364
       assignee.pref.auto_watch_on?('issue_assigned_to_me') &&
365
       valid_watcher?(assignee)
366
      journalized.set_watcher(assignee, true)
367
    end
368
  end
369

  
370
  def valid_watcher?(user)
371
    user.active? &&
372
      user.allowed_to?(:add_issue_watchers, journalized.project) &&
373
      journalized.valid_watcher?(user) &&
374
      !journalized.watched_by?(user)
356
    journalized.auto_watch(user, 'issue_contributed_to')
357
    journalized.auto_watch(journalized.assigned_to, 'issue_assigned_to_me')
375 358
  end
376 359
  def send_notification
test/unit/issue_auto_watchable_test.rb
1
# frozen_string_literal: true
2

  
3
# Redmine - project management software
4
# Copyright (C) 2006-  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19

  
20
require_relative '../test_helper'
21

  
22
class IssueAutoWatchableTest < ActiveSupport::TestCase
23
  def setup
24
    User.current = nil
25
  end
26

  
27
  def test_auto_watch_should_add_watcher_if_option_is_enabled
28
    issue = Issue.find(1)
29
    user = User.find(2)
30
    user.pref.auto_watch_on = ['issue_created']
31
    user.pref.save
32

  
33
    assert_difference 'Watcher.count', 1 do
34
      issue.auto_watch(user, 'issue_created')
35
    end
36
    assert issue.watched_by?(user)
37
  end
38

  
39
  def test_auto_watch_should_not_add_watcher_if_option_is_disabled
40
    issue = Issue.find(1)
41
    user = User.find(2)
42
    user.pref.auto_watch_on = []
43
    user.pref.save
44

  
45
    assert_no_difference 'Watcher.count' do
46
      issue.auto_watch(user, 'issue_created')
47
    end
48
  end
49

  
50
  def test_auto_watch_should_not_add_watcher_without_add_issue_watchers_permission
51
    Role.find(1).remove_permission!(:add_issue_watchers)
52
    issue = Issue.find(1)
53
    user = User.find(2)
54
    user.pref.auto_watch_on = ['issue_created']
55
    user.pref.save
56

  
57
    assert_no_difference 'Watcher.count' do
58
      issue.auto_watch(user, 'issue_created')
59
    end
60
  end
61

  
62
  def test_auto_watch_should_not_add_watcher_if_user_cannot_view_issue
63
    Role.find(1).remove_permission!(:view_issues)
64
    issue = Issue.find(1)
65
    user = User.find(2)
66
    user.pref.auto_watch_on = ['issue_created']
67
    user.pref.save
68

  
69
    assert_no_difference 'Watcher.count' do
70
      issue.auto_watch(user, 'issue_created')
71
    end
72
  end
73

  
74
  def test_auto_watch_should_not_add_locked_user
75
    issue = Issue.find(1)
76
    user = User.find(2)
77
    user.pref.auto_watch_on = ['issue_created']
78
    user.pref.save
79
    user.lock!
80

  
81
    assert_no_difference 'Watcher.count' do
82
      issue.auto_watch(user, 'issue_created')
83
    end
84
  end
85

  
86
  def test_auto_watch_should_not_add_watcher_twice
87
    issue = Issue.find(1)
88
    user = User.find(2)
89
    user.pref.auto_watch_on = ['issue_created']
90
    user.pref.save
91
    issue.add_watcher(user)
92

  
93
    assert_no_difference 'Watcher.count' do
94
      issue.auto_watch(user, 'issue_created')
95
    end
96
  end
97

  
98
  def test_auto_watch_should_not_add_watcher_if_a_group_of_the_user_is_watching
99
    issue = Issue.find(1)
100
    user = User.find(2)
101
    user.pref.auto_watch_on = ['issue_created']
102
    user.pref.save
103
    group = Group.find(10)
104
    group.users << user
105
    issue.add_watcher(group)
106

  
107
    assert_no_difference 'Watcher.count' do
108
      issue.auto_watch(user, 'issue_created')
109
    end
110
  end
111

  
112
  def test_auto_watch_should_ignore_groups_and_nil
113
    issue = Issue.find(1)
114

  
115
    assert_no_difference 'Watcher.count' do
116
      issue.auto_watch(Group.find(10), 'issue_assigned_to_me')
117
      issue.auto_watch(nil, 'issue_assigned_to_me')
118
    end
119
  end
120
end
    (1-1/1)