]> source.dussan.org Git - redmine.git/commitdiff
Ability to add watchers to forum threads (#3390).
authorGo MAEDA <maeda@farend.jp>
Mon, 15 Mar 2021 04:55:56 +0000 (04:55 +0000)
committerGo MAEDA <maeda@farend.jp>
Mon, 15 Mar 2021 04:55:56 +0000 (04:55 +0000)
Patch by Yuichi HARADA.

git-svn-id: http://svn.redmine.org/redmine/trunk@20787 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/views/messages/show.html.erb
app/views/watchers/_new.html.erb
app/views/watchers/_watchers.html.erb
config/locales/en.yml
lib/redmine.rb
test/fixtures/roles.yml
test/functional/messages_controller_test.rb
test/functional/watchers_controller_test.rb

index b8abf03216afa2d4adc7240bd67fddcbdb0f257a..6c902d087cf629a9257dc0a225df18f79a1583d1 100644 (file)
 <% end %>
 
 <% html_title @topic.subject %>
+<% content_for :sidebar do %>
+  <% if User.current.allowed_to?(:add_message_watchers, @project) ||
+    (@topic.watchers.present? && User.current.allowed_to?(:view_message_watchers, @project)) %>
+    <div id="watchers">
+      <%= render :partial => 'watchers/watchers', :locals => {:watched => @topic} %>
+    </div>
+  <% end %>
+<% end %>
index f313d04d36dd20f18c4591cdd2d3c9a824dc213a..bc08a3322bf3ad736eda97af672e0d6cfa96977b 100644 (file)
@@ -1,4 +1,12 @@
-<h3 class="title"><%= l(:permission_add_issue_watchers) %></h3>
+<%
+title =
+  if watchables.present?
+    l(:"permission_add_#{watchables.first.class.name.underscore}_watchers")
+  else
+    l(:permission_add_issue_watchers)
+  end
+-%>
+<h3 class="title"><%= title %></h3>
 
 <%= form_tag(watchables.present? ? watchers_path : watchers_append_path,
              :remote => true,
index 2489662821621cf8e30c90bce95f921662ca715c..b53e09d500d3012cb0ae6d423405c5b05028a8ee 100644 (file)
@@ -1,12 +1,13 @@
-<% if User.current.allowed_to?(:add_issue_watchers, watched.project) %>
+<% watched_klass_name = watched.class.name.underscore -%>
+<% if User.current.allowed_to?(:"add_#{watched_klass_name}_watchers", watched.project) %>
 <div class="contextual">
 <%= link_to l(:button_add),
-      new_watchers_path(:object_type => watched.class.name.underscore, :object_id => watched),
+      new_watchers_path(:object_type => watched_klass_name, :object_id => watched),
       :remote => true,
       :method => 'get' %>
 </div>
 <% end %>
 
-<h3><%= l(:label_issue_watchers) %> (<%= watched.watcher_users.size %>)</h3>
+<h3><%= l(:"label_#{watched_klass_name}_watchers") %> (<%= watched.watcher_users.size %>)</h3>
 
 <%= watchers_list(watched) %>
index 8009fe5f3a6b0228bae6b6d9f307abd850fdb09f..5cbb33ffc09e5423f92bf2cadf988c1b69d25f30 100644 (file)
@@ -569,6 +569,9 @@ en:
   permission_edit_own_messages: Edit own messages
   permission_delete_messages: Delete messages
   permission_delete_own_messages: Delete own messages
+  permission_view_message_watchers: View message watchers list
+  permission_add_message_watchers: Add message watchers
+  permission_delete_message_watchers: Delete message watchers
   permission_export_wiki_pages: Export wiki pages
   permission_manage_subtasks: Manage subtasks
   permission_manage_related_issues: Manage related issues
@@ -952,6 +955,7 @@ en:
   label_incoming_emails: Incoming emails
   label_generate_key: Generate a key
   label_issue_watchers: Watchers
+  label_message_watchers: Watchers
   label_example: Example
   label_display: Display
   label_sort: Sort
index 551ea4005123a208c41ba9f53695262587596691..70b4942b84f2e1132b4a07a5e9c71deabe0f2ed8 100644 (file)
@@ -188,6 +188,9 @@ Redmine::AccessControl.map do |map|
     map.permission :edit_own_messages, {:messages => :edit, :attachments => :upload}, :require => :loggedin
     map.permission :delete_messages, {:messages => :destroy}, :require => :member
     map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
+    map.permission :view_message_watchers, {}, :read => true
+    map.permission :add_message_watchers, {:watchers => [:new, :create, :autocomplete_for_user]}
+    map.permission :delete_message_watchers, {:watchers => :destroy}
     map.permission :manage_boards, {:projects => :settings, :boards => [:new, :create, :edit, :update, :destroy]}, :require => :member
   end
 
index 650511e2ddc2a217f99a9ec384a8efa85b537186..61c324b1ec46a40d12fc6c76c074979ad4d48cd9 100644 (file)
@@ -58,6 +58,9 @@ roles_001:
     - :add_messages
     - :edit_messages
     - :delete_messages
+    - :view_message_watchers
+    - :add_message_watchers
+    - :delete_message_watchers
     - :manage_boards
     - :view_files
     - :manage_files
@@ -113,6 +116,7 @@ roles_002:
     - :add_messages
     - :edit_own_messages
     - :delete_own_messages
+    - :view_message_watchers
     - :manage_boards
     - :view_files
     - :manage_files
@@ -156,6 +160,7 @@ roles_003:
     - :delete_wiki_pages
     - :view_messages
     - :add_messages
+    - :view_message_watchers
     - :manage_boards
     - :view_files
     - :manage_files
index 44b880f9bfc2312ed69759624f08cb75d0df3e79..b42c891a5e2741135b3f63e3fdff9d5c0ee841c2 100644 (file)
@@ -20,7 +20,8 @@
 require File.expand_path('../../test_helper', __FILE__)
 
 class MessagesControllerTest < Redmine::ControllerTest
-  fixtures :projects, :users, :email_addresses, :user_preferences, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
+  fixtures :projects, :users, :email_addresses, :user_preferences, :members, :member_roles, :roles, :boards, :messages, :enabled_modules,
+           :watchers
 
   def setup
     User.current = nil
@@ -88,6 +89,31 @@ class MessagesControllerTest < Redmine::ControllerTest
     assert_response 404
   end
 
+  def test_show_should_display_watchers
+    @request.session[:user_id] = 2
+    message = Message.find(1)
+    message.add_watcher User.find(2)
+    message.add_watcher Group.find(10)
+    [['1', true], ['0', false]].each do |(gravatar_enabled, is_display_gravatar)|
+      with_settings :gravatar_enabled => gravatar_enabled do
+        get(:show, :params => {:board_id => 1, :id => 1})
+      end
+
+      assert_select 'div#watchers ul' do
+        assert_select 'li.user-2' do
+          assert_select 'img.gravatar[title=?]', 'John Smith', is_display_gravatar
+          assert_select 'a[href="/users/2"]'
+          assert_select 'a[class*=delete]'
+        end
+        assert_select "li.user-10" do
+          assert_select 'img.gravatar[title=?]', 'A Team', is_display_gravatar
+          assert_select 'a[href="/users/10"]', false
+          assert_select 'a[class*=delete]'
+        end
+      end
+    end
+  end
+
   def test_get_new
     @request.session[:user_id] = 2
     get(:new, :params => {:board_id => 1})
index 4e93ce606299ce908a8db2c513e18689f274bb83..3690a77bf3a3bf806a8cabb6f23d009764d0716f 100644 (file)
@@ -21,7 +21,8 @@ require File.expand_path('../../test_helper', __FILE__)
 
 class WatchersControllerTest < Redmine::ControllerTest
   fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
-           :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers
+           :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers,
+           :boards, :messages
 
   def setup
     User.current = nil
@@ -155,6 +156,13 @@ class WatchersControllerTest < Redmine::ControllerTest
     assert_match /ajax-modal/, response.body
   end
 
+  def test_new_for_message
+    @request.session[:user_id] = 2
+    get :new, :params => {:object_type => 'message', :object_id => '1'}, :xhr => true
+    assert_response :success
+    assert_match /ajax-modal/, response.body
+  end
+
   def test_new_with_multiple_objects
     @request.session[:user_id] = 2
     get :new, :params => {:object_type => 'issue', :object_id => ['1', '2']}, :xhr => true
@@ -216,6 +224,20 @@ class WatchersControllerTest < Redmine::ControllerTest
     assert Issue.find(2).watched_by?(User.find(4))
   end
 
+  def test_create_for_message
+    @request.session[:user_id] = 2
+    assert_difference('Watcher.count') do
+      post :create, :params => {
+        :object_type => 'message', :object_id => '1',
+        :watcher => {:user_id => '4'}
+      }, :xhr => true
+      assert_response :success
+      assert_match /watchers/, response.body
+      assert_match /ajax-modal/, response.body
+    end
+    assert Message.find(1).watched_by?(User.find(4))
+  end
+
   def test_create_with_mutiple_users
     @request.session[:user_id] = 2
     assert_difference('Watcher.count', 3) do
@@ -233,6 +255,23 @@ class WatchersControllerTest < Redmine::ControllerTest
     assert issue.watched_by?(Group.find(10))
   end
 
+  def test_create_for_message_with_mutiple_users
+    @request.session[:user_id] = 2
+    assert_difference('Watcher.count', 3) do
+      post :create, :params => {
+        :object_type => 'message', :object_id => '1',
+        :watcher => {:user_ids => ['4', '7', '10']}
+      }, :xhr => true
+      assert_response :success
+      assert_match /watchers/, response.body
+      assert_match /ajax-modal/, response.body
+    end
+    message = Message.find(1)
+    assert message.watched_by?(User.find(4))
+    assert message.watched_by?(User.find(7))
+    assert message.watched_by?(Group.find(10))
+  end
+
   def test_create_with_mutiple_objects
     @request.session[:user_id] = 2
     assert_difference('Watcher.count', 6) do
@@ -409,6 +448,22 @@ class WatchersControllerTest < Redmine::ControllerTest
     assert !Issue.find(2).watched_by?(User.find(3))
   end
 
+  def test_destroy_for_meessage
+    @request.session[:user_id] = 2
+    message = Message.find(1)
+    user = User.find(1)
+    assert message.watched_by?(user)
+    assert_difference('Watcher.count', -1) do
+      delete :destroy, :params => {
+        :object_type => 'message', :object_id => '1', :user_id => '1'
+      }, :xhr => true
+      assert_response :success
+      assert_match /watchers/, response.body
+    end
+    message.reload
+    assert !message.watched_by?(user)
+  end
+
   def test_destroy_locked_user
     user = User.find(3)
     user.lock!