Project

General

Profile

Feature #36320 » 20231117_36320.patch

r22429@trunk - Minoru Maeda, 2023-11-17 06:13

View differences:

Gemfile
2 2

  
3 3
ruby '>= 2.7.0', '< 3.3.0'
4 4

  
5
gem 'rails', '6.1.7.6'
5
gem 'rails', '7.1.2'
6 6
gem 'rouge', '~> 4.2.0'
7 7
gem 'request_store', '~> 1.5.0'
8 8
gem 'mini_mime', '~> 1.1.0'
9
gem "actionpack-xml_parser"
9
gem "actionpack-xml_parser", '~> 2.0.1'
10 10
gem 'roadie-rails', '~> 3.1.0'
11 11
gem 'marcel'
12 12
gem 'mail', '~> 2.8.1'
......
87 87
  warn("Please configure your config/database.yml first")
88 88
end
89 89

  
90
group :development, :test do
91
  gem 'debug'
92
end
93

  
90 94
group :development do
91 95
  gem 'listen', '~> 3.3'
92 96
  gem "yard"
app/controllers/application_controller.rb
780 780
  def _include_layout?(*args)
781 781
    api_request? ? false : super
782 782
  end
783

  
784
  # Note: Overrodes #_url_host_allowed? to avoid
785
  #       URI::InvalidURIError: URI must be ascii only...
786
  #       when determining if the redirect destination is its own host.
787
  # See: https://bugs.ruby-lang.org/issues/12852
788
  def _url_host_allowed?(url)
789
    host = Addressable::URI.parse(url.to_s).host
790

  
791
    return true if host == request.host
792
    return false unless host.nil?
793
    return false unless url.to_s.start_with?("/")
794
    !url.to_s.start_with?("//")
795
  rescue TypeError
796
    false
797
  end
798

  
799
  def rendered_format
800
    return request.format if api_request?
801

  
802
    super
803
  end
783 804
end
app/controllers/attachments_controller.rb
100 100
  def upload
101 101
    # Make sure that API users get used to set this content type
102 102
    # as it won't trigger Rails' automatic parsing of the request body for parameters
103
    unless request.content_type == 'application/octet-stream'
103
    unless request.media_type == 'application/octet-stream'
104 104
      head 406
105 105
      return
106 106
    end
app/helpers/application_helper.rb
259 259
    when Array
260 260
      formatted_objects = object.map {|o| format_object(o, html)}
261 261
      html ? safe_join(formatted_objects, ', ') : formatted_objects.join(', ')
262
    when Time
262
    when Time, ActiveSupport::TimeWithZone
263 263
      format_time(object)
264 264
    when Date
265 265
      format_date(object)
......
634 634
                 'span', nil,
635 635
                 :class => "name icon icon-#{principal.class.name.downcase}"
636 636
               )
637
            ) + principal
637
            ) + principal.to_s
638 638
        )
639 639
    end
640 640
    s.html_safe
app/models/attachment.rb
345 345
  #   })
346 346
  #
347 347
  def self.update_attachments(attachments, params)
348
    params = params.transform_keys {|key| key.to_i}
349

  
348
    converted = {}
349
    params.each {|key, val| converted[key.to_i] = val}
350 350
    saved = true
351 351
    transaction do
352 352
      attachments.each do |attachment|
353
        if p = params[attachment.id]
354
          attachment.filename = p[:filename] if p.key?(:filename)
355
          attachment.description = p[:description] if p.key?(:description)
353
        if file = converted[attachment.id]
354
          attachment.filename = file[:filename] if file.key?(:filename)
355
          attachment.description = file[:description] if file.key?(:description)
356 356
          saved &&= attachment.save
357 357
        end
358 358
      end
app/models/query.rb
257 257
  has_and_belongs_to_many :roles, :join_table => "#{table_name_prefix}queries_roles#{table_name_suffix}", :foreign_key => "query_id"
258 258
  serialize :filters
259 259
  serialize :column_names
260
  serialize :sort_criteria, Array
261
  serialize :options, Hash
260
  serialize :sort_criteria, type: Array
261
  serialize :options, type: Hash
