Project

General

Profile

Feature #31322 » 20200609-collapse.diff

Toshi MARUYAMA, 2020-06-09 10:43

View differences:

app/controllers/issues_controller.rb
181 181
  end
182 182

  
183 183
  def update
184
    if request.xhr?
185
      if params[:check_go_to_close_confirm]
186
        result = true
187
        status = nil
188
        status_id = params[:status_id].to_i
189
        can_close_all_descendants = true
190
        if status_id <= 0
191
          result = false
192
        else
193
          status = IssueStatus.find(status_id)
194
          if !status.is_closed
195
            result = false
196
          else
197
            opened_descendants = []
198
            @issue.descendants.open.sort_by(&:lft).each do |issue|
199
              unless issue.visible?
200
                can_close_all_descendants = false
201
                break
202
              end
203

  
204
              unless issue.new_statuses_allowed_to.map{|i| i.id}.include?(status.id)
205
                can_close_all_descendants = false
206
                break
207
              end
208

  
209
              opened_descendants << issue
210
            end
211
            if can_close_all_descendants && opened_descendants.empty?
212
              result = false
213
              can_close_all_descendants = false
214
            end
215
          end
216
          if result
217
            session[:can_close_descendant] = {}
218
            session[:can_close_descendant][:can_close_all] = can_close_all_descendants
219
            if can_close_all_descendants
220
              session[:can_close_descendant][:status_id] = status.id
221
              session[:can_close_descendant][:status_name] = status.name
222
              session[:can_close_descendant][:ids] = opened_descendants.map{|i| i.id}
223
            end
224
          end
225
        end
226
        render :json => {:result => result}
227
        return
228
      end
229

  
230
      if !session.has_key?(:can_close_descendant)
231
        return
232
      end
233

  
234
      render_data = {
235
        :status_name => session[:can_close_descendant][:status_name],
236
        :can_close_all => session[:can_close_descendant][:can_close_all]
237
      }
238
      render(
239
        :partial => 'close_confirm',
240
        :layout => false,
241
        :locals => render_data
242
      )
243
      return
244
    end
245

  
184 246
    return unless update_issue_from_params
185 247

  
186 248
    @issue.save_attachments(params[:attachments] ||
......
200 262

  
201 263
    if saved
202 264
      render_attachment_warning_if_needed(@issue)
265
      if params[:close_descendants] && session.has_key?(:can_close_descendant)
266
        close_descendant_ids = session[:can_close_descendant][:ids]
267
        session.delete(:can_close_descendant)
268
        close_descendant_ids.each do |id|
269
          issue = Issue.find(id)
270
          issue.init_journal(User.current, params[:issue][:notes])
271
          issue.safe_attributes = {'status_id' => params[:issue][:status_id].to_i}
272
          issue.save
273
        end
274
      end
275

  
203 276
      unless @issue.current_journal.new_record? || params[:no_flash]
204 277
        flash[:notice] = l(:notice_successful_update)
205 278
      end
app/views/issues/_close_confirm.js.erb
1
$('#ajax-modal').html(
2
  '<%= escape_javascript(
3
         render(
4
           :partial => 'close_confirm_dialog',
5
           :locals  => {
6
             :status_name => status_name,
7
             :can_close_all => can_close_all
8
           }
9
         )
10
       )
11
   %>'
12
);
13
showModal('ajax-modal', '400px');
app/views/issues/_close_confirm_dialog.html.erb
1
<h3 class="title">&nbsp;</h3>
2
<% if can_close_all %>
3
  <p>
4
    <%= l(:text_close_parent_issue_and_open_subtasks,
5
          :issue_id => params[:id]) %>
6
  </p>
7
  <p>
8
    <label class="block">
9
      <%= radio_button_tag 'choice', '1' %>
10
      <%= l(:text_close_parent_issue_and_open_subtasks_choice_close_also_all_subtasks,
11
            :status => status_name) %>
12
    </label>
13
    <label class="block">
