@@ -36,7 +36,11 class QueryColumn | |||||
36 |
|
36 | |||
37 | # Returns true if the column is sortable, otherwise false |
|
37 | # Returns true if the column is sortable, otherwise false | |
38 | def sortable? |
|
38 | def sortable? | |
39 | !sortable.nil? |
|
39 | !@sortable.nil? | |
|
40 | end | |||
|
41 | ||||
|
42 | def sortable | |||
|
43 | @sortable.is_a?(Proc) ? @sortable.call : @sortable | |||
40 | end |
|
44 | end | |
41 |
|
45 | |||
42 | def value(issue) |
|
46 | def value(issue) | |
@@ -136,8 +140,8 class Query < ActiveRecord::Base | |||||
136 | QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true), |
|
140 | QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true), | |
137 | QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true), |
|
141 | QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true), | |
138 | QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"), |
|
142 | QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"), | |
139 |
QueryColumn.new(:author, :sortable => |
|
143 | QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true), | |
140 |
QueryColumn.new(:assigned_to, :sortable => |
|
144 | QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true), | |
141 | QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'), |
|
145 | QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'), | |
142 | QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true), |
|
146 | QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true), | |
143 | QueryColumn.new(:fixed_version, :sortable => ["#{Version.table_name}.effective_date", "#{Version.table_name}.name"], :default_order => 'desc', :groupable => true), |
|
147 | QueryColumn.new(:fixed_version, :sortable => ["#{Version.table_name}.effective_date", "#{Version.table_name}.name"], :default_order => 'desc', :groupable => true), |
@@ -26,12 +26,13 class User < Principal | |||||
26 | STATUS_REGISTERED = 2 |
|
26 | STATUS_REGISTERED = 2 | |
27 | STATUS_LOCKED = 3 |
|
27 | STATUS_LOCKED = 3 | |
28 |
|
28 | |||
|
29 | # Different ways of displaying/sorting users | |||
29 | USER_FORMATS = { |
|
30 | USER_FORMATS = { | |
30 | :firstname_lastname => '#{firstname} #{lastname}', |
|
31 | :firstname_lastname => {:string => '#{firstname} #{lastname}', :order => %w(firstname lastname id)}, | |
31 | :firstname => '#{firstname}', |
|
32 | :firstname => {:string => '#{firstname}', :order => %w(firstname id)}, | |
32 | :lastname_firstname => '#{lastname} #{firstname}', |
|
33 | :lastname_firstname => {:string => '#{lastname} #{firstname}', :order => %w(lastname firstname id)}, | |
33 | :lastname_coma_firstname => '#{lastname}, #{firstname}', |
|
34 | :lastname_coma_firstname => {:string => '#{lastname}, #{firstname}', :order => %w(lastname firstname id)}, | |
34 | :username => '#{login}' |
|
35 | :username => {:string => '#{login}', :order => %w(login id)}, | |
35 | } |
|
36 | } | |
36 |
|
37 | |||
37 | MAIL_NOTIFICATION_OPTIONS = [ |
|
38 | MAIL_NOTIFICATION_OPTIONS = [ | |
@@ -168,13 +169,29 class User < Principal | |||||
168 | end |
|
169 | end | |
169 | end |
|
170 | end | |
170 | end |
|
171 | end | |
171 |
|
172 | |||
|
173 | def self.name_formatter(formatter = nil) | |||
|
174 | USER_FORMATS[formatter || Setting.user_format] || USER_FORMATS[:firstname_lastname] | |||
|
175 | end | |||
|
176 | ||||
|
177 | # Returns an array of fields names than can be used to make an order statement for users | |||
|
178 | # according to how user names are displayed | |||
|
179 | # Examples: | |||
|
180 | # | |||
|
181 | # User.fields_for_order_statement => ['users.login', 'users.id'] | |||
|
182 | # User.fields_for_order_statement('authors') => ['authors.login', 'authors.id'] | |||
|
183 | def self.fields_for_order_statement(table=nil) | |||
|
184 | table ||= table_name | |||
|
185 | name_formatter[:order].map {|field| "#{table}.#{field}"} | |||
|
186 | end | |||
|
187 | ||||
172 | # Return user's full name for display |
|
188 | # Return user's full name for display | |
173 | def name(formatter = nil) |
|
189 | def name(formatter = nil) | |
|
190 | f = self.class.name_formatter(formatter) | |||
174 | if formatter |
|
191 | if formatter | |
175 | eval('"' + (USER_FORMATS[formatter] || USER_FORMATS[:firstname_lastname]) + '"') |
|
192 | eval('"' + f[:string] + '"') | |
176 | else |
|
193 | else | |
177 | @name ||= eval('"' + (USER_FORMATS[Setting.user_format] || USER_FORMATS[:firstname_lastname]) + '"') |
|
194 | @name ||= eval('"' + f[:string] + '"') | |
178 | end |
|
195 | end | |
179 | end |
|
196 | end | |
180 |
|
197 |
@@ -276,11 +276,6 class IssuesControllerTest < ActionController::TestCase | |||||
276 | assert_response :success |
|
276 | assert_response :success | |
277 | end |
|
277 | end | |
278 |
|
278 | |||
279 | def test_index_sort_by_field_not_included_in_columns |
|
|||
280 | Setting.issue_list_default_columns = %w(subject author) |
|
|||
281 | get :index, :sort => 'tracker' |
|
|||
282 | end |
|
|||
283 |
|
||||
284 | def test_index_csv |
|
279 | def test_index_csv | |
285 | get :index, :format => 'csv' |
|
280 | get :index, :format => 'csv' | |
286 | assert_response :success |
|
281 | assert_response :success | |
@@ -421,10 +416,43 class IssuesControllerTest < ActionController::TestCase | |||||
421 | assert !issues.empty? |
|
416 | assert !issues.empty? | |
422 | assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id) |
|
417 | assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id) | |
423 | end |
|
418 | end | |
|
419 | ||||
|
420 | def test_index_sort_by_field_not_included_in_columns | |||
|
421 | Setting.issue_list_default_columns = %w(subject author) | |||
|
422 | get :index, :sort => 'tracker' | |||
|
423 | end | |||
|
424 | ||||
|
425 | def test_index_sort_by_assigned_to | |||
|
426 | get :index, :sort => 'assigned_to' | |||
|
427 | assert_response :success | |||
|
428 | assignees = assigns(:issues).collect(&:assigned_to).compact | |||
|
429 | assert_equal assignees.sort, assignees | |||
|
430 | end | |||
|
431 | ||||
|
432 | def test_index_sort_by_assigned_to_desc | |||
|
433 | get :index, :sort => 'assigned_to:desc' | |||
|
434 | assert_response :success | |||
|
435 | assignees = assigns(:issues).collect(&:assigned_to).compact | |||
|
436 | assert_equal assignees.sort.reverse, assignees | |||
|
437 | end | |||
|
438 | ||||
|
439 | def test_index_group_by_assigned_to | |||
|
440 | get :index, :group_by => 'assigned_to', :sort => 'priority' | |||
|
441 | assert_response :success | |||
|
442 | end | |||
424 |
|
443 | |||
425 | def test_index_sort_by_author |
|
444 | def test_index_sort_by_author | |
426 | get :index, :sort => 'author' |
|
445 | get :index, :sort => 'author' | |
427 | assert_response :success |
|
446 | assert_response :success | |
|
447 | authors = assigns(:issues).collect(&:author) | |||
|
448 | assert_equal authors.sort, authors | |||
|
449 | end | |||
|
450 | ||||
|
451 | def test_index_sort_by_author_desc | |||
|
452 | get :index, :sort => 'author:desc' | |||
|
453 | assert_response :success | |||
|
454 | authors = assigns(:issues).collect(&:author) | |||
|
455 | assert_equal authors.sort.reverse, authors | |||
428 | end |
|
456 | end | |
429 |
|
457 | |||
430 | def test_index_group_by_author |
|
458 | def test_index_group_by_author |
@@ -98,11 +98,11 class ActiveSupport::TestCase | |||||
98 | end |
|
98 | end | |
99 |
|
99 | |||
100 | def with_settings(options, &block) |
|
100 | def with_settings(options, &block) | |
101 | saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].dup; h} |
|
101 | saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].is_a?(Symbol) ? Setting[k] : Setting[k].dup; h} | |
102 | options.each {|k, v| Setting[k] = v} |
|
102 | options.each {|k, v| Setting[k] = v} | |
103 | yield |
|
103 | yield | |
104 | ensure |
|
104 | ensure | |
105 | saved_settings.each {|k, v| Setting[k] = v} |
|
105 | saved_settings.each {|k, v| Setting[k] = v} if saved_settings | |
106 | end |
|
106 | end | |
107 |
|
107 | |||
108 | def change_user_password(login, new_password) |
|
108 | def change_user_password(login, new_password) |
@@ -443,6 +443,22 class QueryTest < ActiveSupport::TestCase | |||||
443 | assert_nil q.group_by_column |
|
443 | assert_nil q.group_by_column | |
444 | assert_nil q.group_by_statement |
|
444 | assert_nil q.group_by_statement | |
445 | end |
|
445 | end | |
|
446 | ||||
|
447 | def test_sortable_columns_should_sort_assignees_according_to_user_format_setting | |||
|
448 | with_settings :user_format => 'lastname_coma_firstname' do | |||
|
449 | q = Query.new | |||
|
450 | assert q.sortable_columns.has_key?('assigned_to') | |||
|
451 | assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to'] | |||
|
452 | end | |||
|
453 | end | |||
|
454 | ||||
|
455 | def test_sortable_columns_should_sort_authors_according_to_user_format_setting | |||
|
456 | with_settings :user_format => 'lastname_coma_firstname' do | |||
|
457 | q = Query.new | |||
|
458 | assert q.sortable_columns.has_key?('author') | |||
|
459 | assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author'] | |||
|
460 | end | |||
|
461 | end | |||
446 |
|
462 | |||
447 | def test_default_sort |
|
463 | def test_default_sort | |
448 | q = Query.new |
|
464 | q = Query.new |
@@ -397,6 +397,30 class UserTest < ActiveSupport::TestCase | |||||
397 | Setting.user_format = :username |
|
397 | Setting.user_format = :username | |
398 | assert_equal 'jsmith', @jsmith.reload.name |
|
398 | assert_equal 'jsmith', @jsmith.reload.name | |
399 | end |
|
399 | end | |
|
400 | ||||
|
401 | def test_fields_for_order_statement_should_return_fields_according_user_format_setting | |||
|
402 | with_settings :user_format => 'lastname_coma_firstname' do | |||
|
403 | assert_equal ['users.lastname', 'users.firstname', 'users.id'], User.fields_for_order_statement | |||
|
404 | end | |||
|
405 | end | |||
|
406 | ||||
|
407 | def test_fields_for_order_statement_width_table_name_should_prepend_table_name | |||
|
408 | with_settings :user_format => 'lastname_firstname' do | |||
|
409 | assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'], User.fields_for_order_statement('authors') | |||
|
410 | end | |||
|
411 | end | |||
|
412 | ||||
|
413 | def test_fields_for_order_statement_with_blank_format_should_return_default | |||
|
414 | with_settings :user_format => '' do | |||
|
415 | assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement | |||
|
416 | end | |||
|
417 | end | |||
|
418 | ||||
|
419 | def test_fields_for_order_statement_with_invalid_format_should_return_default | |||
|
420 | with_settings :user_format => 'foo' do | |||
|
421 | assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement | |||
|
422 | end | |||
|
423 | end | |||
400 |
|
424 | |||
401 | def test_lock |
|
425 | def test_lock | |
402 | user = User.try_to_login("jsmith", "jsmith") |
|
426 | user = User.try_to_login("jsmith", "jsmith") |
General Comments 0
You need to be logged in to leave comments.
Login now