Project

General

Profile

Feature #9432 » 0001-Add-tracker-setting-for-private-issues-by-default.patch

Go MAEDA, 2026-05-10 11:10

View differences:

app/controllers/issues_controller.rb
630 630
      # so we can use the default version for the new project
631 631
      attrs.delete(:fixed_version_id)
632 632
    end
633
    if action_name == 'new' &&
634
         %w[issue_project_id issue_tracker_id].include?(params[:form_update_triggered_by]) &&
635
         attrs[:is_private] != '1'
636
      # Drop the unchecked value so the selected tracker's private default can be applied.
637
      attrs.delete(:is_private)
638
    end
633 639
    attrs[:assigned_to_id] = User.current.id if attrs[:assigned_to_id] == 'me'
634 640
    @issue.safe_attributes = attrs
635 641

  
app/models/issue.rb
616 616
    if new_record? && !statuses_allowed.include?(status)
617 617
      self.status = statuses_allowed.first || default_status
618 618
    end
619
    # Use the selected tracker's private default when the form has no explicit value.
620
    if new_record? && tracker&.private_by_default? &&
621
         !attrs.key?('is_private') && safe_attribute?('is_private', user)
622
      attrs['is_private'] = '1'
623
    end
619 624
    if (u = attrs.delete('assigned_to_id')) && safe_attribute?('assigned_to_id')
620 625
      self.assigned_to_id = u
621 626
    end
app/models/tracker.rb
74 74
    'name',
75 75
    'default_status_id',
76 76
    'is_in_roadmap',
77
    'private_by_default',
77 78
    'core_fields',
78 79
    'position',
79 80
    'custom_field_ids',
app/views/trackers/_form.html.erb
10 10
        :include_blank => @tracker.default_status.nil?,
11 11
        :required => true %>
12 12
</p>
13
<p><%= f.check_box :private_by_default %></p>
13 14
<p><%= f.check_box :is_in_roadmap %></p>
14 15
<p><%= f.textarea :description, :rows => 4 %></p>
15 16
<p>
config/locales/en.yml
326 326
  field_is_public: Public
327 327
  field_parent: Subproject of
328 328
  field_is_in_roadmap: Issues displayed in roadmap
329
  field_private_by_default: Private by default
329 330
  field_login: Login
330 331
  field_mail_notification: Email notifications
331 332
  field_admin: Administrator
db/migrate/20260510000000_add_private_by_default_to_trackers.rb
1
class AddPrivateByDefaultToTrackers < ActiveRecord::Migration[8.1]
2
  def change
3
    add_column :trackers, :private_by_default, :boolean, :default => false, :null => false
4
  end
5
end
test/functional/issues_controller_test.rb
4241 4241
    end
4242 4242
  end
4243 4243

  
4244
  def test_new_should_check_private_if_tracker_is_private_by_default
4245
    Tracker.find(1).update! :private_by_default => true
4246
    @request.session[:user_id] = 2
4247
    get(:new, :params => {:project_id => 1})
4248
    assert_response :success
4249

  
4250
    assert_select 'input[name=?][checked=checked]', 'issue[is_private]'
4251
  end
4252

  
4253
  def test_update_form_for_new_issue_should_apply_private_by_default_when_submitted_private_is_unchecked
4254
    Tracker.find(2).update! :private_by_default => true
4255
    @request.session[:user_id] = 2
4256
    # Simulates switching from an unchecked tracker to a tracker that is private by default.
4257
    post(
4258
      :new,
4259
      :params => {
4260
        :project_id => 1,
4261
        :issue => {
4262
          :tracker_id => 2,
4263
          :is_private => '0'
4264
        },
4265
        :form_update_triggered_by => 'issue_tracker_id'
4266
      }
4267
    )
4268
    assert_response :success
4269

  
4270
    assert_select 'select[name=?]', 'issue[tracker_id]' do
4271
      assert_select 'option[value=?][selected=selected]', '2'
4272
    end
4273
    assert_select 'input[name=?][checked=checked]', 'issue[is_private]'
4274
  end
4275

  
4276
  def test_update_form_for_new_issue_should_keep_submitted_private_when_checked
4277
    @request.session[:user_id] = 2
4278
    # Simulates keeping the user's checked private value when switching trackers.