14
      <%= radio_button_tag 'choice', '2', true %>
15
      <%= l(:text_close_parent_issue_and_open_subtasks_choice_close_only_parent,
16
            :issue_id => params[:id]) %>
17
    </label>
18
  </p>
19
<% else %>
20
  <p>
21
    <%= l(:text_close_parent_issue_with_open_subtasks_confirmation) %>
22
  </p>
23
<% end %>
24
<p class="buttons">
25
  <%= button_tag l(:button_apply), :type => "button", :onclick => "run_submit();" %>
26
  <%= link_to_function l(:button_cancel), "hideModal(this);" %>
27
</p>
28

  
29
<%= javascript_tag do %>
30
  function run_submit() {
31
    var canCloseAll = <%= can_close_all %>;
32
    if (canCloseAll) {
33
      var radioVal = $("input[name='choice']:checked").val();
34
      if (radioVal == '1') {
35
        $('<input />').attr('type', 'hidden')
36
            .attr('name', "close_descendants")
37
            .appendTo('#issue-form');
38
      }
39
    }
40
    $("#issue-form").off('submit');
41
    $("#issue-form").submit();
42
  }
43
<% end %>
app/views/issues/_edit.html.erb
82 82
    <%= hidden_field_tag 'issue_position', @issue_position if @issue_position %>
83 83
    <%= hidden_field_tag 'issue_count', @issue_count if @issue_count %>
84 84
<% end %>
85
<%= javascript_tag do %>
86
  $('#issue-form').submit(function(){
87
    var status_id = 0;
88
    if ($("#issue_status_id").length > 0) {
89
      status_id = $("#issue_status_id").val();
90
    }
91
    $.ajax({
92
      url: $("#issue-form").attr('action'),
93
      type: 'patch',
94
      data: { 
95
        "check_go_to_close_confirm": "",
96
        "status_id": status_id
97
       },
98
    })
99
      .then(
100
        function(data){
101
          if (data["result"]) {
102
            $.ajax({
103
              url:   $("#issue-form").attr('action'),
104
              type: 'patch',
105
              data: {}
106
              });
107
          } else {
108
            $("#issue-form").off('submit');
109
            $("#issue-form").submit();
110
          }
111
        }
112
      );
113
    return false;
114
  });
115
<% end %>
config/locales/en.yml
1201 1201
  text_time_logged_by_changeset: "Applied in changeset %{value}."
1202 1202
  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
1203 1203
  text_issues_destroy_descendants_confirmation: "This will also delete %{count} subtask(s)."
1204
  text_close_parent_issue_with_open_subtasks_confirmation: Are you sure you want to close parent issue with open subtasks?
1205
  text_close_parent_issue_and_open_subtasks: Issue %{issue_id} has open subtasks.
1206
  text_close_parent_issue_and_open_subtasks_choice_close_also_all_subtasks: Close all open subtasks by "%{status}" status too
1207
  text_close_parent_issue_and_open_subtasks_choice_close_only_parent: Close only issue %{issue_id}
1204 1208
  text_time_entries_destroy_confirmation: 'Are you sure you want to delete the selected time entr(y/ies)?'
1205 1209
  text_select_project_modules: 'Select modules to enable for this project:'
1206 1210
  text_default_administrator_account_changed: Default administrator account changed
test/functional/issues_controller_test.rb
6370 6370
    assert_equal 2, issue.reload.assigned_to_id
6371 6371
  end
6372 6372

  
6373
  test "check_go_to_close_confirm returns false if status_id is not close" do
6374
    issue = Issue.find(1)
6375
    user = User.find(2)
6376
    assert issue.visible?(user)
6377
    assert_not issue.closed?
6378
    @request.session[:user_id] = user.id
6379
    put(
6380
      :update,
6381
      :params => {
6382
        :id => issue.id,
6383
        :check_go_to_close_confirm => "",
6384
        :status_id => 1
6385
      },
6386
      :xhr => true
6387
    )
6388
    assert_response :success
