To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / test / unit / query_test.rb @ 441:cbce1fd3b1b7
History | View | Annotate | Download (22.6 KB)
| 1 | 441:cbce1fd3b1b7 | Chris | # Redmine - project management software
|
|---|---|---|---|
| 2 | # Copyright (C) 2006-2011 Jean-Philippe Lang
|
||
| 3 | 0:513646585e45 | Chris | #
|
| 4 | # This program is free software; you can redistribute it and/or
|
||
| 5 | # modify it under the terms of the GNU General Public License
|
||
| 6 | # as published by the Free Software Foundation; either version 2
|
||
| 7 | # of the License, or (at your option) any later version.
|
||
| 8 | #
|
||
| 9 | # This program is distributed in the hope that it will be useful,
|
||
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
| 12 | # GNU General Public License for more details.
|
||
| 13 | #
|
||
| 14 | # You should have received a copy of the GNU General Public License
|
||
| 15 | # along with this program; if not, write to the Free Software
|
||
| 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
| 17 | |||
| 18 | 119:8661b858af72 | Chris | require File.expand_path('../../test_helper', __FILE__) |
| 19 | 0:513646585e45 | Chris | |
| 20 | class QueryTest < ActiveSupport::TestCase |
||
| 21 | fixtures :projects, :enabled_modules, :users, :members, :member_roles, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :watchers, :custom_fields, :custom_values, :versions, :queries |
||
| 22 | |||
| 23 | def test_custom_fields_for_all_projects_should_be_available_in_global_queries |
||
| 24 | query = Query.new(:project => nil, :name => '_') |
||
| 25 | assert query.available_filters.has_key?('cf_1')
|
||
| 26 | assert !query.available_filters.has_key?('cf_3')
|
||
| 27 | end
|
||
| 28 | |||
| 29 | def test_system_shared_versions_should_be_available_in_global_queries |
||
| 30 | Version.find(2).update_attribute :sharing, 'system' |
||
| 31 | query = Query.new(:project => nil, :name => '_') |
||
| 32 | assert query.available_filters.has_key?('fixed_version_id')
|
||
| 33 | assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'} |
||
| 34 | end
|
||
| 35 | |||
| 36 | 14:1d32c0a0efbf | Chris | def test_project_filter_in_global_queries |
| 37 | query = Query.new(:project => nil, :name => '_') |
||
| 38 | project_filter = query.available_filters["project_id"]
|
||
| 39 | assert_not_nil project_filter |
||
| 40 | project_ids = project_filter[:values].map{|p| p[1]} |
||
| 41 | assert project_ids.include?("1") #public project |
||
| 42 | assert !project_ids.include?("2") #private project user cannot see |
||
| 43 | end
|
||
| 44 | |||
| 45 | 0:513646585e45 | Chris | def find_issues_with_query(query) |
| 46 | Issue.find :all, |
||
| 47 | :include => [ :assigned_to, :status, :tracker, :project, :priority ], |
||
| 48 | :conditions => query.statement
|
||
| 49 | end
|
||
| 50 | |||
| 51 | 22:40f7cfd4df19 | chris | def assert_find_issues_with_query_is_successful(query) |
| 52 | assert_nothing_raised do
|
||
| 53 | find_issues_with_query(query) |
||
| 54 | end
|
||
| 55 | end
|
||
| 56 | |||
| 57 | def assert_query_statement_includes(query, condition) |
||
| 58 | assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}"
|
||
| 59 | end
|
||
| 60 | |||
| 61 | 0:513646585e45 | Chris | def test_query_should_allow_shared_versions_for_a_project_query |
| 62 | subproject_version = Version.find(4) |
||
| 63 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 64 | query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s]) |
||
| 65 | |||
| 66 | assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
|
||
| 67 | end
|
||
| 68 | |||
| 69 | def test_query_with_multiple_custom_fields |
||
| 70 | query = Query.find(1) |
||
| 71 | assert query.valid? |
||
| 72 | assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
|
||
| 73 | issues = find_issues_with_query(query) |
||
| 74 | assert_equal 1, issues.length
|
||
| 75 | assert_equal Issue.find(3), issues.first |
||
| 76 | end
|
||
| 77 | |||
| 78 | def test_operator_none |
||
| 79 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 80 | query.add_filter('fixed_version_id', '!*', ['']) |
||
| 81 | query.add_filter('cf_1', '!*', ['']) |
||
| 82 | assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
|
||
| 83 | assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
|
||
| 84 | find_issues_with_query(query) |
||
| 85 | end
|
||
| 86 | |||
| 87 | def test_operator_none_for_integer |
||
| 88 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 89 | query.add_filter('estimated_hours', '!*', ['']) |
||
| 90 | issues = find_issues_with_query(query) |
||
| 91 | assert !issues.empty? |
||
| 92 | assert issues.all? {|i| !i.estimated_hours}
|
||
| 93 | end
|
||
| 94 | |||
| 95 | def test_operator_all |
||
| 96 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 97 | query.add_filter('fixed_version_id', '*', ['']) |
||
| 98 | query.add_filter('cf_1', '*', ['']) |
||
| 99 | assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
|
||
| 100 | assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
|
||
| 101 | find_issues_with_query(query) |
||
| 102 | end
|
||
| 103 | |||
| 104 | def test_operator_greater_than |
||
| 105 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 106 | query.add_filter('done_ratio', '>=', ['40']) |
||
| 107 | assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40")
|
||
| 108 | find_issues_with_query(query) |
||
| 109 | end
|
||
| 110 | |||
| 111 | def test_operator_in_more_than |
||
| 112 | Issue.find(7).update_attribute(:due_date, (Date.today + 15)) |
||
| 113 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 114 | query.add_filter('due_date', '>t+', ['15']) |
||
| 115 | issues = find_issues_with_query(query) |
||
| 116 | assert !issues.empty? |
||
| 117 | issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
|
||
| 118 | end
|
||
| 119 | |||
| 120 | def test_operator_in_less_than |
||
| 121 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 122 | query.add_filter('due_date', '<t+', ['15']) |
||
| 123 | issues = find_issues_with_query(query) |
||
| 124 | assert !issues.empty? |
||
| 125 | issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
|
||
| 126 | end
|
||
| 127 | |||
| 128 | def test_operator_less_than_ago |
||
| 129 | Issue.find(7).update_attribute(:due_date, (Date.today - 3)) |
||
| 130 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 131 | query.add_filter('due_date', '>t-', ['3']) |
||
| 132 | issues = find_issues_with_query(query) |
||
| 133 | assert !issues.empty? |
||
| 134 | issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
|
||
| 135 | end
|
||
| 136 | |||
| 137 | def test_operator_more_than_ago |
||
| 138 | Issue.find(7).update_attribute(:due_date, (Date.today - 10)) |
||
| 139 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 140 | query.add_filter('due_date', '<t-', ['10']) |
||
| 141 | assert query.statement.include?("#{Issue.table_name}.due_date <=")
|
||
| 142 | issues = find_issues_with_query(query) |
||
| 143 | assert !issues.empty? |
||
| 144 | issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
|
||
| 145 | end
|
||
| 146 | |||
| 147 | def test_operator_in |
||
| 148 | Issue.find(7).update_attribute(:due_date, (Date.today + 2)) |
||
| 149 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 150 | query.add_filter('due_date', 't+', ['2']) |
||
| 151 | issues = find_issues_with_query(query) |
||
| 152 | assert !issues.empty? |
||
| 153 | issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
|
||
| 154 | end
|
||
| 155 | |||
| 156 | def test_operator_ago |
||
| 157 | Issue.find(7).update_attribute(:due_date, (Date.today - 3)) |
||
| 158 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 159 | query.add_filter('due_date', 't-', ['3']) |
||
| 160 | issues = find_issues_with_query(query) |
||
| 161 | assert !issues.empty? |
||
| 162 | issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
|
||
| 163 | end
|
||
| 164 | |||
| 165 | def test_operator_today |
||
| 166 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 167 | query.add_filter('due_date', 't', ['']) |
||
| 168 | issues = find_issues_with_query(query) |
||
| 169 | assert !issues.empty? |
||
| 170 | issues.each {|issue| assert_equal Date.today, issue.due_date}
|
||
| 171 | end
|
||
| 172 | |||
| 173 | def test_operator_this_week_on_date |
||
| 174 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 175 | query.add_filter('due_date', 'w', ['']) |
||
| 176 | find_issues_with_query(query) |
||
| 177 | end
|
||
| 178 | |||
| 179 | def test_operator_this_week_on_datetime |
||
| 180 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 181 | query.add_filter('created_on', 'w', ['']) |
||
| 182 | find_issues_with_query(query) |
||
| 183 | end
|
||
| 184 | |||
| 185 | def test_operator_contains |
||
| 186 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 187 | query.add_filter('subject', '~', ['uNable']) |
||
| 188 | assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
|
||
| 189 | result = find_issues_with_query(query) |
||
| 190 | assert result.empty? |
||
| 191 | result.each {|issue| assert issue.subject.downcase.include?('unable') }
|
||
| 192 | end
|
||
| 193 | |||
| 194 | 441:cbce1fd3b1b7 | Chris | def test_range_for_this_week_with_week_starting_on_monday |
| 195 | I18n.locale = :fr |
||
| 196 | assert_equal '1', I18n.t(:general_first_day_of_week) |
||
| 197 | |||
| 198 | Date.stubs(:today).returns(Date.parse('2011-04-29')) |
||
| 199 | |||
| 200 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 201 | query.add_filter('due_date', 'w', ['']) |
||
| 202 | assert query.statement.match(/issues\.due_date > '2011-04-24 23:59:59(\.9+)?' AND issues\.due_date <= '2011-05-01 23:59:59(\.9+)?/), "range not found in #{query.statement}" |
||
| 203 | I18n.locale = :en |
||
| 204 | end
|
||
| 205 | |||
| 206 | def test_range_for_this_week_with_week_starting_on_sunday |
||
| 207 | I18n.locale = :en |
||
| 208 | assert_equal '7', I18n.t(:general_first_day_of_week) |
||
| 209 | |||
| 210 | Date.stubs(:today).returns(Date.parse('2011-04-29')) |
||
| 211 | |||
| 212 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 213 | query.add_filter('due_date', 'w', ['']) |
||
| 214 | assert query.statement.match(/issues\.due_date > '2011-04-23 23:59:59(\.9+)?' AND issues\.due_date <= '2011-04-30 23:59:59(\.9+)?/), "range not found in #{query.statement}" |
||
| 215 | end
|
||
| 216 | |||
| 217 | 0:513646585e45 | Chris | def test_operator_does_not_contains |
| 218 | query = Query.new(:project => Project.find(1), :name => '_') |
||
| 219 | query.add_filter('subject', '!~', ['uNable']) |
||
| 220 | assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
|
||
| 221 | find_issues_with_query(query) |
||
| 222 | end
|
||
| 223 | |||
| 224 | def test_filter_watched_issues |
||
| 225 | User.current = User.find(1) |
||
| 226 | query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}}) |
||
| 227 | result = find_issues_with_query(query) |
||
| 228 | assert_not_nil result |
||
| 229 | assert !result.empty? |
||
| 230 | assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id) |
||
| 231 | User.current = nil |
||
| 232 | end
|
||
| 233 | |||
| 234 | def test_filter_unwatched_issues |
||
| 235 | User.current = User.find(1) |
||
| 236 | query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}}) |
||
| 237 | result = find_issues_with_query(query) |
||
| 238 | assert_not_nil result |
||
| 239 | assert !result.empty? |
||
| 240 | assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size) |
||
| 241 | User.current = nil |
||
| 242 | end
|
||
| 243 | |||
| 244 | 441:cbce1fd3b1b7 | Chris | def test_statement_should_be_nil_with_no_filters |
| 245 | q = Query.new(:name => '_') |
||
| 246 | q.filters = {}
|
||
| 247 | |||
| 248 | assert q.valid? |
||
| 249 | assert_nil q.statement |
||
| 250 | end
|
||
| 251 | |||
| 252 | 0:513646585e45 | Chris | def test_default_columns |
| 253 | q = Query.new
|
||
| 254 | assert !q.columns.empty? |
||
| 255 | end
|
||
| 256 | |||
| 257 | def test_set_column_names |
||
| 258 | q = Query.new
|
||
| 259 | q.column_names = ['tracker', :subject, '', 'unknonw_column'] |
||
| 260 | assert_equal [:tracker, :subject], q.columns.collect {|c| c.name} |
||
| 261 | c = q.columns.first |
||
| 262 | assert q.has_column?(c) |
||
| 263 | end
|
||
| 264 | |||
| 265 | def test_groupable_columns_should_include_custom_fields |
||
| 266 | q = Query.new
|
||
| 267 | assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn}
|
||
| 268 | end
|
||
| 269 | 119:8661b858af72 | Chris | |
| 270 | def test_grouped_with_valid_column |
||
| 271 | q = Query.new(:group_by => 'status') |
||
| 272 | assert q.grouped? |
||
| 273 | assert_not_nil q.group_by_column |
||
| 274 | assert_equal :status, q.group_by_column.name
|
||
| 275 | assert_not_nil q.group_by_statement |
||
| 276 | assert_equal 'status', q.group_by_statement
|
||
| 277 | end
|
||
| 278 | |||
| 279 | def test_grouped_with_invalid_column |
||
| 280 | q = Query.new(:group_by => 'foo') |
||
| 281 | assert !q.grouped? |
||
| 282 | assert_nil q.group_by_column |
||
| 283 | assert_nil q.group_by_statement |
||
| 284 | end
|
||
| 285 | 0:513646585e45 | Chris | |
| 286 | def test_default_sort |
||
| 287 | q = Query.new
|
||
| 288 | assert_equal [], q.sort_criteria |
||
| 289 | end
|
||
| 290 | |||
| 291 | def test_set_sort_criteria_with_hash |
||
| 292 | q = Query.new
|
||
| 293 | q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
|
||
| 294 | assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria |
||
| 295 | end
|
||
| 296 | |||
| 297 | def test_set_sort_criteria_with_array |
||
| 298 | q = Query.new
|
||
| 299 | q.sort_criteria = [['priority', 'desc'], 'tracker'] |
||
| 300 | assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria |
||
| 301 | end
|
||
| 302 | |||
| 303 | def test_create_query_with_sort |
||
| 304 | q = Query.new(:name => 'Sorted') |
||
| 305 | q.sort_criteria = [['priority', 'desc'], 'tracker'] |
||
| 306 | assert q.save |
||
| 307 | q.reload |
||
| 308 | assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria |
||
| 309 | end
|
||
| 310 | |||
| 311 | def test_sort_by_string_custom_field_asc |
||
| 312 | q = Query.new
|
||
| 313 | c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
|
||
| 314 | assert c |
||
| 315 | assert c.sortable |
||
| 316 | issues = Issue.find :all, |
||
| 317 | :include => [ :assigned_to, :status, :tracker, :project, :priority ], |
||
| 318 | :conditions => q.statement,
|
||
| 319 | :order => "#{c.sortable} ASC" |
||
| 320 | values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
|
||
| 321 | assert !values.empty? |
||
| 322 | assert_equal values.sort, values |
||
| 323 | end
|
||
| 324 | |||
| 325 | def test_sort_by_string_custom_field_desc |
||
| 326 | q = Query.new
|
||
| 327 | c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
|
||
| 328 | assert c |
||
| 329 | assert c.sortable |
||
| 330 | issues = Issue.find :all, |
||
| 331 | :include => [ :assigned_to, :status, :tracker, :project, :priority ], |
||
| 332 | :conditions => q.statement,
|
||
| 333 | :order => "#{c.sortable} DESC" |
||
| 334 | values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
|
||
| 335 | assert !values.empty? |
||
| 336 | assert_equal values.sort.reverse, values |
||
| 337 | end
|
||
| 338 | |||
| 339 | def test_sort_by_float_custom_field_asc |
||
| 340 | q = Query.new
|
||
| 341 | c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
|
||
| 342 | assert c |
||
| 343 | assert c.sortable |
||
| 344 | issues = Issue.find :all, |
||
| 345 | :include => [ :assigned_to, :status, :tracker, :project, :priority ], |
||
| 346 | :conditions => q.statement,
|
||
| 347 | :order => "#{c.sortable} ASC" |
||
| 348 | values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
|
||
| 349 | assert !values.empty? |
||
| 350 | assert_equal values.sort, values |
||
| 351 | end
|
||
| 352 | |||
| 353 | def test_invalid_query_should_raise_query_statement_invalid_error |
||
| 354 | q = Query.new
|
||
| 355 | assert_raise Query::StatementInvalid do |
||
| 356 | q.issues(:conditions => "foo = 1") |
||
| 357 | end
|
||
| 358 | end
|
||
| 359 | |||
| 360 | def test_issue_count_by_association_group |
||
| 361 | q = Query.new(:name => '_', :group_by => 'assigned_to') |
||
| 362 | count_by_group = q.issue_count_by_group |
||
| 363 | assert_kind_of Hash, count_by_group
|
||
| 364 | assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
|
||
| 365 | assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
|
||
| 366 | assert count_by_group.has_key?(User.find(3)) |
||
| 367 | end
|
||
| 368 | |||
| 369 | def test_issue_count_by_list_custom_field_group |
||
| 370 | q = Query.new(:name => '_', :group_by => 'cf_1') |
||
| 371 | count_by_group = q.issue_count_by_group |
||
| 372 | assert_kind_of Hash, count_by_group
|
||
| 373 | assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
|
||
| 374 | assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
|
||
| 375 | assert count_by_group.has_key?('MySQL')
|
||
| 376 | end
|
||
| 377 | |||
| 378 | def test_issue_count_by_date_custom_field_group |
||
| 379 | q = Query.new(:name => '_', :group_by => 'cf_8') |
||
| 380 | count_by_group = q.issue_count_by_group |
||
| 381 | assert_kind_of Hash, count_by_group
|
||
| 382 | assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
|
||
| 383 | assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
|
||
| 384 | end
|
||
| 385 | |||
| 386 | def test_label_for |
||
| 387 | q = Query.new
|
||
| 388 | assert_equal 'assigned_to', q.label_for('assigned_to_id') |
||
| 389 | end
|
||
| 390 | |||
| 391 | def test_editable_by |
||
| 392 | admin = User.find(1) |
||
| 393 | manager = User.find(2) |
||
| 394 | developer = User.find(3) |
||
| 395 | |||
| 396 | # Public query on project 1
|
||
| 397 | q = Query.find(1) |
||
| 398 | assert q.editable_by?(admin) |
||
| 399 | assert q.editable_by?(manager) |
||
| 400 | assert !q.editable_by?(developer) |
||
| 401 | |||
| 402 | # Private query on project 1
|
||
| 403 | q = Query.find(2) |
||
| 404 | assert q.editable_by?(admin) |
||
| 405 | assert !q.editable_by?(manager) |
||
| 406 | assert q.editable_by?(developer) |
||
| 407 | |||
| 408 | # Private query for all projects
|
||
| 409 | q = Query.find(3) |
||
| 410 | assert q.editable_by?(admin) |
||
| 411 | assert !q.editable_by?(manager) |
||
| 412 | assert q.editable_by?(developer) |
||
| 413 | |||
| 414 | # Public query for all projects
|
||
| 415 | q = Query.find(4) |
||
| 416 | assert q.editable_by?(admin) |
||
| 417 | assert !q.editable_by?(manager) |
||
| 418 | assert !q.editable_by?(developer) |
||
| 419 | end
|
||
| 420 | 14:1d32c0a0efbf | Chris | |
| 421 | context "#available_filters" do |
||
| 422 | 22:40f7cfd4df19 | chris | setup do
|
| 423 | @query = Query.new(:name => "_") |
||
| 424 | end
|
||
| 425 | |||
| 426 | 14:1d32c0a0efbf | Chris | should "include users of visible projects in cross-project view" do |
| 427 | 22:40f7cfd4df19 | chris | users = @query.available_filters["assigned_to_id"] |
| 428 | 14:1d32c0a0efbf | Chris | assert_not_nil users |
| 429 | assert users[:values].map{|u|u[1]}.include?("3") |
||
| 430 | end
|
||
| 431 | 22:40f7cfd4df19 | chris | |
| 432 | 119:8661b858af72 | Chris | should "include visible projects in cross-project view" do |
| 433 | projects = @query.available_filters["project_id"] |
||
| 434 | assert_not_nil projects |
||
| 435 | assert projects[:values].map{|u|u[1]}.include?("1") |
||
| 436 | end
|
||
| 437 | |||
| 438 | 22:40f7cfd4df19 | chris | context "'member_of_group' filter" do |
| 439 | should "be present" do |
||
| 440 | assert @query.available_filters.keys.include?("member_of_group") |
||
| 441 | end
|
||
| 442 | |||
| 443 | should "be an optional list" do |
||
| 444 | assert_equal :list_optional, @query.available_filters["member_of_group"][:type] |
||
| 445 | end
|
||
| 446 | |||
| 447 | should "have a list of the groups as values" do |
||
| 448 | Group.destroy_all # No fixtures |
||
| 449 | group1 = Group.generate!.reload
|
||
| 450 | group2 = Group.generate!.reload
|
||
| 451 | |||
| 452 | expected_group_list = [ |
||
| 453 | 37:94944d00e43c | chris | [group1.name, group1.id.to_s], |
| 454 | [group2.name, group2.id.to_s] |
||
| 455 | 22:40f7cfd4df19 | chris | ] |
| 456 | assert_equal expected_group_list.sort, @query.available_filters["member_of_group"][:values].sort |
||
| 457 | end
|
||
| 458 | |||
| 459 | end
|
||
| 460 | |||
| 461 | context "'assigned_to_role' filter" do |
||
| 462 | should "be present" do |
||
| 463 | assert @query.available_filters.keys.include?("assigned_to_role") |
||
| 464 | end
|
||
| 465 | |||
| 466 | should "be an optional list" do |
||
| 467 | assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type] |
||
| 468 | end
|
||
| 469 | |||
| 470 | should "have a list of the Roles as values" do |
||
| 471 | 37:94944d00e43c | chris | assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1']) |
| 472 | assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2']) |
||
| 473 | assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3']) |
||
| 474 | 22:40f7cfd4df19 | chris | end
|
| 475 | |||
| 476 | should "not include the built in Roles as values" do |
||
| 477 | 37:94944d00e43c | chris | assert ! @query.available_filters["assigned_to_role"][:values].include?(['Non member','4']) |
| 478 | assert ! @query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5']) |
||
| 479 | 22:40f7cfd4df19 | chris | end
|
| 480 | |||
| 481 | end
|
||
| 482 | |||
| 483 | 14:1d32c0a0efbf | Chris | end
|
| 484 | 22:40f7cfd4df19 | chris | |
| 485 | context "#statement" do |
||
| 486 | context "with 'member_of_group' filter" do |
||
| 487 | setup do
|
||
| 488 | Group.destroy_all # No fixtures |
||
| 489 | @user_in_group = User.generate! |
||
| 490 | @second_user_in_group = User.generate! |
||
| 491 | @user_in_group2 = User.generate! |
||
| 492 | @user_not_in_group = User.generate! |
||
| 493 | |||
| 494 | @group = Group.generate!.reload |
||
| 495 | @group.users << @user_in_group |
||
| 496 | @group.users << @second_user_in_group |
||
| 497 | |||
| 498 | @group2 = Group.generate!.reload |
||
| 499 | @group2.users << @user_in_group2 |
||
| 500 | |||
| 501 | end
|
||
| 502 | |||
| 503 | should "search assigned to for users in the group" do |
||
| 504 | @query = Query.new(:name => '_') |
||
| 505 | @query.add_filter('member_of_group', '=', [@group.id.to_s]) |
||
| 506 | |||
| 507 | assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')" |
||
| 508 | assert_find_issues_with_query_is_successful @query
|
||
| 509 | end
|
||
| 510 | |||
| 511 | should "search not assigned to any group member (none)" do |
||
| 512 | @query = Query.new(:name => '_') |
||
| 513 | @query.add_filter('member_of_group', '!*', ['']) |
||
| 514 | |||
| 515 | # Users not in a group
|
||
| 516 | assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')" |
||
| 517 | assert_find_issues_with_query_is_successful @query
|
||
| 518 | end
|
||
| 519 | |||
| 520 | should "search assigned to any group member (all)" do |
||
| 521 | @query = Query.new(:name => '_') |
||
| 522 | @query.add_filter('member_of_group', '*', ['']) |
||
| 523 | |||
| 524 | # Only users in a group
|
||
| 525 | assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')" |
||
| 526 | assert_find_issues_with_query_is_successful @query
|
||
| 527 | 245:051f544170fe | Chris | end
|
| 528 | |||
| 529 | should "return an empty set with = empty group" do |
||
| 530 | @empty_group = Group.generate! |
||
| 531 | @query = Query.new(:name => '_') |
||
| 532 | @query.add_filter('member_of_group', '=', [@empty_group.id.to_s]) |
||
| 533 | |||
| 534 | assert_equal [], find_issues_with_query(@query)
|
||
| 535 | end
|
||
| 536 | |||
| 537 | should "return issues with ! empty group" do |
||
| 538 | @empty_group = Group.generate! |
||
| 539 | @query = Query.new(:name => '_') |
||
| 540 | @query.add_filter('member_of_group', '!', [@empty_group.id.to_s]) |
||
| 541 | |||
| 542 | assert_find_issues_with_query_is_successful @query
|
||
| 543 | 22:40f7cfd4df19 | chris | end
|
| 544 | end
|
||
| 545 | |||
| 546 | context "with 'assigned_to_role' filter" do |
||
| 547 | setup do
|
||
| 548 | # No fixtures
|
||
| 549 | MemberRole.delete_all
|
||
| 550 | Member.delete_all
|
||
| 551 | Role.delete_all
|
||
| 552 | |||
| 553 | @manager_role = Role.generate!(:name => 'Manager') |
||
| 554 | @developer_role = Role.generate!(:name => 'Developer') |
||
| 555 | |||
| 556 | @project = Project.generate! |
||
| 557 | @manager = User.generate! |
||
| 558 | @developer = User.generate! |
||
| 559 | @boss = User.generate! |
||
| 560 | User.add_to_project(@manager, @project, @manager_role) |
||
| 561 | User.add_to_project(@developer, @project, @developer_role) |
||
| 562 | User.add_to_project(@boss, @project, [@manager_role, @developer_role]) |
||
| 563 | end
|
||
| 564 | |||
| 565 | should "search assigned to for users with the Role" do |
||
| 566 | @query = Query.new(:name => '_') |
||
| 567 | @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s]) |
||
| 568 | |||
| 569 | assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@boss.id}')" |
||
| 570 | assert_find_issues_with_query_is_successful @query
|
||
| 571 | end
|
||
| 572 | |||
| 573 | should "search assigned to for users not assigned to any Role (none)" do |
||
| 574 | @query = Query.new(:name => '_') |
||
| 575 | @query.add_filter('assigned_to_role', '!*', ['']) |
||
| 576 | |||
| 577 | assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')" |
||
| 578 | assert_find_issues_with_query_is_successful @query
|
||
| 579 | end
|
||
| 580 | |||
| 581 | should "search assigned to for users assigned to any Role (all)" do |
||
| 582 | @query = Query.new(:name => '_') |
||
| 583 | @query.add_filter('assigned_to_role', '*', ['']) |
||
| 584 | |||
| 585 | assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')" |
||
| 586 | assert_find_issues_with_query_is_successful @query
|
||
| 587 | end
|
||
| 588 | 245:051f544170fe | Chris | |
| 589 | should "return an empty set with empty role" do |
||
| 590 | @empty_role = Role.generate! |
||
| 591 | @query = Query.new(:name => '_') |
||
| 592 | @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s]) |
||
| 593 | |||
| 594 | assert_equal [], find_issues_with_query(@query)
|
||
| 595 | end
|
||
| 596 | |||
| 597 | should "return issues with ! empty role" do |
||
| 598 | @empty_role = Role.generate! |
||
| 599 | @query = Query.new(:name => '_') |
||
| 600 | @query.add_filter('member_of_group', '!', [@empty_role.id.to_s]) |
||
| 601 | |||
| 602 | assert_find_issues_with_query_is_successful @query
|
||
| 603 | end
|
||
| 604 | 22:40f7cfd4df19 | chris | end
|
| 605 | end
|
||
| 606 | |||
| 607 | 0:513646585e45 | Chris | end |