make_id_column_configurable_v3.patch

Marius BALTEANU, 2016-08-22 11:20

Download (21 KB)

View differences:

app/models/issue_query.rb
21 21
  self.view_permission = :view_issues
22 22

  
23 23
  self.available_columns = [
24
    QueryColumn.new(:id, :sortable => "#{Issue.table_name}.id", :default_order => 'desc', :caption => '#', :frozen => true),
24
    QueryColumn.new(:id, :sortable => "#{Issue.table_name}.id", :default_order => 'desc', :caption => '#'),
25 25
    QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
26 26
    QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
27 27
    QueryColumn.new(:parent, :sortable => ["#{Issue.table_name}.root_id", "#{Issue.table_name}.lft ASC"], :default_order => 'desc', :caption => :field_parent_issue),
config/settings.yml
191 191
issue_list_default_columns:
192 192
  serialized: true
193 193
  default:
194
  - id
194 195
  - tracker
195 196
  - status
196 197
  - priority
db/migrate/20160712091212_add_id_to_default_issue_list_columns.rb
1
class AddIdToDefaultIssueListColumns < ActiveRecord::Migration
2
  def self.up
3
    columns = Setting.issue_list_default_columns
4
    return if columns.include?("id")
5

  
6
    columns.unshift "id"
7
    Setting.set_from_params("issue_list_default_columns", columns)
8
  end
9
  def down
10
    columns = Setting.issue_list_default_columns
11
    return unless columns.include?("id")
12

  
13
    columns -= ["id"]
14
    Setting.set_from_params("issue_list_default_columns", columns)
15
  end
16
end
test/functional/issues_controller_test.rb
217 217
      :f => [filter_name],
218 218
      :op => {filter_name => '='},
219 219
      :v => {filter_name => ['Foo']},
220
      :c => ['project']
220
      :c => ['id', 'project']
221 221
    assert_response :success
222 222

  
223 223
    assert_equal [3, 5], issues_in_list.map(&:project_id).uniq.sort
......
455 455
    assert_response :success
456 456

  
457 457
    assert_equal 'text/csv; header=present', @response.content_type
458
    assert response.body.starts_with?("#,")
458
    assert response.body.starts_with?("Project,")
459 459
    lines = response.body.chomp.split("\n")
460
    # default columns + id and project
461
    assert_equal Setting.issue_list_default_columns.size + 2, lines[0].split(',').size
460
    # default columns + project
461
    assert_equal Setting.issue_list_default_columns.size + 1, lines[0].split(',').size
462 462
  end
463 463

  
464 464
  def test_index_csv_with_project
......
495 495
    issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
496 496
    TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
497 497

  
498
    get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
498
    get :index, :format => 'csv', :set_filter => '1', :c => %w(id subject spent_hours)
499 499
    assert_response :success
500 500
    assert_equal 'text/csv; header=present', @response.content_type
501 501
    lines = @response.body.chomp.split("\n")
......
549 549
    child = Issue.generate!(:parent_issue_id => parent.id)
550 550

  
551 551
    with_settings :default_language => 'en' do
552
      get :index, :format => 'csv', :c => %w(parent)
552
      get :index, :format => 'csv', :c => %w(id parent)
553 553
    end
554 554
    lines = response.body.split("\n")
555 555
    assert_include "#{child.id},#{parent.id}", lines
......
561 561
      str_big5  = "\xa4@\xa4\xeb".force_encoding('Big5')
562 562
      issue = Issue.generate!(:subject => str_utf8)
563 563

  
564
      get :index, :project_id => 1, 
565
                  :f => ['subject'], 
564
      get :index, :project_id => 1,
565
                  :f => ['subject'],
566 566
                  :op => '=', :values => [str_utf8],
567 567
                  :format => 'csv'
568 568
      assert_equal 'text/csv; header=present', @response.content_type
......
580 580
      str_utf8  = "\xe4\xbb\xa5\xe5\x86\x85".force_encoding('UTF-8')
581 581
      issue = Issue.generate!(:subject => str_utf8)
582 582

  
583
      get :index, :project_id => 1, 
584
                  :f => ['subject'], 
583
      get :index, :project_id => 1,
584
                  :f => ['subject'],
585 585
                  :op => '=', :values => [str_utf8],
586
                  :c => ['status', 'subject'],
586
                  :c => ['id', 'status', 'subject'],
587 587
                  :format => 'csv',
588 588
                  :set_filter => 1
589 589
      assert_equal 'text/csv; header=present', @response.content_type
......
603 603
      str1  = "test_index_csv_tw"
604 604
      issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
605 605

  
606
      get :index, :project_id => 1, 
607
                  :f => ['subject'], 
606
      get :index, :project_id => 1,
607
                  :f => ['subject'],
608 608
                  :op => '=', :values => [str1],
609
                  :c => ['estimated_hours', 'subject'],
609
                  :c => ['id', 'estimated_hours', 'subject'],
610 610
                  :format => 'csv',
611 611
                  :set_filter => 1
612 612
      assert_equal 'text/csv; header=present', @response.content_type
......
620 620
      str1  = "test_index_csv_fr"
621 621
      issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
622 622

  
623
      get :index, :project_id => 1, 
624
                  :f => ['subject'], 
623
      get :index, :project_id => 1,
624
                  :f => ['subject'],
625 625
                  :op => '=', :values => [str1],
626
                  :c => ['estimated_hours', 'subject'],
626
                  :c => ['id', 'estimated_hours', 'subject'],
627 627
                  :format => 'csv',
628 628
                  :set_filter => 1
629 629
      assert_equal 'text/csv; header=present', @response.content_type
......
694 694
    Setting.issue_list_default_columns = %w(subject author)
695 695
    get :index, :sort => 'tracker'
696 696
  end
697
  
697

  
698 698
  def test_index_sort_by_assigned_to
699 699
    get :index, :sort => 'assigned_to'
700 700
    assert_response :success
701
    
701

  
702 702
    assignees = issues_in_list.map(&:assigned_to).compact
703 703
    assert_equal assignees.sort, assignees
704 704
    assert_select 'table.issues.sort-by-assigned-to.sort-asc'
705 705
  end
706
  
706

  
707 707
  def test_index_sort_by_assigned_to_desc
708 708
    get :index, :sort => 'assigned_to:desc'
709 709
    assert_response :success
710
    
710

  
711 711
    assignees = issues_in_list.map(&:assigned_to).compact
712 712
    assert_equal assignees.sort.reverse, assignees
713 713
    assert_select 'table.issues.sort-by-assigned-to.sort-desc'
714 714
  end
715
  
715

  
716 716
  def test_index_group_by_assigned_to
717 717
    get :index, :group_by => 'assigned_to', :sort => 'priority'
718 718
    assert_response :success
719 719
  end
720
  
720

  
721 721
  def test_index_sort_by_author
722 722
    get :index, :sort => 'author', :c => ['author']
723 723
    assert_response :success
724
    
724

  
725 725
    authors = issues_in_list.map(&:author)
726 726
    assert_equal authors.sort, authors
727 727
  end
......
729 729
  def test_index_sort_by_author_desc
730 730
    get :index, :sort => 'author:desc'
731 731
    assert_response :success
732
    
732

  
733 733
    authors = issues_in_list.map(&:author)
734 734
    assert_equal authors.sort.reverse, authors
735 735
  end
736
  
736

  
737 737
  def test_index_group_by_author
738 738
    get :index, :group_by => 'author', :sort => 'priority'
739 739
    assert_response :success
740 740
  end
741
  
741

  
742 742
  def test_index_sort_by_spent_hours
743 743
    get :index, :sort => 'spent_hours:desc'
744 744
    assert_response :success
745 745
    hours = issues_in_list.map(&:spent_hours)
746 746
    assert_equal hours.sort.reverse, hours
747 747
  end
748
  
748

  
749 749
  def test_index_sort_by_total_spent_hours
750 750
    get :index, :sort => 'total_spent_hours:desc'
751 751
    assert_response :success
752 752
    hours = issues_in_list.map(&:total_spent_hours)
753 753
    assert_equal hours.sort.reverse, hours
754 754
  end
755
  
755

  
756 756
  def test_index_sort_by_total_estimated_hours
757 757
    get :index, :sort => 'total_estimated_hours:desc'
758 758
    assert_response :success
......
767 767
    CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
768 768
    CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
769 769

  
770
    get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
770
    get :index, :project_id => 1, :c => ["id"], :set_filter => 1, :sort => "cf_#{cf.id},id"
771 771
    assert_response :success
772 772

  
773 773
    assert_equal [2, 3, 1], issues_in_list.select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
......
778 778
    get :index, :set_filter => 1, :c => columns
779 779
    assert_response :success
780 780

  
781
    # query should use specified columns + id and checkbox
782
    assert_select 'table.issues thead th', columns.size + 2
781
    # query should use specified columns + checkbox
782
    assert_select 'table.issues thead th', columns.size + 1
783 783

  
784 784
    # columns should be stored in session
785 785
    assert_kind_of Hash, session[:issue_query]
......
799 799
    get :index, :set_filter => 1
800 800

  
801 801
    # query should use specified columns
802
    assert_equal ["#", "Project", "Tracker", "Subject", "Assignee"], columns_in_issues_list
802
    assert_equal ["Project", "Tracker", "Subject", "Assignee"], columns_in_issues_list
803 803
  end
804 804

  
805 805
  def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
......
816 816
    with_settings :issue_list_default_columns => columns do
817 817
      get :index, :project_id => 1, :set_filter => 1
818 818

  
819
      assert_equal ["#", "Assignee", "Subject", "Status", "Tracker"], columns_in_issues_list
819
      assert_equal ["Assignee", "Subject", "Status", "Tracker"], columns_in_issues_list
820 820
    end
821 821
  end
822 822

  
823 823
  def test_index_with_custom_field_column
824
    columns = %w(tracker subject cf_2)
824
    columns = %w(id tracker subject cf_2)
825 825
    get :index, :set_filter => 1, :c => columns
826 826
    assert_response :success
827 827

  
......
915 915
    IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
916 916
    IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
917 917

  
918
    get :index, :set_filter => 1, :c => %w(subject relations)
918
    get :index, :set_filter => 1, :c => %w(id subject relations)
919 919
    assert_response :success
920 920
    assert_select "tr#issue-1 td.relations" do
921 921
      assert_select "span", 3
......
931 931
      assert_select "span", 0
932 932
    end
933 933

  
934
    get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
934
    get :index, :set_filter => 1, :c => %w(id relations), :format => 'csv'
935 935
    assert_response :success
936 936
    assert_equal 'text/csv; header=present', response.content_type
937 937
    lines = response.body.chomp.split("\n")
......
939 939
    assert_include '2,Blocked by #12', lines
940 940
    assert_include '3,""', lines
941 941

  
942
    get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
942
    get :index, :set_filter => 1, :c => %w(id subject relations), :format => 'pdf'
943 943
    assert_response :success
944 944
    assert_equal 'application/pdf', response.content_type
945 945
  end
......
947 947
  def test_index_with_description_column
948 948
    get :index, :set_filter => 1, :c => %w(subject description)
949 949

  
950
    assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
951
    assert_select 'td.description[colspan="3"]', :text => 'Unable to print recipes'
950
    assert_select 'table.issues thead th', 2 # columns: chekbox subject
951
    assert_select 'td.description[colspan="2"]', :text => 'Unable to print recipes'
952 952

  
953 953
    get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
954 954
    assert_response :success
......
1089 1089
  def test_index_should_not_include_new_issue_tab_for_project_without_trackers
1090 1090
    with_settings :new_item_menu_tab => '1' do
1091 1091
      Project.find(1).trackers.clear
1092
  
1092

  
1093 1093
      @request.session[:user_id] = 2
1094 1094
      get :index, :project_id => 1
1095 1095
      assert_select '#main-menu a.new-issue', 0
......
1101 1101
      role = Role.find(1)
1102 1102
      role.remove_permission! :add_issues
1103 1103
      role.add_permission! :copy_issues
1104
  
1104

  
1105 1105
      @request.session[:user_id] = 2
1106 1106
      get :index, :project_id => 1
1107 1107
      assert_select '#main-menu a.new-issue', 0
......
1377 1377

  
1378 1378
  def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1379 1379
    @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1380
    
1380

  
1381 1381
    %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1382 1382
      @request.session['issues_index_sort'] = assoc_sort
1383 1383

  
......
1610 1610
  end
1611 1611

  
1612 1612
  def test_show_export_to_pdf
1613
    issue = Issue.find(3) 
1613
    issue = Issue.find(3)
1614 1614
    assert issue.relations.select{|r| r.other_issue(issue).visible?}.present?
1615 1615
    get :show, :id => 3, :format => 'pdf'
1616 1616
    assert_response :success
......
2039 2039
    get :new, :project_id => 'invalid'
2040 2040
    assert_response 404
2041 2041
  end
2042
 
2042

  
2043 2043
  def test_new_with_parent_id_should_only_propose_valid_trackers
2044 2044
    @request.session[:user_id] = 2
2045 2045
    t = Tracker.find(3)
......
2588 2588
                              :custom_field_values => {'2' => 'Value for field 2'}}