6389
    assert_equal 'application/json', response.content_type
6390
    json = ActiveSupport::JSON.decode(response.body)
6391
    assert_equal({"result" => false}, json)
6392
    assert_not session.has_key?(:can_close_descendant)
6393
  end
6394

  
6395
  test "check_go_to_close_confirm returns false if status_id is 0" do
6396
    issue = Issue.find(1)
6397
    user = User.find(2)
6398
    assert issue.visible?(user)
6399
    assert_not issue.closed?
6400
    @request.session[:user_id] = user.id
6401
    put(
6402
      :update,
6403
      :params => {
6404
        :id => issue.id,
6405
        :check_go_to_close_confirm => "",
6406
        :status_id => 0
6407
      },
6408
      :xhr => true
6409
    )
6410
    assert_response :success
6411
    assert_equal 'application/json', response.content_type
6412
    json = ActiveSupport::JSON.decode(response.body)
6413
    assert_equal({"result" => false}, json)
6414
    assert_not session.has_key?(:can_close_descendant)
6415
  end
6416

  
6417
  test "check_go_to_close_confirm returns false if issue does not have child" do
6418
    issue = Issue.generate!
6419
    user = User.find(2)
6420
    assert issue.visible?(user)
6421
    assert_not issue.closed?
6422
    @request.session[:user_id] = user.id
6423
    put(
6424
      :update,
6425
      :params => {
6426
        :id => issue.id,
6427
        :check_go_to_close_confirm => "",
6428
        :status_id => 5
6429
      },
6430
      :xhr => true
6431
    )
6432
    assert_response :success
6433
    assert_equal 'application/json', response.content_type
6434
    json = ActiveSupport::JSON.decode(response.body)
6435

  
6436
    assert_equal 1, issue.reload.status.id
6437
    assert_equal({"result" => false}, json)
6438
    assert_not session.has_key?(:can_close_descendant)
6439
  end
6440

  
6441
  test "check_go_to_close_confirm returns true if issue have open child" do
6442
    parent = Issue.generate!
6443
    child = Issue.generate!(:parent_issue_id => parent.id)
6444
    user = User.find(2)
6445
    assert parent.reload.visible?(user)
6446
    assert_not parent.closed?
6447
    assert child.reload.visible?(user)
6448
    assert_not child.closed?
6449

  
6450
    @request.session[:user_id] = user.id
6451
    put(
6452
      :update,
6453
      :params => {
6454
        :id => parent.id,
6455
        :check_go_to_close_confirm => "",
6456
        :status_id => 5
6457
      },
6458
      :xhr => true
6459
    )
6460
    assert_response :success
6461
    assert_equal 'application/json', response.content_type
6462
    json = ActiveSupport::JSON.decode(response.body)
6463

  
6464
    assert_equal 1, parent.reload.status.id
6465
    assert_equal({"result" => true}, json)
6466
    assert session.has_key?(:can_close_descendant)
6467
  end
6468

  
6469
  test "check_go_to_close_confirm returns false if child is closed" do
6470
    parent = Issue.generate!
6471
    child = Issue.
6472
              generate!(
6473
                :parent_issue_id => parent.id,
6474
                :status_id => 5
6475
              )
6476
    user = User.find(2)
6477
    assert parent.reload.visible?(user)
6478
    assert_not parent.closed?
6479
    assert child.reload.visible?(user)
6480
    assert child.closed?
6481

  
6482
    @request.session[:user_id] = user.id
6483
    put(
6484
      :update,
6485
      :params => {
6486
        :id => parent.id,
6487
        :check_go_to_close_confirm => "",
6488
        :status_id => 5
6489
      },
6490
      :xhr => true
6491
    )
6492
    assert_response :success
6493
    assert_equal 'application/json', response.content_type
6494
    json = ActiveSupport::JSON.decode(response.body)
6495

  
6496
    assert_equal 1, parent.reload.status.id
6497
    assert_equal({"result" => false}, json)
