Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add date and datetime conversions #56

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
7 changes: 5 additions & 2 deletions lib/fulfil/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'http'
require 'logger'
require 'fulfil/response_parser'
require 'fulfil/domain_parser'

module Fulfil
SUBDOMAIN = ENV.fetch('FULFIL_SUBDOMAIN', nil)
Expand Down Expand Up @@ -69,15 +70,17 @@ def find_many(model:, ids:, fields: nil)

def search(model:, domain:, offset: nil, limit: 100, sort: nil, fields: %w[id])
uri = URI("#{model_url(model: model)}/search_read")
body = [domain, offset, limit, sort, fields]
parsed_domain = Fulfil::DomainParser.new(domain).parsed
body = [parsed_domain, offset, limit, sort, fields]

results = request(verb: :put, endpoint: uri, json: body)
parse(results: results)
end

def count(model:, domain:)
uri = URI("#{model_url(model: model)}/search_count")
body = [domain]
parsed_domain = Fulfil::DomainParser.new(domain).parsed
body = [parsed_domain]

request(verb: :put, endpoint: uri, json: body)
end
Expand Down
20 changes: 20 additions & 0 deletions lib/fulfil/converter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Fulfil
# The Fulfil::Conversions module provides utility methods for converting
# Date and DateTime objects into a standardized hash format.
class Converter
class << self
def datetime_as_object(datetime)
{
__class__: 'datetime',
iso_string: datetime.new_offset(0).iso8601
}
end

def date_as_object(date)
datetime_as_object(date.to_datetime)
end
end
end
end
64 changes: 64 additions & 0 deletions lib/fulfil/domain_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

require 'fulfil/converter'

module Fulfil
# The Fulfil::DomainParser module provides utility methods for converting
# Date and DateTime objects into a standardized hash format.
# The module iterates over given parameters, identifies
# Date and DateTime objects, and converts them into a hash with a class descriptor
# and an ISO 8601 formatted string.
class DomainParser
attr_reader :domain

def initialize(domain)
@domain = domain

disable_escape_html_entities
end

def parsed
new_domain = domain.map do |values|
update_values(values)
end

enable_escape_html_entities
new_domain
end

def update_values(values)
values.map do |value|
case value.class.name
when 'Date'
date_as_object(value)
when 'DateTime'
datetime_as_object(value)
else
value
end
end
end

private

def date_as_object(date)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fulfil::DomainParser#date_as_object doesn't depend on instance state (maybe move it to another class?)

Converter.date_as_object(date)
end

def datetime_as_object(datetime)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fulfil::DomainParser#datetime_as_object doesn't depend on instance state (maybe move it to another class?)

Converter.datetime_as_object(datetime)
end

def disable_escape_html_entities
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fulfil::DomainParser#disable_escape_html_entities doesn't depend on instance state (maybe move it to another class?)

return unless defined?(ActiveSupport) && ActiveSupport.respond_to?(:escape_html_entities_in_json=)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fulfil::DomainParser#disable_escape_html_entities manually dispatches method call

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cdmwebs rake test was erroring out when my guard clause was only return unless defined?(ActiveSupport) not sure exactly what to do to fix this codeclimate reek.


ActiveSupport.escape_html_entities_in_json = false
end

def enable_escape_html_entities
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fulfil::DomainParser#enable_escape_html_entities doesn't depend on instance state (maybe move it to another class?)

return unless defined?(ActiveSupport) && ActiveSupport.respond_to?(:escape_html_entities_in_json=)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fulfil::DomainParser#enable_escape_html_entities manually dispatches method call


ActiveSupport.escape_html_entities_in_json = true
end
end
end
1 change: 1 addition & 0 deletions lib/fulfil/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def search(
offset: nil,
sort: nil
)

@client.search(
model: model,
domain: domain,
Expand Down
77 changes: 77 additions & 0 deletions test/fulfil/client_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'test_helper'
require 'date'

module Fulfil
class ClientTest < Minitest::Test
Expand Down Expand Up @@ -68,5 +69,81 @@ def test_do_not_retry_when_retry_is_disabled
end
end
end

def test_date_conversion_in_search
date = Date.new(2022, 1, 1)
datetime = date.to_datetime
utc_datetime = datetime.new_offset(0)
expected_formatted_date = {
__class__: 'datetime',
iso_string: utc_datetime.iso8601
}

# Convert the expected hash's symbol keys to strings for comparison
expected_formatted_date_with_string_keys = expected_formatted_date.transform_keys(&:to_s)

stub_request(:put, fulfil_url_for('sale.sale/search_read'))
.to_return(status: 200, body: [].to_json, headers: { 'Content-Type' => 'application/json' })

client = Fulfil::Client.new
fulfil_model = Fulfil::Model.new(client: client, model_name: 'sale.sale')
fulfil_model.search(domain: [['create_date', '>=', date]])

assert_requested(:put, fulfil_url_for('sale.sale/search_read'), times: 1) do |request|
actual_formatted_date = JSON.parse(request.body).dig(0, 0, 2)

assert_equal expected_formatted_date_with_string_keys, actual_formatted_date
end
end

def test_datetime_conversion_in_search
datetime = DateTime.new(2022, 1, 1, 12, 0, 0)
utc_datetime = datetime.new_offset(0)
expected_formatted_date = {
__class__: 'datetime',
iso_string: utc_datetime.iso8601
}

# Convert the expected hash's symbol keys to strings for comparison
expected_formatted_date_with_string_keys = expected_formatted_date.transform_keys(&:to_s)

stub_request(:put, fulfil_url_for('sale.sale/search_read'))
.to_return(status: 200, body: [].to_json, headers: { 'Content-Type' => 'application/json' })

client = Fulfil::Client.new
fulfil_model = Fulfil::Model.new(client: client, model_name: 'sale.sale')
fulfil_model.search(domain: [['create_date', '>=', datetime]])

assert_requested(:put, fulfil_url_for('sale.sale/search_read'), times: 1) do |request|
actual_formatted_date = JSON.parse(request.body).dig(0, 0, 2)

assert_equal expected_formatted_date_with_string_keys, actual_formatted_date
end
end

def test_datetime_conversion_in_count
datetime = DateTime.new(2022, 1, 1, 12, 0, 0)
utc_datetime = datetime.new_offset(0)
expected_formatted_date = {
__class__: 'datetime',
iso_string: utc_datetime.iso8601
}

# Convert the expected hash's symbol keys to strings for comparison
expected_formatted_date_with_string_keys = expected_formatted_date.transform_keys(&:to_s)

stub_request(:put, fulfil_url_for('sale.sale/search_count'))
.to_return(status: 200, body: [].to_json, headers: { 'Content-Type' => 'application/json' })

client = Fulfil::Client.new
fulfil_model = Fulfil::Model.new(client: client, model_name: 'sale.sale')
fulfil_model.count(domain: [['create_date', '>=', datetime]])

assert_requested(:put, fulfil_url_for('sale.sale/search_count'), times: 1) do |request|
actual_formatted_date = JSON.parse(request.body).dig(0, 0, 2)

assert_equal expected_formatted_date_with_string_keys, actual_formatted_date
end
end
end
end
Loading