Project

General

Profile

Defect #28033 » 28033.patch

Yuichi HARADA, 2022-01-14 03:19

View differences:

app/controllers/queries_controller.rb
20 20
class QueriesController < ApplicationController
21 21
  menu_item :issues
22 22
  before_action :find_query, :only => [:edit, :update, :destroy]
23
  before_action :find_optional_project, :only => [:new, :create]
23
  before_action :find_optional_project, :only => [:new, :create, :edit, :update]
24 24

  
25 25
  accept_api_auth :index
26 26

  
......
121 121
  end
122 122

  
123 123
  def update_query_from_params
124
    @query.project = params[:query_is_for_all] ? nil : @project
124
    @query.project = (params[:query] && params[:query][:project_id].present?) ? Project.find(params[:query][:project_id]) : nil
125 125
    @query.build_from_params(params)
126 126
    @query.column_names = nil if params[:default_columns]
127 127
    @query.sort_criteria = (params[:query] && params[:query][:sort_criteria]) || @query.sort_criteria
app/views/calendars/show.html.erb
33 33
                         :class => 'icon icon-save' %>
34 34
  <% end %>
35 35
  <% if !@query.new_record? && @query.editable_by?(User.current) %>
36
    <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :calendar => 1), :class => 'icon icon-edit' %>
36
    <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :calendar => 1, :project_id => @project&.identifier), :class => 'icon icon-edit' %>
37 37
    <%= delete_link query_path(@query, :calendar => 1), {}, l(:button_delete_object, object_name: l(:label_query).downcase) %>
38 38
  <% end %>
39 39
</p>
app/views/gantts/show.html.erb
96 96
                         :class => 'icon icon-save' %>
97 97
  <% end %>
98 98
<% if !@query.new_record? && @query.editable_by?(User.current) %>
99
  <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :gantt => 1), :class => 'icon icon-edit' %>
99
  <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :gantt => 1, :project_id => @project&.identifier), :class => 'icon icon-edit' %>
100 100
  <%= delete_link query_path(@query, :gantt => 1), {}, l(:button_delete_object, object_name: l(:label_query).downcase) %>
101 101
<% end %>
102 102
</p>
app/views/queries/_form.html.erb
24 24
<% end %>
25 25

  
26 26
<% unless @query.type == 'ProjectQuery' %>
27
  <p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label>
28
  <%= check_box_tag 'query_is_for_all', 1, @query.project.nil?, :class => (User.current.admin? ? '' : 'disable-unless-private') %></p>
27
  <p><label><%=l(:field_project)%></label>
28
    <%= radio_button_tag 'query[project_id]', '', @query.project.nil?, id: nil, class: ('disable-unless-private' unless User.current.admin?) %> <%= l(:field_is_for_all) %>
29
  <% if @project %>
30
    <%= radio_button_tag 'query[project_id]', @project.identifier, !@query.project.nil?, id: nil %> <%= @project.name %>
31
  <% end%>
32
  </p>
29 33
<% end %>
30 34

  
31 35
<% unless params[:calendar] %>
......
105 109
    var roles_checked = $('#query_visibility_1').is(':checked');
106 110
    var private_checked = $('#query_visibility_0').is(':checked');
107 111
    $("input[name='query[role_ids][]'][type=checkbox]").attr('disabled', !roles_checked);
108
    if (!private_checked) $("input.disable-unless-private").attr('checked', false);
109
    $("input.disable-unless-private").attr('disabled', !private_checked);
112
    if($("input.disable-unless-private").length){
113
      if (!private_checked) $("input[name='query[project_id]']:not([value=''])").prop('checked', true);
114
      $("input.disable-unless-private").attr('disabled', !private_checked);
115
    }
110 116
  }).trigger('change');
111 117
});
112 118

  
app/views/queries/_query_form.html.erb
63 63
    <% end %>
64 64
  <% else %>
65 65
    <% if @query.editable_by?(User.current) %>