6498
    assert_not session.has_key?(:can_close_descendant)
6499
  end
6500

  
6501
  test "check_go_to_close_confirm returns true if child is open and not visible" do
6502
    user = User.generate!
6503
    project = Project.generate!
6504
    role = Role.generate!
6505
    role.add_permission! :view_issues, :edit_issues
6506
    role.set_permission_trackers :view_issues, [2]
6507
    role.set_permission_trackers :edit_issues, [2]
6508
    role.save!
6509
    User.add_to_project(user, project, role)
6510
    parent = Issue.
6511
              generate!(
6512
                :project => project,
6513
                :tracker_id => 2,
6514
                :status_id => 1
6515
              )
6516
    child = Issue.
6517
              generate!(
6518
                :project => project,
6519
                :tracker_id => 1,
6520
                :parent_issue_id => parent.id,
6521
                :status_id => 1
6522
              )
6523
    assert parent.reload.visible?(user)
6524
    assert_not parent.closed?
6525
    assert_not child.reload.visible?(user)
6526
    assert_not child.closed?
6527

  
6528
    @request.session[:user_id] = user.id
6529
    put(
6530
      :update,
6531
      :params => {
6532
        :id => parent.id,
6533
        :check_go_to_close_confirm => "",
6534
        :status_id => 5
6535
      },
6536
      :xhr => true
6537
    )
6538
    assert_response :success
6539
    assert_equal 'application/json', response.content_type
6540
    json = ActiveSupport::JSON.decode(response.body)
6541

  
6542
    assert_equal 1, parent.reload.status.id
6543
    assert_equal({"result" => true}, json)
6544
    assert session.has_key?(:can_close_descendant)
6545
    assert_not session[:can_close_descendant][:can_close_all]
6546
  end
6547

  
6548
  test "close all descendants which are open" do
6549
    with_settings :closed_parent_issues_with_open_subtasks => 1 do
6550
      parent = Issue.generate!
6551
      child =
6552
        Issue.
6553
         generate!(
6554
           :parent_issue_id => parent.id
6555
         )
6556
      grandchild1 =
6557
        Issue.
6558
          generate!(
6559
            :parent_issue_id => child.id
6560
          )
6561
      grandchild2 =
6562
        Issue.
6563
         generate!(
6564
           :parent_issue_id => child.id,
6565
           :status_id => 6
6566
         )
6567
      user = User.find(2)
6568
      assert parent.reload.visible?(user)
6569
      assert_not parent.closed?
6570
      assert child.reload.visible?(user)
6571
      assert_not child.closed?
6572
      assert grandchild1.reload.visible?(user)
6573
      assert_not grandchild1.closed?
6574
      assert grandchild2.reload.visible?(user)
6575
      assert grandchild2.closed?
6576

  
6577
      assert [parent, child, grandchild1, grandchild2].
6578
               map{|i| i.new_statuses_allowed_to(user)}.
6579
                 reduce(:&).map{|i| i.id}.include?(5)
6580
      @request.session[:user_id] = user.id
6581
      put(
6582
        :update,
6583
        :params => {
6584
          :id => parent.id,
6585
          :check_go_to_close_confirm => "",
6586
          :status_id => 5
6587
        },
6588
        :xhr => true
6589
      )
6590
      assert_response :success
6591
      assert_equal 'application/json', response.content_type
6592
      json = ActiveSupport::JSON.decode(response.body)
6593

  
6594
      assert_equal 1, parent.reload.status.id
6595
      assert_equal({"result" => true}, json)
6596
      assert session.has_key?(:can_close_descendant)
6597
      assert session[:can_close_descendant][:can_close_all]
6598
      assert_equal [child.id, grandchild1.id], session[:can_close_descendant][:ids] 
6599

  
6600
      notes = 'close all'
6601

  
6602
      assert_difference(
6603
        -> {parent.journals.count} => 1,
6604
        -> {child.journals.count} => 1,
6605
        -> {grandchild1.journals.count} => 1,
6606
        -> {grandchild2.journals.count} => 0
6607
      ) do