262 262

  
263 263
  validates_presence_of :name
264 264
  validates_length_of :name, :maximum => 255
......
1631 1631
      else
1632 1632
        from = from - 1 # second
1633 1633
      end
1634
      if self.class.default_timezone == :utc
1634
      if ActiveRecord.default_timezone == :utc
1635 1635
        from = from.utc
1636 1636
      end
1637 1637
      s << ("#{table}.#{field} > '%s'" % [quoted_time(from, is_custom_filter)])
......
1640 1640
      if to.is_a?(Date)
1641 1641
        to = date_for_user_time_zone(to.year, to.month, to.day).end_of_day
1642 1642
      end
1643
      if self.class.default_timezone == :utc
1643
      if ActiveRecord.default_timezone == :utc
1644 1644
        to = to.utc
1645 1645
      end
1646 1646
      s << ("#{table}.#{field} <= '%s'" % [quoted_time(to, is_custom_filter)])
app/models/role.rb
76 76
  has_many :members, :through => :member_roles
77 77
  acts_as_positioned :scope => :builtin
78 78

  
79
  serialize :permissions, ::Role::PermissionsAttributeCoder
79
  serialize :permissions, coder: ::Role::PermissionsAttributeCoder
80 80
  store :settings, :accessors => [:permissions_all_trackers, :permissions_tracker_ids]
81 81

  
82 82
  validates_presence_of :name
app/views/custom_fields/_visibility_by_project_selector.html.erb
4 4
  <div id="custom_field_project_ids">
5 5
    <% project_ids = @custom_field.project_ids.to_a %>
6 6
    <%= render_project_nested_lists(Project.all) do |p|
7
      content_tag('label', check_box_tag('custom_field[project_ids][]', p.id, project_ids.include?(p.id), :id => nil) + ' ' + p)
7
      content_tag('label', check_box_tag('custom_field[project_ids][]', p.id, project_ids.include?(p.id), :id => nil) + ' ' + p.to_s)
8 8
    end %>
9 9
    <%= hidden_field_tag('custom_field[project_ids][]', '', :id => nil) %>
10 10
  </div>
config/application.rb
23 23
    # Application configuration should go into files in config/initializers
24 24
    # -- all .rb files in that directory are automatically loaded.
25 25

  
26
    # Custom directories with classes and modules you want to be autoloadable.
27
    config.autoloader = :zeitwerk
26
    # Adds `lib` to `config.autoload_paths` and `config.eager_load_paths`.
27
    config.autoload_lib(ignore: %w(tasks generators plugins))
28 28

  
29 29
    # Only load the plugins named here, in the order given (default is alphabetical).
30 30
    # :all can be used as a placeholder for all plugins not explicitly named.
31 31
    # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
32 32

  
33
    config.load_defaults 7.1
34
    config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1
35
    config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1
36
    config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
37
    config.active_record.default_column_serializer = YAML
38
    config.active_record.belongs_to_required_by_default = false
39
    config.action_dispatch.cookies_serializer = :marshal
40
    config.action_controller.raise_on_missing_callback_actions = false
41
    config.active_support.remove_deprecated_time_with_zone_name = true
42
    config.active_support.cache_format_version = 7.1
43

  
33 44
    config.active_record.store_full_sti_class = true
34 45
    config.active_record.default_timezone = :local
35 46
    config.active_record.yaml_column_permitted_classes = [
config/environments/test.rb
9 9

  
10 10
Rails.application.configure do
11 11
  # Settings specified here will take precedence over those in config/application.rb.
12
  config.add_autoload_paths_to_load_path = true
13
  config.dom_testing_default_html_version = :html4
12 14

  
13 15
  config.cache_classes = true
14 16
  # config.action_view.cache_template_loading = true
......
30 32
  config.cache_store = :null_store
31 33

  
32 34
  # Raise exceptions instead of rendering exception templates.
33
  config.action_dispatch.show_exceptions = true
35
  config.action_dispatch.show_exceptions = :all
34 36

  
35 37
  # Disable request forgery protection in test environment.
36 38
  config.action_controller.allow_forgery_protection = false
config/initializers/10-patches.rb
49 49
  end
50 50

  
51 51
  class Resolver
52
    def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[])