2589 2589
      end
2590 2590
      assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2591
  
2591

  
2592 2592
      assert_equal 1, ActionMailer::Base.deliveries.size
2593 2593
    end
2594 2594
  end
......
2862 2862
        assert_select 'option[value="1"][selected=selected]', :text => 'eCookbook'
2863 2863
        assert_select 'option[value="2"]:not([selected])', :text => 'OnlineStore'
2864 2864
      end
2865
      assert_select 'input[name=?][value=?]', 'issue[subject]', orig.subject 
2865
      assert_select 'input[name=?][value=?]', 'issue[subject]', orig.subject
2866 2866
      assert_select 'input[name=copy_from][value="1"]'
2867 2867
    end
2868 2868
  end
......
3137 3137
  def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
3138 3138
    @request.session[:user_id] = 2
3139 3139
    Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
3140
    
3140

  
3141 3141
    get :edit, :id => 1
3142 3142
    assert_select 'input[name=?]', 'time_entry[hours]'
3143 3143
  end
......
3145 3145
  def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
3146 3146
    @request.session[:user_id] = 2
3147 3147
    Role.find_by_name('Manager').remove_permission! :log_time
3148
    
3148

  
3149 3149
    get :edit, :id => 1
3150 3150
    assert_select 'input[name=?]', 'time_entry[hours]', 0