6608
        put(
6609
          :update,
6610
          :params => {
6611
            :id => parent.id,
6612
            :close_descendants => "",
6613
            :issue => {
6614
              :status_id => 5,
6615
              :notes => notes
6616
            }
6617
          }
6618
        )
6619
        assert_response 302
6620
      end
6621
      assert 5, parent.reload.status.id
6622
      assert_equal notes, parent.journals.last.notes
6623
      assert 5, child.reload.status.id
6624
      assert_equal notes, child.journals.last.notes
6625
      assert 5, grandchild1.reload.status.id
6626
      assert_equal notes, grandchild1.journals.last.notes
6627
      assert 6, grandchild2.reload.status.id
6628
    end
6629
  end
6630

  
6631
  test "session generated by check_go_to_close_confirm should respect subtask statuses" do
6632
    with_settings :closed_parent_issues_with_open_subtasks => 1 do
6633
      WorkflowTransition.delete_all
6634
      WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
6635
                                 :old_status_id => 1, :new_status_id => 5)
6636
      WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
6637
                                 :old_status_id => 1, :new_status_id => 6)
6638
      WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
6639
                                 :old_status_id => 1, :new_status_id => 6)
6640
      user = User.find(2)
6641
      parent =
6642
        Issue.
6643
          generate!(
6644
            :author_id => 2,
6645
            :tracker_id => 1,
6646
            :status_id => 1
6647
          )
6648
     child1 =
6649
       Issue.
6650
         generate!(
6651
           :author_id => 2,
6652
           :parent_issue_id => parent.id,
6653
           :tracker_id => 1,
6654
           :status_id => 1
6655
         )
6656
     child2 =
6657
       Issue.
6658
         generate!(
6659
           :author_id => 2,
6660
           :parent_issue_id => parent.id,
6661
           :tracker_id => 2,
6662
           :status_id => 1
6663
         )
6664
      assert parent.reload.visible?(user)
6665
      assert child1.reload.visible?(user)
6666
      assert child2.reload.visible?(user)
6667

  
6668
      assert [5, 6].all? do |id|
6669
        parent.new_statuses_allowed_to(user).map{|s| s.id}.include?(id)
6670
      end
6671
      assert [5, 6].all? do |id|
6672
        child1.new_statuses_allowed_to(user).map{|s| s.id}.include?(id)
6673
      end
6674
      assert_not child2.new_statuses_allowed_to(user).map{|s| s.id}.include?(5)
6675
      assert child2.new_statuses_allowed_to(user).map{|s| s.id}.include?(6)
6676

  
6677
      @request.session[:user_id] = user.id
6678
      put(
6679
        :update,
6680
        :params => {
6681
          :id => parent.id,
6682
          :check_go_to_close_confirm => "",
6683
          :status_id => 6
6684
        },
6685
        :xhr => true
6686
      )
6687
      assert_response :success
6688
      assert_equal 'application/json', response.content_type
6689
      json = ActiveSupport::JSON.decode(response.body)
6690

  
6691
      assert_equal 1, parent.reload.status.id
6692
      assert_equal({"result" => true}, json)
6693
      assert session.has_key?(:can_close_descendant)
6694
      assert session[:can_close_descendant][:can_close_all]
6695
      assert_equal [child1.id, child2.id], session[:can_close_descendant][:ids] 
6696

  
6697
      @request.session.delete(:can_close_descendant)
6698

  
6699
      @request.session[:user_id] = user.id
6700
      put(
6701
        :update,
6702
        :params => {
6703
          :id => parent.id,
6704
          :check_go_to_close_confirm => "",
6705
          :status_id => 5
6706
        },
6707
        :xhr => true
6708
      )
6709
      assert_response :success
6710
      assert_equal 'application/json', response.content_type
6711
      json = ActiveSupport::JSON.decode(response.body)
6712

  
6713
      assert_equal 1, parent.reload.status.id