53
      locals = locals.map(&:to_s).sort!.freeze
52
    def find_all(name, prefix = nil, partial = false, details = {}, key = nil, locals = [])
53
      if (details[:formats] & [:xml, :json]).any?
54
        details = details.dup
55
        details[:formats] = details[:formats].dup + [:api]
54 56

  
55
      cached(key, [name, prefix, partial], details, locals) do
56
        if (details[:formats] & [:xml, :json]).any?
57
          details = details.dup
58
          details[:formats] = details[:formats].dup + [:api]
59
        end
60
        _find_all(name, prefix, partial, details, key, locals)
57
        key = ActionView::TemplateDetails::Requested.new(**details) if key
61 58
      end
59

  
60
      _find_all(name, prefix, partial, details, key, locals)
62 61
    end
63 62
  end
64 63
end
......
69 68
module ActionView
70 69
  module Helpers
71 70
    module Tags
72
      class Base
73
        private
74
        alias :add_options_without_non_empty_blank_option :add_options
71
      SelectRenderer.prepend(Module.new do
75 72
        def add_options(option_tags, options, value = nil)
76
          if options[:include_blank] == true
77
            options = options.dup
78
            options[:include_blank] = '&nbsp;'.html_safe
73
          if options.delete(:include_blank)
74
            options[:prompt] = '&nbsp;'.html_safe
79 75
          end
80
          add_options_without_non_empty_blank_option(option_tags, options, value)
76
          super
81 77
        end
82
      end
78
      end)
83 79
    end
84 80

  
85 81
    module FormHelper
