diff --git a/app/helpers/time_zone_helper.rb b/app/helpers/time_zone_helper.rb index daf99ad9b5e..00f65b72c8e 100644 --- a/app/helpers/time_zone_helper.rb +++ b/app/helpers/time_zone_helper.rb @@ -1,7 +1,26 @@ # frozen_string_literal: true module TimeZoneHelper - def timezone_data + TIME_ZONE_FORMAT_ATTRS = { + short: %i[identifier name offset], + full: %i[identifier name abbr offset formatted_offset] + }.freeze + private_constant :TIME_ZONE_FORMAT_ATTRS + + # format: + # * :full - all available fields + # * :short (default) + # + # Example: + # timezone_data # :short by default + # timezone_data(format: :full) + # + def timezone_data(format: :short) + attrs = TIME_ZONE_FORMAT_ATTRS.fetch(format) do + valid_formats = TIME_ZONE_FORMAT_ATTRS.keys.map { |k| ":#{k}"}.join(", ") + raise ArgumentError.new("Invalid format :#{format}. Valid formats are #{valid_formats}.") + end + ActiveSupport::TimeZone.all.map do |timezone| { identifier: timezone.tzinfo.identifier, @@ -9,7 +28,7 @@ module TimeZoneHelper abbr: timezone.tzinfo.strftime('%Z'), offset: timezone.now.utc_offset, formatted_offset: timezone.now.formatted_offset - } + }.slice(*attrs) end end end diff --git a/spec/helpers/time_zone_helper_spec.rb b/spec/helpers/time_zone_helper_spec.rb index 7e7eb368474..391e9bd38ed 100644 --- a/spec/helpers/time_zone_helper_spec.rb +++ b/spec/helpers/time_zone_helper_spec.rb @@ -4,32 +4,68 @@ require 'spec_helper' RSpec.describe TimeZoneHelper, :aggregate_failures do describe '#timezone_data' do - subject(:timezone_data) { helper.timezone_data } + context 'with short format' do + subject(:timezone_data) { helper.timezone_data } - it 'matches schema' do - expect(timezone_data).not_to be_empty + it 'matches schema' do + expect(timezone_data).not_to be_empty - timezone_data.each_with_index do |timezone_hash, i| - expect(timezone_hash.keys).to contain_exactly( - :identifier, - :name, - :abbr, - :offset, - :formatted_offset - ), "Failed at index #{i}" + timezone_data.each_with_index do |timezone_hash, i| + expect(timezone_hash.keys).to contain_exactly( + :identifier, + :name, + :offset + ), "Failed at index #{i}" + end + end + + it 'formats for display' do + tz = ActiveSupport::TimeZone.all[0] + + expect(timezone_data[0]).to eq( + identifier: tz.tzinfo.identifier, + name: tz.name, + offset: tz.now.utc_offset + ) end end - it 'formats for display' do - tz = ActiveSupport::TimeZone.all[0] + context 'with full format' do + subject(:timezone_data) { helper.timezone_data(format: :full) } - expect(timezone_data[0]).to eq( - identifier: tz.tzinfo.identifier, - name: tz.name, - abbr: tz.tzinfo.strftime('%Z'), - offset: tz.now.utc_offset, - formatted_offset: tz.now.formatted_offset - ) + it 'matches schema' do + expect(timezone_data).not_to be_empty + + timezone_data.each_with_index do |timezone_hash, i| + expect(timezone_hash.keys).to contain_exactly( + :identifier, + :name, + :abbr, + :offset, + :formatted_offset + ), "Failed at index #{i}" + end + end + + it 'formats for display' do + tz = ActiveSupport::TimeZone.all[0] + + expect(timezone_data[0]).to eq( + identifier: tz.tzinfo.identifier, + name: tz.name, + abbr: tz.tzinfo.strftime('%Z'), + offset: tz.now.utc_offset, + formatted_offset: tz.now.formatted_offset + ) + end + end + + context 'with unknown format' do + subject(:timezone_data) { helper.timezone_data(format: :unknown) } + + it 'raises an exception' do + expect { timezone_data }.to raise_error ArgumentError, 'Invalid format :unknown. Valid formats are :short, :full.' + end end end end