6714
      assert_equal({"result" => true}, json)
6715
      assert session.has_key?(:can_close_descendant)
6716
      assert_not session[:can_close_descendant][:can_close_all]
6717
      assert_not session[:can_close_descendant].has_key?(:ids)
6718
    end
6719
  end
6720

  
6373 6721
  def test_get_bulk_edit
6374 6722
    @request.session[:user_id] = 2
6375 6723
    get(:bulk_edit, :params => {:ids => [1, 3]})
test/system/issues_test.rb
234 234
    assert_equal 5, issue.reload.status.id
235 235
  end
236 236

  
237
  test "add confirm dialog to issue submit button" do
238
    parent = Issue.generate!(:project_id => 1)
239
    child = Issue.generate!(:project_id => 1, :parent_issue_id => parent.id)
240
    hidden_child =
241
      Issue.
242
        generate!(
243
          :project_id => 1,
244
          :parent_issue_id => parent.id,
245
          :author_id => 2,
246
          :is_private => true
247
        )
248
    assert_not hidden_child.visible?(User.find(3))
249
    with_settings :closed_parent_issues_with_open_subtasks => 1 do
250
      log_user('dlopper', 'foo')
251
      visit "/issues/#{parent.id}"
252

  
253
      page.first(:link, 'Edit').click
254
      assert page.has_select?("issue_status_id", {:selected => "New"})
255
      page.find("#issue_status_id").select("Closed")
256
      assert_no_difference ['Issue.count', 'child.journals.count'] do
257
        assert_no_difference 'parent.journals.count' do
258
          page.first(:button, 'Submit').click
259
          within('#ajax-modal') do
260
            assert page.has_text?(/Are you sure/)
261
            page.first(:link, 'Cancel').click
262
          end
263
          assert_equal 1, parent.reload.status.id
264
        end
265
        assert_difference 'parent.journals.count' do
266
          page.first(:button, 'Submit').click
267
          within('#ajax-modal') do
268
            assert page.has_text?(/Are you sure/)
269
            page.first(:button, 'Apply').click
270
          end
271
          assert page.has_css?('#flash_notice')
272
          assert_equal 5, parent.reload.status.id
273
        end
274
      end
275

  
276
      page.first(:link, 'Edit').click
277
      assert page.has_select?("issue_status_id", {:selected => "Closed"})
278
      fill_in 'Subject', :with => 'test of confirm dialog'
279
      assert_no_difference ['Issue.count', 'child.journals.count'] do
280
        assert_no_difference 'parent.journals.count' do
281
          page.first(:button, 'Submit').click
282
          within('#ajax-modal') do
283
            assert page.has_text?(/Are you sure/)
284
            page.first(:link, 'Cancel').click
285
          end
286
          assert_equal 5, parent.reload.status.id
287
        end
288
        assert_difference 'parent.journals.count' do
289
        page.first(:button, 'Submit').click
290
          within('#ajax-modal') do
291
            assert page.has_text?(/Are you sure/)
292
            page.first(:button, 'Apply').click
293
          end
294
          assert page.has_css?('#flash_notice')
295
          assert_equal 5, parent.reload.status.id
296
          assert_equal 'test of confirm dialog', parent.reload.subject
297
        end
298
      end
299

  
300
      page.first(:link, 'Edit').click
301
      assert page.has_select?("issue_status_id", {:selected => "Closed"})
302
      page.find("#issue_status_id").select("New")
303
      assert_no_difference ['Issue.count', 'child.journals.count'] do
304
        assert_difference 'parent.journals.count' do
305
          page.first(:button, 'Submit').click
306
          assert page.has_css?('#flash_notice')
307
          assert_equal 1, parent.reload.status.id
308
        end
309
      end
310

  
311
      visit "/issues/#{child.id}"
312
      page.first(:link, 'Edit').click
313
      assert page.has_select?("issue_status_id", {:selected => "New"})
314
      page.find("#issue_status_id").select("Closed")
