You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

time_entry_query_test.rb 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006- Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. require_relative '../test_helper'
  19. class TimeEntryQueryTest < ActiveSupport::TestCase
  20. fixtures :issues, :projects, :users,
  21. :members, :roles, :member_roles,
  22. :trackers, :issue_statuses,
  23. :projects_trackers,
  24. :journals, :journal_details,
  25. :issue_categories, :enumerations,
  26. :groups_users,
  27. :enabled_modules,
  28. :custom_fields, :custom_fields_trackers, :custom_fields_projects
  29. def setup
  30. User.current = nil
  31. end
  32. def test_filter_values_without_project_should_be_arrays
  33. q = TimeEntryQuery.new
  34. assert_nil q.project
  35. q.available_filters.each do |name, filter|
  36. values = filter.values
  37. assert (values.nil? || values.is_a?(Array)),
  38. "#values for #{name} filter returned a #{values.class.name}"
  39. end
  40. end
  41. def test_filter_values_with_project_should_be_arrays
  42. q = TimeEntryQuery.new(:project => Project.find(1))
  43. assert_not_nil q.project
  44. q.available_filters.each do |name, filter|
  45. values = filter.values
  46. assert (values.nil? || values.is_a?(Array)),
  47. "#values for #{name} filter returned a #{values.class.name}"
  48. end
  49. end
  50. def test_cross_project_activity_filter_should_propose_non_active_activities
  51. activity = TimeEntryActivity.create!(:name => 'Disabled', :active => false)
  52. assert !activity.active?
  53. query = TimeEntryQuery.new(:name => '_')
  54. assert options = query.available_filters['activity_id']
  55. assert values = options[:values]
  56. assert_include ["Disabled", activity.id.to_s], values
  57. end
  58. def test_activity_filter_should_consider_system_and_project_activities
  59. TimeEntry.delete_all
  60. system = TimeEntryActivity.create!(:name => 'Foo')
  61. TimeEntry.generate!(:activity => system, :hours => 1.0)
  62. override = TimeEntryActivity.create!(:name => 'Foo', :parent_id => system.id, :project_id => 1)
  63. other = TimeEntryActivity.create!(:name => 'Bar')
  64. TimeEntry.generate!(:activity => override, :hours => 2.0)
  65. TimeEntry.generate!(:activity => other, :hours => 4.0)
  66. with_current_user User.find(2) do
  67. query = TimeEntryQuery.new(:name => '_')
  68. query.add_filter('activity_id', '=', [system.id.to_s])
  69. assert_equal 3.0, query.results_scope.sum(:hours)
  70. query = TimeEntryQuery.new(:name => '_')
  71. query.add_filter('activity_id', '!', [system.id.to_s])
  72. assert_equal 4.0, query.results_scope.sum(:hours)
  73. end
  74. end
  75. def test_project_query_should_include_project_issue_custom_fields_only_as_filters
  76. global = IssueCustomField.generate!(:is_for_all => true, :is_filter => true)
  77. field_on_project =
  78. IssueCustomField.generate!(:is_for_all => false, :project_ids => [3],
  79. :is_filter => true)
  80. field_not_on_project =
  81. IssueCustomField.generate!(:is_for_all => false, :project_ids => [1, 2],
  82. :is_filter => true)
  83. query = TimeEntryQuery.new(:project => Project.find(3))
  84. assert_include "issue.cf_#{global.id}", query.available_filters.keys
  85. assert_include "issue.cf_#{field_on_project.id}", query.available_filters.keys
  86. assert_not_include "issue.cf_#{field_not_on_project.id}", query.available_filters.keys
  87. end
  88. def test_project_query_should_include_project_issue_custom_fields_only_as_columns
  89. global = IssueCustomField.generate!(:is_for_all => true, :is_filter => true)
  90. field_on_project =
  91. IssueCustomField.generate!(:is_for_all => false, :project_ids => [3],
  92. :is_filter => true)
  93. field_not_on_project =
  94. IssueCustomField.generate!(:is_for_all => false, :project_ids => [1, 2],
  95. :is_filter => true)
  96. query = TimeEntryQuery.new(:project => Project.find(3))
  97. assert_include "issue.cf_#{global.id}", query.available_columns.map {|c| c.name.to_s}
  98. assert_include "issue.cf_#{field_on_project.id}", query.available_columns.map {|c| c.name.to_s}
  99. assert_not_include "issue.cf_#{field_not_on_project.id}", query.available_columns.map {|c| c.name.to_s}
  100. end
  101. def test_issue_category_filter_should_not_be_available_in_global_queries
  102. query = TimeEntryQuery.new(:project => nil, :name => '_')
  103. assert !query.available_filters.has_key?('issue.category_id')
  104. end
  105. def test_project_status_filter_should_be_available_in_global_queries
  106. query = TimeEntryQuery.new(:project => nil, :name => '_')
  107. assert query.available_filters.has_key?('project.status')
  108. end
  109. def test_project_status_filter_should_be_available_when_project_has_subprojects
  110. query = TimeEntryQuery.new(:project => Project.find(1), :name => '_')
  111. assert query.available_filters.has_key?('project.status')
  112. end
  113. def test_project_status_filter_should_not_be_available_when_project_is_leaf
  114. query = TimeEntryQuery.new(:project => Project.find(2), :name => '_')
  115. assert !query.available_filters.has_key?('project.status')
  116. end
  117. def test_results_scope_should_be_in_the_same_order_when_paginating
  118. 4.times {TimeEntry.generate!}
  119. q = TimeEntryQuery.new
  120. q.sort_criteria = {'0' => ['user', 'asc']}
  121. time_entry_ids = q.results_scope.pluck(:id)
  122. paginated_time_entry_ids = []
  123. # Test with a maximum of 2 records per page.
  124. ((q.results_scope.count / 2) + 1).times do |i|
  125. paginated_time_entry_ids += q.results_scope.offset((i * 2)).limit(2).pluck(:id)
  126. end
  127. # Non-paginated time entry ids and paginated time entry ids should be in the same order.
  128. assert_equal time_entry_ids, paginated_time_entry_ids
  129. end
  130. end