]> source.dussan.org Git - redmine.git/commitdiff
Filter issues by notes (#5893).
authorGo MAEDA <maeda@farend.jp>
Wed, 21 Apr 2021 07:01:02 +0000 (07:01 +0000)
committerGo MAEDA <maeda@farend.jp>
Wed, 21 Apr 2021 07:01:02 +0000 (07:01 +0000)
Patch by Yuichi HARADA.

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

app/models/issue_query.rb
test/unit/query_test.rb

index a2e821f9f94923680146b509a03f291a822e93c0..1ed7056d2fb70698fe9545eb1057fe157a6816a4 100644 (file)
@@ -176,6 +176,7 @@ class IssueQuery < Query
     ) if project
     add_available_filter "subject", :type => :text
     add_available_filter "description", :type => :text
+    add_available_filter "notes", :type => :text
     add_available_filter "created_on", :type => :date_past
     add_available_filter "updated_on", :type => :date_past
     add_available_filter "closed_on", :type => :date_past
@@ -447,6 +448,14 @@ class IssueQuery < Query
     raise StatementInvalid.new(e.message)
   end
 
+  def sql_for_notes_field(field, operator, value)
+    subquery = "SELECT 1 FROM #{Journal.table_name}" +
+      " WHERE #{Journal.table_name}.journalized_type='Issue' AND #{Journal.table_name}.journalized_id=#{Issue.table_name}.id" +
+      " AND (#{sql_for_field field, operator.sub(/^!/, ''), value, Journal.table_name, 'notes'})" +
+      " AND (#{Journal.visible_notes_condition(User.current, :skip_pre_condition => true)})"
+    "#{/^!/.match?(operator) ? "NOT EXISTS" : "EXISTS"} (#{subquery})"
+  end
+
   def sql_for_updated_by_field(field, operator, value)
     neg = (operator == '!' ? 'NOT' : '')
     subquery = "SELECT 1 FROM #{Journal.table_name}" +
index 75efaae8ab0550ce7c18f659e5ebfb527d835408..118cb3dc11ff24f0c9d50d1b53ded0eaca1a5e96 100644 (file)
@@ -803,6 +803,47 @@ class QueryTest < ActiveSupport::TestCase
     end
   end
 
+  def test_filter_notes
+    user = User.generate!
+    Journal.create!(:user_id => user.id, :journalized => Issue.find(2), :notes => 'Notes.')
+    Journal.create!(:user_id => user.id, :journalized => Issue.find(3), :notes => 'Notes.')
+
+    issue_journals = Issue.find(1).journals.sort
+    assert_equal ['Journal notes', 'Some notes with Redmine links: #2, r2.'], issue_journals.map(&:notes)
+    assert_equal [false, false], issue_journals.map(&:private_notes)
+
+    query = IssueQuery.new(:name => '_')
+    filter_name = 'notes'
+    assert_include filter_name, query.available_filters.keys
+
+    {
+      '~' => [1, 2, 3],
+      '!~' => Issue.ids.sort - [1, 2, 3],
+      '^' => [2, 3],
+      '$' => [1],
+    }.each do |operator, expected|
+      query.filters = {filter_name => {:operator => operator, :values => ['Notes']}}
+      assert_equal expected, find_issues_with_query(query).map(&:id).sort
+    end
+  end
+
+  def test_filter_notes_should_ignore_private_notes_that_are_not_visible
+    user = User.generate!
+    Journal.create!(:user_id => user.id, :journalized => Issue.find(2), :notes => 'Notes.', :private_notes => true)
+    Journal.create!(:user_id => user.id, :journalized => Issue.find(3), :notes => 'Notes.')
+
+    issue_journals = Issue.find(1).journals.sort
+    assert_equal ['Journal notes', 'Some notes with Redmine links: #2, r2.'], issue_journals.map(&:notes)
+    assert_equal [false, false], issue_journals.map(&:private_notes)
+
+    query = IssueQuery.new(:name => '_')
+    filter_name = 'notes'
+    assert_include filter_name, query.available_filters.keys
+
+    query.filters = {filter_name => {:operator => '~', :values => ['Notes']}}
+    assert_equal [1, 3], find_issues_with_query(query).map(&:id).sort
+  end
+
   def test_filter_updated_by
     user = User.generate!
     Journal.create!(:user_id => user.id, :journalized => Issue.find(2), :notes => 'Notes')