315
      assert_no_difference ['Issue.count', 'parent.journals.count'] do
316
        assert_difference 'child.journals.count' do
317
          page.first(:button, 'Submit').click
318
          assert page.has_css?('#flash_notice')
319
          assert_equal 5, child.reload.status.id
320
        end
321
      end
322

  
323
      hidden_child.status_id = 5
324
      hidden_child.save!
325

  
326
      visit "/issues/#{parent.id}"
327
      page.first(:link, 'Edit').click
328
      assert page.has_select?("issue_status_id", {:selected => "New"})
329
      page.find("#issue_status_id").select("Closed")
330
      assert_no_difference ['Issue.count', 'child.journals.count'] do
331
        assert_difference 'parent.journals.count' do
332
          page.first(:button, 'Submit').click
333
          assert page.has_css?('#flash_notice')
334
          assert_equal 5, parent.reload.status.id
335
        end
336
      end
337
    end
338
  end
339

  
340
  test "close all open subtasks" do
341
    parent = Issue.generate!(:project_id => 1)
342
    child = Issue.generate!(:project_id => 1, :parent_issue_id => parent.id)
343
    close_only_text = "Close only issue #{parent.id}"
344

  
345
    with_settings :closed_parent_issues_with_open_subtasks => 1 do
346
      log_user('dlopper', 'foo')
347
      visit "/issues/#{parent.id}"
348
      page.first(:link, 'Edit').click
349
      assert page.has_select?("issue_status_id", {:selected => "New"})
350
      page.find("#issue_status_id").select("Closed")
351
      assert_no_difference ['Issue.count', 'child.journals.count'] do
352
        assert_no_difference 'parent.journals.count' do
353
          page.first(:button, 'Submit').click
354
          within('#ajax-modal') do
355
            assert page.has_text?(/has open subtasks/)
356
            assert page.has_checked_field?(close_only_text)
357
            page.first(:link, 'Cancel').click
358
          end
359
          assert_equal 1, parent.reload.status.id
360
        end
361
        assert_difference 'parent.journals.count' do
362
          page.first(:button, 'Submit').click
363
          within('#ajax-modal') do
364
            assert page.has_text?(/has open subtasks/)
365
            assert page.has_checked_field?(close_only_text)
366
            page.first(:button, 'Apply').click
367
          end
368
          assert page.has_css?('#flash_notice')
369
          assert_equal 5, parent.reload.status.id
370
        end
371
      end
372
      page.first(:link, 'Edit').click
373
      assert page.has_select?("issue_status_id", {:selected => "Closed"})
374
      page.find("#issue_status_id").select("New")
375
      assert_no_difference ['Issue.count', 'child.journals.count'] do
376
        assert_difference 'parent.journals.count' do
377
          page.first(:button, 'Submit').click
378
          assert page.has_css?('#flash_notice')
379
          assert_equal 1, parent.reload.status.id
380
        end
381
      end
382
      page.first(:link, 'Edit').click
383
      assert page.has_select?("issue_status_id", {:selected => "New"})
384
      page.find("#issue_status_id").select("Closed")
385
      assert_no_difference 'Issue.count' do
386
        assert_difference ['parent.journals.count', 'child.journals.count'] do
387
          page.first(:button, 'Submit').click
388
          within('#ajax-modal') do
389
            all_text = 'Close all open subtasks by "Closed" status'
390
            assert page.has_text?(/has open subtasks/)
391
            assert page.has_checked_field?(close_only_text)
392
            page.choose(all_text)
393
            assert page.has_checked_field?(all_text)
394
            page.first(:button, 'Apply').click
395
          end
396
          assert page.has_css?('#flash_notice')
397
          assert_equal 5, parent.reload.status.id
398
          assert_equal 5, child.reload.status.id
399
        end
400
      end
401
    end
402
  end
403

  
237 404
  test "removing issue shows confirm dialog" do
238 405
    log_user('jsmith', 'jsmith')
239 406
    visit '/issues/1'
(14-14/15)