66
      <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query), :class => 'icon icon-edit' %>
66
      <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, project_id: @project&.identifier), :class => 'icon icon-edit' %>
67 67
      <%= delete_link query_path(@query), {}, l(:button_delete_object, object_name: l(:label_query).downcase) %>
68 68
    <% end %>
69 69
  <% end %>
app/views/queries/edit.html.erb
1 1
<h2><%= l(:label_query) %></h2>
2 2

  
3
<%= form_tag(query_path(@query), :method => :put, :id => "query-form") do %>
3
<%= form_tag(query_path(@query, project_id: @project&.identifier), :method => :put, :id => "query-form") do %>
4 4
  <%= render :partial => 'form', :locals => {:query => @query} %>
5 5
  <%= submit_tag l(:button_save) %>
6 6
<% end %>
test/functional/queries_controller_test.rb
43 43
    assert_response :success
44 44

  
45 45
    assert_select 'input[name=?][value="0"][checked=checked]', 'query[visibility]'
46
    assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked]):not([disabled])'
46
    assert_select 'input[name=?][type=radio]', 'query[project_id]', 2 do
47
      assert_select '[value=""][class="disable-unless-private"]:not([checked])'
48
      assert_select '[value="ecookbook"][checked]'
49
    end
47 50
    assert_select 'select[name=?]', 'c[]' do
48 51
      assert_select 'option[value=tracker]'
49 52
      assert_select 'option[value=subject]'
......
56 59
    assert_response :success
57 60

  
58 61
    assert_select 'input[name=?]', 'query[visibility]', 0
59
    assert_select 'input[name=query_is_for_all][type=checkbox][checked]:not([disabled])'
62
    assert_select 'input[name=?][type=radio]', 'query[project_id]', 1 do
63
      assert_select '[value=""][class="disable-unless-private"][checked]'
64
    end
60 65
  end
61 66

  
62 67
  def test_new_on_invalid_project
......
84 89
    get(:new, :params => {:project_id => 1, :type => 'TimeEntryQuery'})
85 90
    assert_response :success
86 91
    assert_select 'input[name=type][value=?]', 'TimeEntryQuery'
92
    assert_select 'input[name=?][type=radio]', 'query[project_id]', 2 do
93
      assert_select '[value=""][class="disable-unless-private"]:not([checked])'
94
      assert_select '[value="ecookbook"][checked]'
95
    end
87 96
    assert_select 'p[class=?]', 'totable_columns', 1
88 97
    assert_select 'p[class=?]', 'block_columns', 0
89 98
  end
......
93 102
    get(:new, :params => {:type => 'ProjectQuery'})
94 103
    assert_response :success
95 104
    assert_select 'input[name=type][value=?]', 'ProjectQuery'
105
    assert_select 'input[name=?]', 'query[project_id]', 0
96 106
  end
97 107

  
98 108
  def test_new_project_query_should_not_render_roles_visibility_options
......
104 114
    assert_select 'input[id=?]', 'query_visibility_1', 0
105 115
  end
106 116

  
107
  def test_new_project_query_should_not_render_for_all_projects_option
108
    @request.session[:user_id] = 1
109
    get(:new, :params => {:type => 'ProjectQuery'})
110
    assert_response :success
111
    assert_select 'input[name=?]', 'for_all_projects', 0
112
  end
113

  
114 117
  def test_new_time_entry_query_should_select_spent_time_from_main_menu
115 118
    @request.session[:user_id] = 2
116 119
    get(
......
147 150
    assert_select 'fieldset#filters'
148 151
    assert_select 'fieldset legend', {:text => 'Sort', :count => 0}
149 152
    assert_select 'fieldset#columns'
153
    assert_select 'input[name=?]', 'query[project_id]'
150 154
  end
151 155

  
152 156
  def test_new_with_calendar_params
......
159 163
    assert_select 'fieldset#filters'
160 164
    assert_select 'fieldset legend', {:text => 'Sort', :count => 0}
161 165
    assert_select 'fieldset#columns', :count => 0
166
    assert_select 'input[name=?]', 'query[project_id]'
162 167
  end
163 168

  
164 169
  def test_new_without_gantt_and_calendar_params
......
187 192
          "assigned_to_id" => ["1"], "status_id" => ["1"]
188 193
        },
