diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -124,12 +124,12 @@ class IssueQuery < Query add_available_filter "priority_id", :type => :list, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] } - author_values = [] - author_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged? - author_values += users.collect{|s| [s.name, s.id.to_s] } + user_values = [] + user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged? + user_values += users.collect{|s| [s.name, s.id.to_s] } add_available_filter("author_id", - :type => :list, :values => author_values - ) unless author_values.empty? + :type => :list, :values => user_values + ) unless user_values.empty? assigned_to_values = [] assigned_to_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged? @@ -194,6 +194,16 @@ class IssueQuery < Query :values => subprojects.collect{|s| [s.name, s.id.to_s] } end + unless user_values.empty? + add_available_filter("updated_by", + :type => :list, :values => user_values + ) + + add_available_filter("last_updated_by", + :type => :list, :values => user_values + ) + end + add_custom_fields_filters(issue_custom_fields) add_associations_custom_fields_filters :project, :author, :assigned_to, :fixed_version @@ -504,6 +514,20 @@ class IssueQuery < Query end end + def sql_for_updated_by_field(field, operator, value) + db_table = Journal.table_name + + "#{Issue.table_name}.id IN (SELECT #{db_table}.journalized_id FROM #{db_table} WHERE #{db_table}.journalized_type='Issue' AND #{db_table}.journalized_id = #{Issue.table_name}.id AND " + + sql_for_field(field, operator, value, db_table, 'user_id') + ')' + end + + def sql_for_last_updated_by_field(field, operator, value) + db_table = Journal.table_name + + "#{Issue.table_name}.id IN (SELECT max(#{db_table}.journalized_id) FROM #{db_table} WHERE #{db_table}.journalized_type='Issue' AND #{db_table}.created_on = #{Issue.table_name}.updated_on AND #{db_table}.journalized_id = #{Issue.table_name}.id AND " + + sql_for_field(field, operator, value, db_table, 'user_id') + ')' + end + def sql_for_relations(field, operator, value, options={}) relation_options = IssueRelation::TYPES[field] return relation_options unless relation_options diff --git a/app/models/query.rb b/app/models/query.rb --- a/app/models/query.rb +++ b/app/models/query.rb @@ -696,7 +696,7 @@ class Query < ActiveRecord::Base operator = operator_for(field) # "me" value substitution - if %w(assigned_to_id author_id user_id watcher_id).include?(field) + if %w(assigned_to_id author_id user_id watcher_id updated_by last_updated_by).include?(field) if v.delete("me") if User.current.logged? v.push(User.current.id.to_s) diff --git a/config/locales/en.yml b/config/locales/en.yml --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -365,6 +365,8 @@ en: field_default_version: Default version field_remote_ip: IP address field_textarea_font: Font used for text areas + field_updated_by: Updated by + field_last_updated_by: Last updated by setting_app_title: Application title setting_app_subtitle: Application subtitle diff --git a/test/fixtures/issues.yml b/test/fixtures/issues.yml --- a/test/fixtures/issues.yml +++ b/test/fixtures/issues.yml @@ -2,7 +2,7 @@ issues_001: created_on: <%= 3.days.ago.to_s(:db) %> project_id: 1 - updated_on: <%= 1.day.ago.to_s(:db) %> + updated_on: <%= 1.days.ago.to_date.to_s(:db) %> priority_id: 4 subject: Cannot print recipes id: 1 @@ -96,7 +96,7 @@ issues_005: issues_006: created_on: <%= 1.minute.ago.to_s(:db) %> project_id: 5 - updated_on: <%= 1.minute.ago.to_s(:db) %> + updated_on: <%= 1.days.ago.to_date.to_s(:db) %> priority_id: 4 subject: Issue of a private subproject id: 6 @@ -252,7 +252,7 @@ issues_014: id: 14 created_on: <%= 15.days.ago.to_s(:db) %> project_id: 3 - updated_on: <%= 15.days.ago.to_s(:db) %> + updated_on: <%= 15.days.ago.to_date.to_s(:db) %> priority_id: 5 subject: Private issue on public project fixed_version_id: diff --git a/test/fixtures/journals.yml b/test/fixtures/journals.yml --- a/test/fixtures/journals.yml +++ b/test/fixtures/journals.yml @@ -14,7 +14,7 @@ journals_002: user_id: 2 journalized_id: 1 journals_003: - created_on: <%= 1.days.ago.to_date.to_s(:db) %> + created_on: 2006-07-19 21:09:50 +02:00 notes: "A comment with inline image: !picture.jpg! and a reference to #1 and r2." id: 3 journalized_type: Issue @@ -29,8 +29,15 @@ journals_004: journalized_id: 6 journals_005: id: 5 - created_on: <%= 1.days.ago.to_date.to_s(:db) %> + created_on: <%= 15.days.ago.to_date.to_s(:db) %> notes: "A comment on a private issue." user_id: 2 journalized_type: Issue journalized_id: 14 +journals_006: + id: 6 + created_on: 2006-07-19 21:07:27 +02:00 + notes: "New updates" + user_id: 3 + journalized_type: Issue + journalized_id: 3 diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -2702,7 +2702,7 @@ class IssueTest < ActiveSupport::TestCas end def test_last_journal_id_without_journals_should_return_nil - assert_nil Issue.find(3).last_journal_id + assert_nil Issue.find(4).last_journal_id end def test_journals_after_should_return_journals_with_greater_id diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -29,7 +29,7 @@ class QueryTest < ActiveSupport::TestCas :queries, :projects_trackers, :custom_fields_trackers, - :workflows + :workflows, :journals def setup User.current = nil @@ -691,6 +691,40 @@ class QueryTest < ActiveSupport::TestCas assert !result.include?(i3) end + def test_filter_updated_by + query = IssueQuery.new(:name => '_') + filter_name = "updated_by" + assert_include filter_name, query.available_filters.keys + + query.filters = {filter_name => {:operator => '=', :values => [2]}} + assert_equal [1,2,14], find_issues_with_query(query).map(&:id).uniq.sort + + query.filters = {filter_name => {:operator => '=', :values => [4]}} + assert_equal [], find_issues_with_query(query).map(&:id).uniq.sort + + query.filters = {filter_name => {:operator => '!', :values => [3]}, 'project_id' => {:operator => '=', :values =>[3]}} + assert_equal [14], find_issues_with_query(query).map(&:id).uniq.sort + end + + def test_filter_updated_by_me + User.current = User.find(1) + + query = IssueQuery.new(:name => '_', :filters => { "updated_by" => {:operator => '=', :values => ['me']}}) + assert_equal [1,6], find_issues_with_query(query).map(&:id).uniq.sort + end + + def test_filter_last_updated_by + query = IssueQuery.new(:name => '_') + filter_name = "last_updated_by" + assert_include filter_name, query.available_filters.keys + + query.filters = {filter_name => {:operator => '=', :values => [2]}} + assert_equal [1,2,14], find_issues_with_query(query).map(&:id).uniq.sort + + query.filters = {filter_name => {:operator => '!', :values => [1,2]}} + assert_equal [3], find_issues_with_query(query).map(&:id).uniq.sort + end + def test_user_custom_field_filtered_on_me User.current = User.find(2) cf = IssueCustomField.create!(:field_format => 'user', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1])