4279
    post(
4280
      :new,
4281
      :params => {
4282
        :project_id => 1,
4283
        :issue => {
4284
          :tracker_id => 2,
4285
          :is_private => '1'
4286
        },
4287
        :form_update_triggered_by => 'issue_tracker_id'
4288
      }
4289
    )
4290
    assert_response :success
4291

  
4292
    assert_select 'select[name=?]', 'issue[tracker_id]' do
4293
      assert_select 'option[value=?][selected=selected]', '2'
4294
    end
4295
    assert_select 'input[name=?][checked=checked]', 'issue[is_private]'
4296
  end
4297

  
4244 4298
  def test_update_form_for_new_issue_should_ignore_version_when_changing_project
4245 4299
    version = Version.generate!(:project_id => 1)
4246 4300
    Project.find(1).update_attribute :default_version_id, version.id
......
4902 4956
    assert issue.is_private?
4903 4957
  end
4904 4958

  
4959
  def test_post_create_should_respect_private_by_default_per_tracker_setting
4960
    @request.session[:user_id] = 2
4961
    tracker = Tracker.find(1)
4962
    tracker.update! :private_by_default => true
4963

  
4964
    assert_difference 'Issue.count' do
4965
      post(
4966
        :create,
4967
        :params => {
4968
          :project_id => 1,
4969
          :issue => {
4970
            :tracker_id => tracker.id,
4971
            :subject => 'This is a private issue by default'
4972
          }
4973
        }
4974
      )
4975
    end
4976
    issue = Issue.order(id: :desc).first
4977
    assert issue.is_private?
4978

  
4979
    assert_difference 'Issue.count' do
4980
      post(
4981
        :create,
4982
        :params => {
4983
          :project_id => 1,
4984
          :issue => {
4985
            :tracker_id => tracker.id,
4986
            :subject => 'This is a public issue',
4987
            :is_private => '0'
4988
          }
4989
        }
4990
      )
4991
    end
4992
    issue = Issue.order(id: :desc).first
4993
    assert_not issue.is_private?
4994
  end
4995

  
4996
  def test_post_create_should_not_apply_private_by_default_without_permission
4997
    role = Role.find(1)
4998
    role.remove_permission! :set_issues_private
4999
    role.remove_permission! :set_own_issues_private
5000
    Tracker.find(1).update! :private_by_default => true
5001
    @request.session[:user_id] = 2
5002

  
5003
    assert_difference 'Issue.count' do
5004
      post(
5005
        :create,
5006
        :params => {
5007
          :project_id => 1,
5008
          :issue => {
5009
            :tracker_id => 1,
5010
            :subject => 'This is a public issue'
5011
          }
5012
        }
5013
      )
5014
    end
5015
    issue = Issue.order(id: :desc).first
5016
    assert_not issue.is_private?
5017
  end
5018

  
4905 5019
  def test_create_without_project_id
4906 5020
    @request.session[:user_id] = 2
4907 5021
    assert_difference 'Issue.count' do
test/functional/trackers_controller_test.rb
121 121
        :tracker => {
122 122
          :name => 'New tracker',
123 123
          :default_status_id => 1,
124
          :private_by_default => '1',
124 125
          :project_ids => ['1', '', ''],
125 126
          :custom_field_ids => ['1', '6', '']
126 127
        }
......
129 130
    assert_redirected_to :action => 'index'
130 131
    tracker = Tracker.order(id: :desc).first
131 132
    assert_equal 'New tracker', tracker.name
133
    assert tracker.private_by_default?
132 134
    assert_equal [1], tracker.project_ids.sort
133 135
    assert_equal Tracker::CORE_FIELDS, tracker.core_fields
134 136
    assert_equal [1, 6], tracker.custom_field_ids.sort
test/integration/api_test/issues_test.rb
728 728
    assert_response :unprocessable_content
729 729
  end
730 730

  
731
  test "POST /issues.json should use the tracker private_by_default setting" do
732
    Tracker.find(1).update! :private_by_default => true
733

  
734
    issue = new_record(Issue) do
735
      post(
736
        '/issues.json',
737
        :params => {:issue => {:project_id => 1, :tracker_id => 1, :subject => 'API'}},
738
        :headers => credentials('jsmith'))
739
    end
740
    assert issue.is_private?
741
  end
742

  
731 743
  test "PUT /issues/:id.xml" do
732 744
    assert_difference('Journal.count') do
733 745
      put(
(8-8/8)