mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
store tzinfo time zones
This commit is contained in:
@@ -48,8 +48,28 @@ module Settings
|
||||
|
||||
##
|
||||
# Returns time zone (label, value) tuples to be used for a select field.
|
||||
# As we only store tzinfo compatible data we only provide options, for which the
|
||||
# values can later on be retrieved unambiguously. This is not always the case
|
||||
# for values in ActiveSupport::TimeZone since multiple AS zones map to single tzinfo zones.
|
||||
def time_zone_entries
|
||||
time_zones.map { |tz| [tz.to_s, tz.name] }
|
||||
time_zones
|
||||
.group_by { |tz| tz.tzinfo.name }
|
||||
.values
|
||||
.map do |zones|
|
||||
tz = namesake_time_zone(zones)
|
||||
|
||||
[tz.to_s, tz.tzinfo.canonical_identifier]
|
||||
end
|
||||
end
|
||||
|
||||
# If there are multiple AS::TimeZones for a single TZInfo::Timezone, we
|
||||
# one return the one that is the namesake.
|
||||
def namesake_time_zone(time_zones)
|
||||
if time_zones.length == 1
|
||||
time_zones.first
|
||||
else
|
||||
time_zones.detect { |tz| tz.tzinfo.name.include?(tz.name.gsub(' ', '_')) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -54,7 +54,10 @@ module UserPreferences
|
||||
protected
|
||||
|
||||
def time_zone_correctness
|
||||
errors.add(:time_zone, :inclusion) if model.time_zone.present? && model.canonical_time_zone.nil?
|
||||
if model.time_zone.present? &&
|
||||
ActiveSupport::TimeZone[model.time_zone]&.tzinfo&.canonical_identifier != model.time_zone
|
||||
errors.add(:time_zone, :inclusion)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
||||
@@ -50,8 +50,9 @@ describe UserPreferences::UpdateContract do
|
||||
enabled: true,
|
||||
times: %w[08:00:00+00:00 12:00:00+00:00]
|
||||
},
|
||||
time_zone: 'Brasilia',
|
||||
warn_on_leaving_unsaved: true
|
||||
time_zone: 'America/Sao_Paulo',
|
||||
warn_on_leaving_unsaved: true,
|
||||
workdays: [1, 2, 4, 6]
|
||||
}
|
||||
end
|
||||
let(:contract) { described_class.new(user_preference, current_user) }
|
||||
@@ -237,36 +238,34 @@ describe UserPreferences::UpdateContract do
|
||||
it_behaves_like 'contract is invalid', time_zone: :inclusion
|
||||
end
|
||||
|
||||
describe 'workdays' do
|
||||
context 'with valid entries' do
|
||||
let(:settings) do
|
||||
{
|
||||
workdays: [1, 2, 4, 6]
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'contract is valid'
|
||||
context 'with a non tzinfo time_zone' do
|
||||
let(:settings) do
|
||||
{
|
||||
time_zone: 'Brasilia'
|
||||
}
|
||||
end
|
||||
|
||||
context 'with duplicate entries' do
|
||||
let(:settings) do
|
||||
{
|
||||
workdays: [1, 1]
|
||||
}
|
||||
end
|
||||
it_behaves_like 'contract is invalid', time_zone: :inclusion
|
||||
end
|
||||
|
||||
it_behaves_like 'contract is invalid', workdays: :no_duplicates
|
||||
context 'with duplicate workday entries' do
|
||||
let(:settings) do
|
||||
{
|
||||
workdays: [1, 1]
|
||||
}
|
||||
end
|
||||
|
||||
context 'with non-iso entries' do
|
||||
let(:settings) do
|
||||
{
|
||||
workdays: [nil, 'foo', :bar, 21345, 2.0]
|
||||
}
|
||||
end
|
||||
it_behaves_like 'contract is invalid', workdays: :no_duplicates
|
||||
end
|
||||
|
||||
it_behaves_like 'contract is invalid', workdays: %i[invalid type_mismatch_nested
|
||||
type_mismatch_nested type_mismatch_nested]
|
||||
context 'with non-iso workday entries' do
|
||||
let(:settings) do
|
||||
{
|
||||
workdays: [nil, 'foo', :bar, 21345, 2.0]
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'contract is invalid', workdays: %i[invalid type_mismatch_nested
|
||||
type_mismatch_nested type_mismatch_nested]
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user