189 194
        :query => {
190
          "name" => "test_new_project_public_query", "visibility" => "2"
195
          "name" => "test_new_project_public_query", "visibility" => "2", "project_id" => "ecookbook"
191 196
        }
192 197
      }
193 198
    )
......
241 246
        :query => {
242 247
          "name" => "test_create_project_roles_query",
243 248
          "visibility" => "1",
244
          "role_ids" => ["1", "2", ""]
249
          "role_ids" => ["1", "2", ""],
250
          "project_id" => "ecookbook"
245 251
        }
246 252
      }
247 253
    )
......
441 447
        :params => {
442 448
          :project_id => 'ecookbook',
443 449
          :query => {
444
            "name" => "name", "visibility" => "2"
450
            "name" => "name", "visibility" => "2", "project_id" => "ecookbook"
445 451
          }
446 452
        }
447 453
      )
......
458 464
        :create,
459 465
        :params => {
460 466
          :project_id => 'ecookbook',
461
          :query_is_for_all => '1',
462 467
          :query => {
463
            "name" => "name", "visibility" => "2"
468
            "name" => "name", "visibility" => "2", "project_id" => ""
464 469
          }
465 470
        }
466 471
      )
......
478 483
        :params => {
479 484
          :project_id => 'ecookbook',
480 485
          :query => {
481
            "name" => "name", "visibility" => "2"
486
            "name" => "name", "visibility" => "2", "project_id" => "ecookbook"
482 487
          }
483 488
        }
484 489
      )
......
495 500
        :create,
496 501
        :params => {
497 502
          :project_id => 'ecookbook',
498
          :query_is_for_all => '1',
499 503
          :query => {
500
            "name" => "name", "visibility" => "2"
504
            "name" => "name", "visibility" => "2", "project_id" => ""
501 505
          }
502 506
        }
503 507
      )
......
514 518
        :create,
515 519
        :params => {
516 520
          :project_id => 'ecookbook',
517
          :query_is_for_all => '1',
518 521
          :query => {
519
            "name" => "name", "visibility" => "2"
522
            "name" => "name", "visibility" => "2", "project_id" => ""
520 523
          }
521 524
        }
522 525
      )
......
544 547
            "spent_on" => ["2016-07-14"]
545 548
          },
546 549
          :query => {
547
            "name" => "test_new_project_public_query", "visibility" => "2"
550
            "name" => "test_new_project_public_query", "visibility" => "2", "project_id" => "ecookbook"
548 551
          }
549 552
        }
550 553
      )
......
591 594
    assert_response :success
592 595

  
593 596
    assert_select 'input[name=?][value="2"][checked=checked]', 'query[visibility]'
594
    assert_select 'input[name=query_is_for_all][type=checkbox][checked=checked]'
597
    assert_select 'input[name=?][type=radio]', 'query[project_id]', 1 do
598
      assert_select '[value=""][checked]:not([class="disable-unless-private"])'
599
    end
595 600
  end
596 601

  
597 602
  def test_edit_global_private_query
......
600 605
    assert_response :success
601 606

  
602 607
    assert_select 'input[name=?]', 'query[visibility]', 0
603
    assert_select 'input[name=query_is_for_all][type=checkbox][checked=checked]'
608
    assert_select 'input[name=?][type=radio]', 'query[project_id]', 1 do
609
      assert_select '[value=""][class="disable-unless-private"][checked]'
610
    end
604 611
  end
605 612

  
606 613
  def test_edit_project_private_query