3151 3151
  end
......
3790 3790
    assert_response :redirect
3791 3791
    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3792 3792
  end
3793
 
3793

  
3794 3794
  def test_put_update_should_redirect_with_previous_and_next_issue_ids_params
3795 3795
    @request.session[:user_id] = 2
3796 3796

  
......
3844 3844

  
3845 3845
      assert_select 'select[name=?]', 'issue[project_id]'
3846 3846
      assert_select 'input[name=?]', 'issue[parent_issue_id]'
3847
  
3847

  
3848 3848
      # Project specific custom field, date type
3849 3849
      field = CustomField.find(9)
3850 3850
      assert !field.is_for_all?
3851 3851
      assert_equal 'date', field.field_format
3852 3852
      assert_select 'input[name=?]', 'issue[custom_field_values][9]'
3853
  
3853

  
3854 3854
      # System wide custom field
3855 3855
      assert CustomField.find(1).is_for_all?
3856 3856
      assert_select 'select[name=?]', 'issue[custom_field_values][1]'
3857
  
3857

  
3858 3858
      # Be sure we don't display inactive IssuePriorities
3859 3859
      assert ! IssuePriority.find(15).active?
3860 3860
      assert_select 'select[name=?]', 'issue[priority_id]' do
......
4027 4027
                                       :issue => {:priority_id => '',
4028 4028
                                                  :assigned_to_id => group.id,
4029 4029
                                                  :custom_field_values => {'2' => ''}}
