Skip to content

Commit

Permalink
adds operations to transform time to string and vice versa
Browse files Browse the repository at this point in the history
  • Loading branch information
saikumar9 committed Oct 14, 2024
1 parent 1b25e26 commit 9786695
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/aca_entities/libraries/core_library.rb
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ module CoreLibrary
require 'aca_entities/operations/create_family'
require 'aca_entities/operations/create_person'
require 'aca_entities/operations/encrypted_ssn_validator'
require 'aca_entities/operations/date_time_transforms/convert_string_to_time'
require 'aca_entities/operations/date_time_transforms/convert_time_to_string'
end
# rubocop:enable Metrics/ModuleLength
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# frozen_string_literal: true

require 'aca_entities/types'

module AcaEntities
module Operations
module DateTimeTransforms
# Class to convert a string to a Time object
class ConvertStringToTime
include Dry::Monads[:do, :result]

# Converts a string to a Time object
#
# @param params [Hash] the input parameters containing the string
# @option params [String] :time_string the string to be converted to Time
# @return [Dry::Monads::Result::Success<Time>, Dry::Monads::Result::Failure<String>] the result of the conversion
def call(params)
time_string = yield validate(params)
time = yield convert(time_string)

Success(time)
end

private

# Validates the input parameters
#
# @param params [Hash] the input parameters
# @option params [String] :time_string the string to be validated
# @return [Dry::Monads::Result::Success<String>, Dry::Monads::Result::Failure<String>] the result of the validation
def validate(params)
return Failure('Invalid input: params cannot be nil.') if params.nil?
time_string = params[:time_string]

if time_string.nil?
Failure("Invalid input: #{params}. Time string is required.")
elsif !time_string.is_a?(String)
Failure("Invalid input: #{params}. Time string must be a String.")
else
Success(time_string)
end
end

# Converts the validated time string to a Time object
#
# @param time_string [String] the validated time string
# @return [Dry::Monads::Result::Success<Time>, Dry::Monads::Result::Failure<String>] the result of the conversion
def convert(time_string)
begin
Success(Time.strptime(time_string, AcaEntities::Types::DATETIME_FORMAT_ISO8601))
rescue ArgumentError => e
Failure("Invalid time format: #{e.message} with time input: #{time_string}. Time string must match the format #{AcaEntities::Types::DATETIME_FORMAT_ISO8601}.")
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require 'aca_entities/types'

module AcaEntities
module Operations
module DateTimeTransforms
# Class to convert a Time object to a string in ISO8601 format
class ConvertTimeToString
include Dry::Monads[:do, :result]

# Converts a Time object to a string in ISO8601 format
#
# @param params [Hash] the parameters containing the Time object
# @option params [Time] :time the Time object to be converted
# @return [Dry::Monads::Result::Success<String>, Dry::Monads::Result::Failure<String>] the result of the conversion
def call(params)
time = yield validate(params)
time_string = yield convert(time)

Success(time_string)
end

private

# Validates the input parameters
#
# @param params [Hash, nil] the parameters containing the Time object
# @option params [Time] :time the Time object to be validated
# @return [Dry::Monads::Result::Success<Time>, Dry::Monads::Result::Failure<String>] the result of the validation
def validate(params)
return Failure('Invalid input: params cannot be nil.') if params.nil?
time = params[:time]

if time.nil?
Failure("Invalid input: #{params}. Time is required.")
elsif !time.is_a?(Time)
Failure("Invalid input: #{params}. Time must be a Time object.")
else
Success(time)
end
end

# Converts the Time object to a string in ISO8601 format
#
# @param time [Time] the Time object to be converted
# @return [Dry::Monads::Result::Success<String>] the result of the conversion
def convert(time)
Success(time.strftime(AcaEntities::Types::DATETIME_FORMAT_ISO8601))
end
end
end
end
end
4 changes: 4 additions & 0 deletions lib/aca_entities/types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ module Types
electronic_only: 'Only Electronic communications'
}.freeze

# @!constant
# @return [String] the ISO 8601 datetime format string
DATETIME_FORMAT_ISO8601 = "%Y-%m-%dT%H:%M:%S.%N%z".freeze

ElectronicCommunicationKinds = Types::String.enum('sms', 'smtp').freeze

ElectronicCommunicationKindsMap = { simple_message_service: 'Text message', smtp: 'Email' }.freeze
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

require 'spec_helper'
require 'aca_entities/types'
require 'aca_entities/operations/date_time_transforms/convert_string_to_time'

RSpec.describe AcaEntities::Operations::DateTimeTransforms::ConvertStringToTime do
subject { described_class.new }

describe '#call' do
context 'when params is nil' do
let(:params) { nil }

it 'returns a failure' do
result = subject.call(params)
expect(result).to be_failure
expect(result.failure).to eq('Invalid input: params cannot be nil.')
end
end

context 'when time_string is nil' do
let(:params) { { time_string: nil } }

it 'returns a failure' do
result = subject.call(params)
expect(result).to be_failure
expect(result.failure).to eq("Invalid input: #{params}. Time string is required.")
end
end

context 'when time_string is not a String' do
let(:params) { { time_string: 12345 } }

it 'returns a failure' do
result = subject.call(params)
expect(result).to be_failure
expect(result.failure).to eq("Invalid input: #{params}. Time string must be a String.")
end
end

context 'when time_string is a valid ISO8601 string' do
let(:params) { { time_string: '2024-10-14T17:28:44.106928000+0000' } }

it 'returns a success' do
result = subject.call(params)
expect(result).to be_success
expect(result.value!).to be_a(Time)
end
end

context 'when time_string is an invalid ISO8601 string' do
let(:params) { { time_string: 'invalid-time-string' } }

it 'returns a failure' do
result = subject.call(params)
expect(result).to be_failure
expect(result.failure).to include(
"with time input: #{params[:time_string]}. Time string must match the format #{AcaEntities::Types::DATETIME_FORMAT_ISO8601}."
)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

require 'spec_helper'
require 'aca_entities/types'
require 'aca_entities/operations/date_time_transforms/convert_time_to_string'
require 'active_support/time'

RSpec.describe AcaEntities::Operations::DateTimeTransforms::ConvertTimeToString do
describe '#call' do
context 'when the input is a valid Time object' do
let(:input_params) { { time: Time.now } }

it 'returns a success' do
result = subject.call(input_params)
expect(result).to be_success
expect(result.value!).to be_a(String)
end
end

context 'when the input is valid ActiveSupport::TimeWithZone object' do
let(:input_params) do
Time.zone = 'UTC'
{ time: Time.zone.now }
end

it 'returns a success' do
result = subject.call(input_params)
expect(result).to be_success
expect(result.value!).to be_a(String)
end
end

context 'when the input is nil' do
let(:input_params) { nil }

it 'returns a failure' do
result = subject.call(input_params)
expect(result).to be_failure
expect(result.failure).to eq('Invalid input: params cannot be nil.')
end
end

context 'when the input value for time is nil' do
let(:input_params) { { time: nil } }

it 'returns a failure' do
result = subject.call(input_params)
expect(result).to be_failure
expect(result.failure).to eq("Invalid input: #{input_params}. Time is required.")
end
end

context 'when time is not a Time object' do
let(:input_params) { { time: 'not a time object' } }

it 'returns a failure' do
result = subject.call(input_params)
expect(result).to be_failure
expect(result.failure).to eq("Invalid input: #{input_params}. Time must be a Time object.")
end
end
end
end

0 comments on commit 9786695

Please sign in to comment.