config/initializers/20-mime_types.rb
1 1
# frozen_string_literal: true
2 2

  
3 3
# Add new mime types for use in respond_to blocks:
4
Mime::SET << 'api'
config/initializers/zeitwerk.rb
1 1
# frozen_string_literal: true
2 2

  
3 3
lib = Rails.root.join('lib/redmine')
4
Rails.autoloaders.main.push_dir lib, namespace: Redmine
5
Rails.application.config.watchable_dirs[lib] = [:rb]
6

  
7 4
IGNORE_LIST = [
8 5
  'wiki_formatting/textile/redcloth3.rb',
9 6
  'core_ext.rb',
lib/redmine/plugin.rb
467 467
          else
468 468
            migrations
469 469
          end
470
        Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
470
        Migrator.new(:up, selected_migrations, schema_migration, internal_metadata, target_version).migrate
471 471
      end
472 472

  
473 473
      def down(target_version = nil)
......
477 477
          else
478 478
            migrations
479 479
          end
480
        Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
480
        Migrator.new(:down, selected_migrations, schema_migration, internal_metadata, target_version).migrate
481 481
      end
482 482

  
483 483
      def run(direction, target_version)
484
        Migrator.new(direction, migrations, schema_migration, target_version).run
484
        Migrator.new(direction, migrations, schema_migration, internal_metadata, target_version).run
485 485
      end
486 486

  
487 487
      def open
488
        Migrator.new(:up, migrations, schema_migration)
488
        Migrator.new(:up, migrations, schema_migration, internal_metadata)
489 489
      end
490 490

  
491 491
      def current_version
......
510 510
          # Delete migrations that don't match .. to_i will work because the number comes first
511 511
          @all_versions ||= {}
512 512
          @all_versions[plugin.id.to_s] ||= begin
513
            sm_table = ::ActiveRecord::SchemaMigration.table_name
513
            sm_table = ::ActiveRecord::Base.connection.schema_migration.table_name
514 514
            migration_versions  = ActiveRecord::Base.connection.select_values("SELECT version FROM #{sm_table}")
515 515
            versions_by_plugins = migration_versions.group_by {|version| version.match(/-(.*)$/).try(:[], 1)}
516 516
            @all_versions       = versions_by_plugins.transform_values! {|versions| versions.map!(&:to_i).sort!}
test/fixtures/issues.yml
1 1
---
2 2
issues_001:
3
  created_on: <%= 3.days.ago.to_s(:db) %>
3
  created_on: <%= 3.days.ago.to_fs(:db) %>
4 4
  project_id: 1
5
  updated_on: <%= 1.day.ago.to_s(:db) %>
5
  updated_on: <%= 1.day.ago.to_fs(:db) %>
6 6
  priority_id: 4
7 7
  subject: Cannot print recipes
8 8
  id: 1
......
13 13
  assigned_to_id:
14 14
  author_id: 2
15 15
  status_id: 1
16
  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
17
  due_date: <%= 10.day.from_now.to_date.to_s(:db) %>
16
  start_date: <%= 1.day.ago.to_date.to_fs(:db) %>
17
  due_date: <%= 10.day.from_now.to_date.to_fs(:db) %>
18 18
  estimated_hours: 200.0
19 19
  root_id: 1
20 20
  lft: 1
......
34 34
  assigned_to_id: 3
35 35
  author_id: 2
36 36
  status_id: 2
37
  start_date: <%= 2.day.ago.to_date.to_s(:db) %>
37
  start_date: <%= 2.day.ago.to_date.to_fs(:db) %>
38 38
  due_date:
39 39
  estimated_hours: 0.5
40 40
  root_id: 2
......
56 56
  assigned_to_id: 3
57 57
  author_id: 2
58 58
  status_id: 1
59
  start_date: <%= 15.day.ago.to_date.to_s(:db) %>
60
  due_date: <%= 5.day.ago.to_date.to_s(:db) %>
59
  start_date: <%= 15.day.ago.to_date.to_fs(:db) %>
60
  due_date: <%= 5.day.ago.to_date.to_fs(:db) %>
61 61
  estimated_hours: 1.0
62 62
  root_id: 3
63 63
  lft: 1
64 64
  rgt: 2
65 65
issues_004:
66
  created_on: <%= 5.days.ago.to_s(:db) %>
66
  created_on: <%= 5.days.ago.to_fs(:db) %>
67 67
  project_id: 2
68
  updated_on: <%= 2.days.ago.to_s(:db) %>
68
  updated_on: <%= 2.days.ago.to_fs(:db) %>
69 69
  priority_id: 4
70 70
  subject: Issue on project 2
71 71
  id: 4
......
80 80
  lft: 1
81 81
  rgt: 2
82 82
issues_005:
83
  created_on: <%= 5.days.ago.to_s(:db) %>
83
  created_on: <%= 5.days.ago.to_fs(:db) %>
84 84
  project_id: 3
85
  updated_on: <%= 2.days.ago.to_s(:db) %>
85
  updated_on: <%= 2.days.ago.to_fs(:db) %>
86 86
  priority_id: 4
87 87
  subject: Subproject issue
88 88
  id: 5
......
98 98
  lft: 1
99 99
  rgt: 2
100 100
issues_006:
101
  created_on: <%= 1.minute.ago.to_s(:db) %>
101
  created_on: <%= 1.minute.ago.to_fs(:db) %>
102 102
  project_id: 5
103
  updated_on: <%= 1.minute.ago.to_s(:db) %>
103
  updated_on: <%= 1.minute.ago.to_fs(:db) %>
104 104
  priority_id: 4
105 105
  subject: Issue of a private subproject
106 106
  id: 6
......
111 111
  assigned_to_id:
112 112
  author_id: 2
113 113
  status_id: 1
114
  start_date: <%= Date.today.to_s(:db) %>
115
  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
114
  start_date: <%= Date.today.to_fs(:db) %>
115
  due_date: <%= 1.days.from_now.to_date.to_fs(:db) %>
116 116
  root_id: 6
117 117
  lft: 1
118 118
  rgt: 2
119 119
issues_007:
120
  created_on: <%= 10.days.ago.to_s(:db) %>
120
  created_on: <%= 10.days.ago.to_fs(:db) %>
121 121
  project_id: 1
122
  updated_on: <%= 10.days.ago.to_s(:db) %>
122
  updated_on: <%= 10.days.ago.to_fs(:db) %>
123 123
  priority_id: 5
124 124
  subject: Issue due today
125 125
  id: 7
......
130 130
  assigned_to_id:
131 131
  author_id: 2
132 132
  status_id: 1
133
  start_date: <%= 10.days.ago.to_s(:db) %>
134
  due_date: <%= Date.today.to_s(:db) %>
133
  start_date: <%= 10.days.ago.to_fs(:db) %>
134
  due_date: <%= Date.today.to_fs(:db) %>
135 135
  lock_version: 0
136 136
  root_id: 7
137 137
  lft: 1
138 138
  rgt: 2
139 139
issues_008:
140
  created_on: <%= 10.days.ago.to_s(:db) %>
140
  created_on: <%= 10.days.ago.to_fs(:db) %>
141 141
  project_id: 1
142
  updated_on: <%= 10.days.ago.to_s(:db) %>
142
  updated_on: <%= 10.days.ago.to_fs(:db) %>
143 143
  priority_id: 5
144 144
  subject: Closed issue
145 145
  id: 8
......
156 156
  root_id: 8
157 157
  lft: 1
158 158
  rgt: 2
159
  closed_on: <%= 3.days.ago.to_s(:db) %>
159
  closed_on: <%= 3.days.ago.to_fs(:db) %>
160 160
issues_009:
161
  created_on: <%= 1.minute.ago.to_s(:db) %>
161
  created_on: <%= 1.minute.ago.to_fs(:db) %>
162 162
  project_id: 5
163
  updated_on: <%= 1.minute.ago.to_s(:db) %>
163
  updated_on: <%= 1.minute.ago.to_fs(:db) %>
164 164
  priority_id: 5
165 165
  subject: Blocked Issue
166 166
  id: 9
......
171 171
  assigned_to_id:
172 172
  author_id: 2
173 173
  status_id: 1
174
  start_date: <%= Date.today.to_s(:db) %>
175
  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
174
  start_date: <%= Date.today.to_fs(:db) %>
175
  due_date: <%= 1.days.from_now.to_date.to_fs(:db) %>
176 176
  root_id: 9
177 177
  lft: 1
178 178
  rgt: 2
179 179
issues_010:
180
  created_on: <%= 1.minute.ago.to_s(:db) %>
180
  created_on: <%= 1.minute.ago.to_fs(:db) %>
181 181
  project_id: 5
182
  updated_on: <%= 1.minute.ago.to_s(:db) %>
182
  updated_on: <%= 1.minute.ago.to_fs(:db) %>
183 183
  priority_id: 5
184 184
  subject: Issue Doing the Blocking
185 185
  id: 10
......
190 190
  assigned_to_id:
191 191
  author_id: 2
192 192
  status_id: 1
193
  start_date: <%= Date.today.to_s(:db) %>
194
  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
193
  start_date: <%= Date.today.to_fs(:db) %>
194
  due_date: <%= 1.days.from_now.to_date.to_fs(:db) %>
195 195
  root_id: 10
196 196
  lft: 1
197 197
  rgt: 2
198 198
issues_011:
199
  created_on: <%= 3.days.ago.to_s(:db) %>
199
  created_on: <%= 3.days.ago.to_fs(:db) %>
200 200
  project_id: 1
201
  updated_on: <%= 1.day.ago.to_s(:db) %>
201
  updated_on: <%= 1.day.ago.to_fs(:db) %>
202 202
  priority_id: 5
203 203
  subject: Closed issue on a closed version
204 204
  id: 11
......
209 209
  assigned_to_id:
210 210
  author_id: 2
211 211
  status_id: 5
212
  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
212
  start_date: <%= 1.day.ago.to_date.to_fs(:db) %>
213 213
  due_date:
214 214
  root_id: 11
215 215
  lft: 1
216 216
  rgt: 2
217
  closed_on: <%= 1.day.ago.to_s(:db) %>
217
  closed_on: <%= 1.day.ago.to_fs(:db) %>
218 218
issues_012:
219
  created_on: <%= 3.days.ago.to_s(:db) %>
219
  created_on: <%= 3.days.ago.to_fs(:db) %>
220 220
  project_id: 1
221
  updated_on: <%= 1.day.ago.to_s(:db) %>
221
  updated_on: <%= 1.day.ago.to_fs(:db) %>
222 222
  priority_id: 5
223 223
  subject: Closed issue on a locked version
224 224
  id: 12
......
229 229
  assigned_to_id:
230 230
  author_id: 3
231 231
  status_id: 5
232
  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
232
  start_date: <%= 1.day.ago.to_date.to_fs(:db) %>
233 233
  due_date:
234 234
  root_id: 12
235 235
  lft: 1
236 236
  rgt: 2
237
  closed_on: <%= 1.day.ago.to_s(:db) %>
237
  closed_on: <%= 1.day.ago.to_fs(:db) %>
238 238
issues_013:
239
  created_on: <%= 5.days.ago.to_s(:db) %>
239
  created_on: <%= 5.days.ago.to_fs(:db) %>
240 240
  project_id: 3
241
  updated_on: <%= 2.days.ago.to_s(:db) %>
241
  updated_on: <%= 2.days.ago.to_fs(:db) %>
242 242
  priority_id: 4
243 243
  subject: Subproject issue two
244 244
  id: 13
......
254 254
  rgt: 2
255 255
issues_014:
256 256
  id: 14
257
  created_on: <%= 15.days.ago.to_s(:db) %>
257
  created_on: <%= 15.days.ago.to_fs(:db) %>
258 258
  project_id: 3
259
  updated_on: <%= 15.days.ago.to_s(:db) %>
259
  updated_on: <%= 15.days.ago.to_fs(:db) %>
260 260
  priority_id: 5
261 261
  subject: Private issue on public project
262 262
  fixed_version_id:
test/fixtures/journals.yml
1 1
---
2 2
journals_001:
3
  created_on: <%= 2.days.ago.to_date.to_s(:db) %>
4
  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
3
  created_on: <%= 2.days.ago.to_date.to_fs(:db) %>
4
  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
5 5
  notes: "Journal notes"
6 6
  id: 1
7 7
  journalized_type: Issue
......
9 9
  journalized_id: 1
10 10
  updated_by_id: 1
11 11
journals_002:
12
  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
13
  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
12
  created_on: <%= 1.days.ago.to_date.to_fs(:db) %>
13
  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
14 14
  notes: "Some notes with Redmine links: #2, r2."
15 15
  id: 2
16 16
  journalized_type: Issue
17 17
  user_id: 2
18 18
  journalized_id: 1
19 19
journals_003:
20
  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
21
  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
20
  created_on: <%= 1.days.ago.to_date.to_fs(:db) %>
21
  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
22 22
  notes: "A comment with inline image: !picture.jpg! and a reference to #1 and r2."
23 23
  id: 3
24 24
  journalized_type: Issue
25 25
  user_id: 2
26 26
  journalized_id: 2
27 27
journals_004:
28
  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
29
  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
28
  created_on: <%= 1.days.ago.to_date.to_fs(:db) %>
29
  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
30 30
  notes: "A comment with a private version."
31 31
  id: 4
32 32
  journalized_type: Issue
......
34 34
  journalized_id: 6
35 35
journals_005:
36 36
  id: 5
37
  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
38
  updated_on: <%= 1.days.ago.to_date.to_s(:db) %>
37
  created_on: <%= 1.days.ago.to_date.to_fs(:db) %>
38
  updated_on: <%= 1.days.ago.to_date.to_fs(:db) %>
39 39
  notes: "A comment on a private issue."
40 40
  user_id: 2
41 41
  journalized_type: Issue
test/fixtures/messages.yml
45 45
  parent_id: 
46 46
  board_id: 1
47 47
messages_005: 
48
  created_on: <%= 3.days.ago.to_date.to_s(:db) %>
49
  updated_on: <%= 3.days.ago.to_date.to_s(:db) %>
48
  created_on: <%= 3.days.ago.to_date.to_fs(:db) %>
49
  updated_on: <%= 3.days.ago.to_date.to_fs(:db) %>
50 50
  subject: 'RE: post 2'
51 51
  id: 5
52 52
  replies_count: 0
......
56 56
  parent_id: 4
57 57
  board_id: 1
58 58
messages_006: 
59
  created_on: <%= 2.days.ago.to_date.to_s(:db) %>
60
  updated_on: <%= 2.days.ago.to_date.to_s(:db) %>
59
  created_on: <%= 2.days.ago.to_date.to_fs(:db) %>
60
  updated_on: <%= 2.days.ago.to_date.to_fs(:db) %>
61 61
  subject: 'RE: post 2'
62 62
  id: 6
63 63
  replies_count: 0
......
67 67
  parent_id: 4
68 68
  board_id: 1
69 69
messages_007: 
70
  created_on: <%= 2.days.ago.to_date.to_s(:db) %>
71
  updated_on: <%= 2.days.ago.to_date.to_s(:db) %>
70
  created_on: <%= 2.days.ago.to_date.to_fs(:db) %>
71
  updated_on: <%= 2.days.ago.to_date.to_fs(:db) %>
72 72
  subject: 'Message on a private project'
73 73
  id: 7
74 74
  replies_count: 0
test/fixtures/versions.yml
16 16
  updated_on: 2006-07-19 21:00:33 +02:00
17 17
  id: 2
18 18
  description: Stable release
19
  effective_date: <%= 20.day.from_now.to_date.to_s(:db) %>
19
  effective_date: <%= 20.day.from_now.to_date.to_fs(:db) %>
20 20
  status: locked
21 21
  sharing: 'none'
22 22
  wiki_page_title: ECookBookV1
test/integration/layout_test.rb
48 48
  def test_top_menu_and_search_not_visible_when_login_required
49 49
    with_settings :login_required => '1' do
50 50
      get '/'
51
      assert_select "#top-menu > ul", 0
52
      assert_select "#quick-search", 0
51

  
52
      assert_equal response.status, 302
53 53
    end
54 54
  end
55 55

  
test/unit/query_test.rb
1549 1549
    query = IssueQuery.new(:name => '_')
1550 1550
    filter_name = "fixed_version.due_date"
1551 1551
    assert_include filter_name, query.available_filters.keys
1552
    query.filters = {filter_name => {:operator => '=', :values => [20.day.from_now.to_date.to_s(:db)]}}
1552
    query.filters = {filter_name => {:operator => '=', :values => [20.day.from_now.to_date.to_fs(:db)]}}
1553 1553
    issues = find_issues_with_query(query)
1554 1554
    assert_equal [2], issues.map(&:fixed_version_id).uniq.sort
1555 1555
    assert_equal [2, 12], issues.map(&:id).sort
1556 1556

  
1557 1557
    query = IssueQuery.new(:name => '_')
1558
    query.filters = {filter_name => {:operator => '>=', :values => [21.day.from_now.to_date.to_s(:db)]}}
1558
    query.filters = {filter_name => {:operator => '>=', :values => [21.day.from_now.to_date.to_fs(:db)]}}
1559 1559
    assert_equal 0, find_issues_with_query(query).size
1560 1560
  end
1561 1561

  
......
2962 2962
    User.current.pref.update_attribute :time_zone, 'Hawaii'
2963 2963

  
2964 2964
    # assume timestamps are stored as utc
2965
    ActiveRecord::Base.default_timezone = :utc
2965
    ActiveRecord.default_timezone = :utc
2966 2966

  
2967 2967
    from = Date.parse '2016-03-20'
2968 2968
    to = Date.parse '2016-03-22'
......
2973 2973
    t = Time.new(2016, 3, 23, 9, 59, 59, 0).end_of_hour
2974 2974
    assert_equal "table.field > '#{Query.connection.quoted_date f}' AND table.field <= '#{Query.connection.quoted_date t}'", c
2975 2975
  ensure
2976
    ActiveRecord::Base.default_timezone = :local # restore Redmine default
2976
    ActiveRecord.default_timezone = :local # restore Redmine default
2977 2977
  end
2978 2978

  
2979 2979
  def test_project_statement_with_closed_subprojects
test/unit/user_query_test.rb
209 209
    users = q.results_scope
210 210

  
211 211
    assert_equal 2, users.size
212
    assert_equal [2, 1], users.ids
212
    assert_equal [2, 1], users.pluck(:id)
213 213
  end
214 214

  
215 215
  def find_users_with_query(query)
(6-6/8)