4030
  
4030

  
4031 4031
      assert_response 302
4032 4032
      assert_equal [group, group], Issue.where(:id => [1, 2]).collect {|i| i.assigned_to}
4033 4033
    end
......
4333 4333
      assert_select 'option[value="2"]'
4334 4334
    end
4335 4335
  end
4336
  
4336

  
4337 4337
  def test_bulk_copy_to_another_project
4338 4338
    @request.session[:user_id] = 2
4339 4339
    assert_difference 'Issue.count', 2 do
......
4386 4386
                    :assigned_to_id => 3)
4387 4387
    ]
4388 4388
    assert_difference 'Issue.count', issues.size do
4389
      post :bulk_update, :ids => issues.map(&:id), :copy => '1', 
4389
      post :bulk_update, :ids => issues.map(&:id), :copy => '1',
4390 4390
           :issue => {
4391 4391
             :project_id => '', :tracker_id => '', :assigned_to_id => '',
4392 4392
             :status_id => '', :start_date => '', :due_date => ''
......
4414 4414
    @request.session[:user_id] = 2
4415 4415
    assert_difference 'Issue.count', 2 do
4416 4416
      assert_no_difference 'Project.find(1).issues.count' do
4417
        post :bulk_update, :ids => [1, 2], :copy => '1', 
4417
        post :bulk_update, :ids => [1, 2], :copy => '1',
4418 4418
             :issue => {
4419 4419
               :project_id => '2', :tracker_id => '', :assigned_to_id => '2',
4420 4420
               :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
test/functional/issues_custom_fields_visibility_test.rb
206 206
    Issue.generate!(:project => p1, :tracker_id => 1, :custom_field_values => {@field2.id => 'ValueC'})
207 207

  
208 208
    @request.session[:user_id] = user.id
209
    get :index, :c => ["subject", "cf_#{@field2.id}"]
209
    get :index, :c => ["id", "subject", "cf_#{@field2.id}"]
210 210
    assert_select 'td', :text => 'ValueA'
211 211
    assert_select 'td', :text => 'ValueB', :count => 0
212 212
    assert_select 'td', :text => 'ValueC'
test/functional/queries_controller_test.rb
122 122
         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
123 123
         :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
124 124
         :query => {"name" => "test_new_global_private_query", "visibility" => "0"},
125
         :c => ["", "tracker", "subject", "priority", "category"]
125
         :c => ["", "id", "tracker", "subject", "priority", "category"]
126 126

  
127 127
    q = Query.find_by_name('test_new_global_private_query')
128 128
    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
test/unit/query_test.rb
1037 1037

  
1038 1038
  def test_set_column_names
1039 1039
    q = IssueQuery.new
1040
    q.column_names = ['tracker', :subject, '', 'unknonw_column']
1040
    q.column_names = ['id', 'tracker', :subject, '', 'unknonw_column']
1041 1041
    assert_equal [:id, :tracker, :subject], q.columns.collect {|c| c.name}
1042 1042
  end
1043 1043

  
......
1063 1063

  
1064 1064
  def test_inline_and_block_columns
1065 1065
    q = IssueQuery.new
1066
    q.column_names = ['subject', 'description', 'tracker']
1066
    q.column_names = ['id', 'subject', 'description', 'tracker']
1067 1067

  
1068 1068
    assert_equal [:id, :subject, :tracker], q.inline_columns.map(&:name)
1069 1069
    assert_equal [:description], q.block_columns.map(&:name)