607 614
    @request.session[:user_id] = 3
608
    get(:edit, :params => {:id => 2})
615
    get(:edit, :params => {:id => 2, :project_id => 'ecookbook'})
609 616
    assert_response :success
610 617

  
611 618
    assert_select 'input[name=?]', 'query[visibility]', 0
612
    assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked])'
619
    assert_select 'input[name=?][type=radio]', 'query[project_id]', 2 do
620
      assert_select '[value=""][class="disable-unless-private"]:not([checked])'
621
      assert_select '[value="ecookbook"][checked]'
622
    end
613 623
  end
614 624

  
615 625
  def test_edit_project_public_query
616 626
    @request.session[:user_id] = 2
617
    get(:edit, :params => {:id => 1})
627
    get(:edit, :params => {:id => 1, :project_id => 'ecookbook'})
618 628
    assert_response :success
619 629

  
620 630
    assert_select 'input[name=?][value="2"][checked=checked]', 'query[visibility]'
621
    assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked])'
631
    assert_select 'input[name=?][type=radio]', 'query[project_id]', 2 do
632
      assert_select '[value=""][class="disable-unless-private"]:not([checked])'
633
      assert_select '[value="ecookbook"][checked]'
634
    end
622 635
  end
623 636

  
624 637
  def test_edit_sort_criteria
......
653 666
          "assigned_to_id" => ["me"], "status_id" => ["1"]
654 667
        },
655 668
        :query => {
656
          "name" => "test_edit_global_private_query", "visibility" => "2"
669
          "name" => "test_edit_global_private_query", "visibility" => "2", "project_id" => ""
657 670
        }
658 671
      }
659 672
    )
......
661 674
    q = Query.find_by_name('test_edit_global_private_query')
662 675
    assert !q.is_public?
663 676
    assert q.has_default_columns?
677
    assert_nil q.project
664 678
    assert q.valid?
665 679
  end
666 680

  
......
679 693
          "assigned_to_id" => ["1"], "status_id" => ["1"]
680 694
        },
681 695
        :query => {
682
          "name" => "test_edit_global_public_query", "visibility" => "2"
696
          "name" => "test_edit_global_public_query", "visibility" => "2", "project_id" => ""
683 697
        }
684 698
      }
685 699
    )
......
687 701
    q = Query.find_by_name('test_edit_global_public_query')
688 702
    assert q.is_public?
689 703
    assert q.has_default_columns?
704
    assert_nil q.project
690 705
    assert q.valid?
691 706
  end
692 707

  
708
  def test_update_global_private_query_when_change_global_to_project_should_set_project
709
    assert_nil Query.find_by_name('test_edit_global_private_query')
710
    @request.session[:user_id] = 3
711
    put(
712
      :update,
713
      :params => {
714
        :id => 3,
715
        :project_id => 'ecookbook',
716
        :query => {
717
          "name" => "test_edit_global_private_query", "visibility" => "0", "project_id" => "ecookbook"
718
        }
719
      }
720
    )
721
    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => 3
722
    q = Query.find_by_name('test_edit_global_private_query')
723
    assert !q.is_global?
724
    assert q.project
725
  end
726

  
727
  def test_update_project_private_query_when_change_project_to_global_should_not_set_project
728
    assert_nil Query.find_by_name('test_edit_project_private_query')
729
    @request.session[:user_id] = 3
730
    put(
731
      :update,
732
      :params => {
733
        :id => 2,
734
        :project_id => 'ecookbook',
735
        :query => {
736
          "name" => "test_edit_project_private_query", "visibility" => "0", "project_id" => ""
737
        }
738
      }
739
    )
740
    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => 2
741
    q = Query.find_by_name('test_edit_project_private_query')
742
    assert q.is_global?
743
    assert_nil q.project
744
  end
745

  
693 746
  def test_update_with_failure
694 747
    @request.session[:user_id] = 1
695 748
    put(
(3-3/4)