From c7c8dc71f2fc8f224deb0a5340f7bbb8906e584d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Thu, 12 Mar 2009 18:06:54 +0000 Subject: [PATCH] Ability to save "sort order" in custom queries (#2899). git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2572 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/issues_controller.rb | 3 +- app/helpers/sort_helper.rb | 57 +++++++++++++++------- app/models/query.rb | 27 ++++++++++ app/views/queries/_form.rhtml | 9 ++++ config/locales/bg.yml | 3 ++ config/locales/ca.yml | 3 ++ config/locales/cs.yml | 3 ++ config/locales/da.yml | 3 ++ config/locales/de.yml | 3 ++ config/locales/en.yml | 3 ++ config/locales/es.yml | 3 ++ config/locales/fi.yml | 3 ++ config/locales/fr.yml | 3 ++ config/locales/gl.yml | 3 ++ config/locales/he.yml | 3 ++ config/locales/hu.yml | 3 ++ config/locales/it.yml | 3 ++ config/locales/ja.yml | 3 ++ config/locales/ko.yml | 3 ++ config/locales/lt.yml | 3 ++ config/locales/nl.yml | 3 ++ config/locales/no.yml | 3 ++ config/locales/pl.yml | 3 ++ config/locales/pt-BR.yml | 3 ++ config/locales/pt.yml | 3 ++ config/locales/ro.yml | 3 ++ config/locales/ru.yml | 3 ++ config/locales/sk.yml | 3 ++ config/locales/sl.yml | 3 ++ config/locales/sr.yml | 3 ++ config/locales/sv.yml | 3 ++ config/locales/th.yml | 3 ++ config/locales/tr.yml | 3 ++ config/locales/uk.yml | 3 ++ config/locales/vi.yml | 3 ++ config/locales/zh-TW.yml | 3 ++ config/locales/zh.yml | 3 ++ .../20090312172426_add_queries_sort_criteria.rb | 9 ++++ test/fixtures/queries.yml | 20 ++++++++ test/functional/queries_controller_test.rb | 29 +++++++++++ test/unit/query_test.rb | 25 ++++++++++ 41 files changed, 259 insertions(+), 19 deletions(-) create mode 100644 db/migrate/20090312172426_add_queries_sort_criteria.rb diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 0af5f192..929b928a 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -45,7 +45,7 @@ class IssuesController < ApplicationController def index retrieve_query - sort_init 'id', 'desc' + sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h})) if @query.valid? @@ -471,6 +471,7 @@ private @query = Query.find(params[:query_id], :conditions => cond) @query.project = @project session[:query] = {:id => @query.id, :project_id => @query.project_id} + sort_clear else if params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil) # Give it a name, required to be valid diff --git a/app/helpers/sort_helper.rb b/app/helpers/sort_helper.rb index d4d8f721..7b7fbc8a 100644 --- a/app/helpers/sort_helper.rb +++ b/app/helpers/sort_helper.rb @@ -69,6 +69,11 @@ module SortHelper normalize! end + def criteria=(arg) + @criteria = arg + normalize! + end + def to_param @criteria.collect {|k,o| k + (o ? '' : ':desc')}.join(',') end @@ -102,24 +107,42 @@ module SortHelper @criteria.first && @criteria.first.last end + def empty? + @criteria.empty? + end + private def normalize! - @criteria = @criteria.collect {|s| [s.first, (s.last == false || s.last == 'desc') ? false : true]} + @criteria ||= [] + @criteria = @criteria.collect {|s| s = s.to_a; [s.first, (s.last == false || s.last == 'desc') ? false : true]} @criteria = @criteria.select {|k,o| @available_criteria.has_key?(k)} if @available_criteria @criteria.slice!(3) self end end + + def sort_name + controller_name + '_' + action_name + '_sort' + end - # Initializes the default sort column (default_key) and sort order - # (default_order). - # - # - default_key is a column attribute name. - # - default_order is 'asc' or 'desc'. + # Initializes the default sort. + # Examples: + # + # sort_init 'name' + # sort_init 'id', 'desc' + # sort_init ['name', ['id', 'desc']] + # sort_init [['name', 'desc'], ['id', 'desc']] # - def sort_init(default_key, default_order='asc') - @sort_default = "#{default_key}:#{default_order}" + def sort_init(*args) + case args.size + when 1 + @sort_default = args.first.is_a?(Array) ? args.first : [[args.first]] + when 2 + @sort_default = [[args.first, args.last]] + else + raise ArgumentError + end end # Updates the sort state. Call this in the controller prior to calling @@ -127,13 +150,18 @@ module SortHelper # - criteria can be either an array or a hash of allowed keys # def sort_update(criteria) - sort_name = controller_name + '_' + action_name + '_sort' - @sort_criteria = SortCriteria.new @sort_criteria.available_criteria = criteria - @sort_criteria.from_param(params[:sort] || session[sort_name] || @sort_default) + @sort_criteria.from_param(params[:sort] || session[sort_name]) + @sort_criteria.criteria = @sort_default if @sort_criteria.empty? session[sort_name] = @sort_criteria.to_param end + + # Clears the sort criteria session data + # + def sort_clear + session[sort_name] = nil + end # Returns an SQL sort clause corresponding to the current sort state. # Use this to sort the controller's table items collection. @@ -188,13 +216,6 @@ module SortHelper # # <%= sort_header_tag('id', :title => 'Sort by contact ID', :width => 40) %> # - # Renders: - # - # - # Id - #   Sort_asc - # - # def sort_header_tag(column, options = {}) caption = options.delete(:caption) || column.to_s.humanize default_order = options.delete(:default_order) || 'asc' diff --git a/app/models/query.rb b/app/models/query.rb index 5c9fad5e..99ebb757 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -28,6 +28,11 @@ class QueryColumn def caption l("field_#{name}") end + + # Returns true if the column is sortable, otherwise false + def sortable? + !sortable.nil? + end end class QueryCustomFieldColumn < QueryColumn @@ -52,6 +57,7 @@ class Query < ActiveRecord::Base belongs_to :user serialize :filters serialize :column_names + serialize :sort_criteria, Array attr_protected :project_id, :user_id @@ -261,6 +267,27 @@ class Query < ActiveRecord::Base column_names.nil? || column_names.empty? end + def sort_criteria=(arg) + c = [] + if arg.is_a?(Hash) + arg = arg.keys.sort.collect {|k| arg[k]} + end + c = arg.select {|k,o| !k.to_s.blank?}.slice(0,3).collect {|k,o| [k.to_s, o == 'desc' ? o : 'asc']} + write_attribute(:sort_criteria, c) + end + + def sort_criteria + read_attribute(:sort_criteria) || [] + end + + def sort_criteria_key(arg) + sort_criteria && sort_criteria[arg] && sort_criteria[arg].first + end + + def sort_criteria_order(arg) + sort_criteria && sort_criteria[arg] && sort_criteria[arg].last + end + def project_statement project_clauses = [] if project && !@project.descendants.active.empty? diff --git a/app/views/queries/_form.rhtml b/app/views/queries/_form.rhtml index 8da26403..7c227a9f 100644 --- a/app/views/queries/_form.rhtml +++ b/app/views/queries/_form.rhtml @@ -25,5 +25,14 @@ <%= render :partial => 'queries/filters', :locals => {:query => query}%> +
<%= l(:label_sort) %> +<% 3.times do |i| %> +<%= i+1 %>: <%= select_tag("query[sort_criteria][#{i}][]", + options_for_select([[]] + query.available_columns.select(&:sortable?).collect {|column| [column.caption, column.name.to_s]}, @query.sort_criteria_key(i))) %> + <%= select_tag("query[sort_criteria][#{i}][]", + options_for_select([[], [l(:label_ascending), 'asc'], [l(:label_descending), 'desc']], @query.sort_criteria_order(i))) %>
+<% end %> +
+ <%= render :partial => 'queries/columns', :locals => {:query => query}%> diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 0a6bca01..0179cb26 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -778,3 +778,6 @@ bg: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 15cca4e0..e62a936d 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -779,3 +779,6 @@ ca: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 0795b078..57775853 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -783,3 +783,6 @@ cs: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/da.yml b/config/locales/da.yml index e27c4a05..76323520 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -811,3 +811,6 @@ da: setting_per_page_options: Objects per page options mail_body_reminder: "{{count}} issue(s) that are assigned to you are due in the next {{days}} days:" field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/de.yml b/config/locales/de.yml index 44329474..95a6f6c3 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -810,3 +810,6 @@ de: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/en.yml b/config/locales/en.yml index 47dcc0e4..e0cce3cb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -662,6 +662,9 @@ en: label_issue_watchers: Watchers label_example: Example label_display: Display + label_sort: Sort + label_ascending: Ascending + label_descending: Descending button_login: Login button_submit: Submit diff --git a/config/locales/es.yml b/config/locales/es.yml index 78f3bbd5..259d2948 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -831,3 +831,6 @@ es: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/fi.yml b/config/locales/fi.yml index d9f3c03d..1ae6bc75 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -821,3 +821,6 @@ fi: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 9af234cc..72a1023a 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -694,6 +694,9 @@ fr: label_issue_watchers: Observateurs label_example: Exemple label_display: Affichage + label_sort: Tri + label_ascending: Croissant + label_descending: Décroissant button_login: Connexion button_submit: Soumettre diff --git a/config/locales/gl.yml b/config/locales/gl.yml index d1544888..65f37de8 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -810,3 +810,6 @@ gl: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/he.yml b/config/locales/he.yml index 661fca90..e674cc16 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -793,3 +793,6 @@ he: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/hu.yml b/config/locales/hu.yml index a1456c3a..d1fe5a04 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -816,3 +816,6 @@ field_identity_url: OpenID URL label_login_with_open_id_option: bejelentkezés OpenID használatával field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/it.yml b/config/locales/it.yml index f0c008f8..d10084ce 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -796,3 +796,6 @@ it: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 3753bb3e..c82074b0 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -809,3 +809,6 @@ ja: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/ko.yml b/config/locales/ko.yml index c60744f9..30d04324 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -840,3 +840,6 @@ ko: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 09bf3fe7..a8bea412 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -821,3 +821,6 @@ lt: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 644d6f93..89e9b834 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -766,3 +766,6 @@ nl: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/no.yml b/config/locales/no.yml index f0da35ce..1b670ad6 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -783,3 +783,6 @@ field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 595705d5..6f263aaf 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -814,3 +814,6 @@ pl: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 861881df..daeeb9fd 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -816,3 +816,6 @@ pt-BR: field_identity_url: OpenID URL label_login_with_open_id_option: ou use o OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 4f248edd..fb444797 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -802,3 +802,6 @@ pt: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/ro.yml b/config/locales/ro.yml index 3e2214d6..30fbc3a9 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -823,3 +823,6 @@ ro: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/ru.yml b/config/locales/ru.yml index c9788c37..fcb62b35 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -909,3 +909,6 @@ ru: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/sk.yml b/config/locales/sk.yml index b0ff847a..fb75161f 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -782,3 +782,6 @@ sk: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 98c8995e..249e47fb 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -780,3 +780,6 @@ sl: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 80a29067..a4b66a05 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -804,3 +804,6 @@ field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 9b5adcd4..0ed8e8d2 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -838,3 +838,6 @@ sv: enumeration_doc_categories: Dokumentkategorier enumeration_activities: Aktiviteter (tidsuppföljning) field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/th.yml b/config/locales/th.yml index 06d46c5a..147c59bf 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -781,3 +781,6 @@ th: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/tr.yml b/config/locales/tr.yml index d240cae3..de461194 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -817,3 +817,6 @@ tr: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 08ca568a..4eda5113 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -780,3 +780,6 @@ uk: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 375f03b5..decba375 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -850,3 +850,6 @@ vi: field_identity_url: OpenID URL label_login_with_open_id_option: or login with OpenID field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 1b9387b2..f1cd072f 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -888,3 +888,6 @@ enumeration_doc_categories: 文件分類 enumeration_activities: 活動 (時間追蹤) field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/config/locales/zh.yml b/config/locales/zh.yml index dd7de569..ee6671a2 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -813,3 +813,6 @@ zh: enumeration_doc_categories: 文档类别 enumeration_activities: 活动(时间跟踪) field_content: Content + label_descending: Descending + label_sort: Sort + label_ascending: Ascending diff --git a/db/migrate/20090312172426_add_queries_sort_criteria.rb b/db/migrate/20090312172426_add_queries_sort_criteria.rb new file mode 100644 index 00000000..743ed42f --- /dev/null +++ b/db/migrate/20090312172426_add_queries_sort_criteria.rb @@ -0,0 +1,9 @@ +class AddQueriesSortCriteria < ActiveRecord::Migration + def self.up + add_column :queries, :sort_criteria, :text + end + + def self.down + remove_column :queries, :sort_criteria + end +end diff --git a/test/fixtures/queries.yml b/test/fixtures/queries.yml index f1202272..a274ce35 100644 --- a/test/fixtures/queries.yml +++ b/test/fixtures/queries.yml @@ -67,3 +67,23 @@ queries_004: user_id: 2 column_names: +queries_005: + id: 5 + project_id: + is_public: true + name: Open issues by priority and tracker + filters: | + status_id: + :values: + - "1" + :operator: o + + user_id: 1 + column_names: + sort_criteria: | + --- + - - priority + - desc + - - tracker + - asc + \ No newline at end of file diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index de08b424..1951aff8 100644 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -111,6 +111,22 @@ class QueriesControllerTest < Test::Unit::TestCase assert q.valid? end + def test_new_with_sort + @request.session[:user_id] = 1 + post :new, + :confirm => '1', + :default_columns => '1', + :operators => {"status_id" => "o"}, + :values => {"status_id" => ["1"]}, + :query => {:name => "test_new_with_sort", + :is_public => "1", + :sort_criteria => {"0" => ["due_date", "desc"], "1" => ["tracker", ""]}} + + query = Query.find_by_name("test_new_with_sort") + assert_not_nil query + assert_equal [['due_date', 'desc'], ['tracker', 'asc']], query.sort_criteria + end + def test_get_edit_global_public_query @request.session[:user_id] = 1 get :edit, :id => 4 @@ -202,6 +218,19 @@ class QueriesControllerTest < Test::Unit::TestCase :disabled => 'disabled' } end + def test_get_edit_sort_criteria + @request.session[:user_id] = 1 + get :edit, :id => 5 + assert_response :success + assert_template 'edit' + assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' }, + :child => { :tag => 'option', :attributes => { :value => 'priority', + :selected => 'selected' } } + assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' }, + :child => { :tag => 'option', :attributes => { :value => 'desc', + :selected => 'selected' } } + end + def test_destroy @request.session[:user_id] = 2 post :destroy, :id => 1 diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index d568604c..80112b77 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -195,6 +195,31 @@ class QueryTest < Test::Unit::TestCase assert q.has_column?(c) end + def test_default_sort + q = Query.new + assert_equal [], q.sort_criteria + end + + def test_set_sort_criteria_with_hash + q = Query.new + q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']} + assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria + end + + def test_set_sort_criteria_with_array + q = Query.new + q.sort_criteria = [['priority', 'desc'], 'tracker'] + assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria + end + + def test_create_query_with_sort + q = Query.new(:name => 'Sorted') + q.sort_criteria = [['priority', 'desc'], 'tracker'] + assert q.save + q.reload + assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria + end + def test_sort_by_string_custom_field_asc q = Query.new c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' } -- 2.11.0