Skip to content

Commit

Permalink
Handle loading attributes with special characters
Browse files Browse the repository at this point in the history
  • Loading branch information
paulomarg committed Apr 7, 2022
1 parent f163bfc commit d69bdf1
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 13 deletions.
57 changes: 45 additions & 12 deletions lib/shopify_api/rest/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Base
@paths = T.let([], T::Array[T::Hash[Symbol, T.any(T::Array[Symbol], String, Symbol)]])
@custom_prefix = T.let(nil, T.nilable(String))

@aliased_properties = T.let({}, T::Hash[String, String])

sig { returns(T::Hash[Symbol, T.untyped]) }
attr_accessor :original_state

Expand All @@ -32,6 +34,7 @@ def initialize(session: nil, from_hash: nil)
@original_state = T.let({}, T::Hash[Symbol, T.untyped])
@custom_prefix = T.let(nil, T.nilable(String))
@forced_nils = T.let({}, T::Hash[String, T::Boolean])
@aliased_properties = T.let({}, T::Hash[String, String])

session ||= ShopifyAPI::Context.active_session

Expand All @@ -42,7 +45,7 @@ def initialize(session: nil, from_hash: nil)
@errors = T.let(Rest::BaseErrors.new, Rest::BaseErrors)

from_hash&.each do |key, value|
instance_variable_set("@#{key}", value)
set_property(key, value)
end
end

Expand Down Expand Up @@ -235,13 +238,13 @@ def create_instance(data:, session:, instance: nil)
def method_missing(meth_id, val = nil)
match = meth_id.id2name.match(/([^=]+)(=)?/)

var = match[1]
var = T.must(T.must(match)[1])

if match[2]
instance_variable_set("@#{var}", val)
@forced_nils[T.must(var)] = val.nil?
if T.must(match)[2]
set_property(var, val)
@forced_nils[var] = val.nil?
else
instance_variable_get("@#{var}")
get_property(var)
end
end

Expand All @@ -257,17 +260,30 @@ def respond_to_missing?(meth_id, *args)
def to_hash
hash = {}
instance_variables.each do |var|
next if [:"@original_state", :"@session", :"@client", :"@forced_nils", :"@errors"].include?(var)
next if [
:"@original_state",
:"@session",
:"@client",
:"@forced_nils",
:"@errors",
:"@aliased_properties",
].include?(var)

var = var.to_s.delete("@")
attribute = if @aliased_properties.value?(var)
T.must(@aliased_properties.key(var))
else
var
end.to_sym

attribute = var.to_s.delete("@").to_sym
if self.class.has_many?(attribute)
hash[attribute.to_s] = instance_variable_get(var).map(&:to_hash).to_a if instance_variable_get(var)
hash[attribute.to_s] = get_property(attribute).map(&:to_hash).to_a if get_property(attribute)
elsif self.class.has_one?(attribute)
element_hash = instance_variable_get(var)&.to_hash
element_hash = get_property(attribute)&.to_hash
hash[attribute.to_s] = element_hash if element_hash || @forced_nils[attribute.to_s]
elsif !instance_variable_get(var).nil? || @forced_nils[attribute.to_s]
elsif !get_property(attribute).nil? || @forced_nils[attribute.to_s]
hash[attribute.to_s] =
instance_variable_get(var)
get_property(attribute)
end
end
hash
Expand Down Expand Up @@ -312,6 +328,23 @@ def save(update_object: false)
@errors.errors << e
raise
end

private

sig { params(var: T.any(String, Symbol), val: T.untyped).void }
def set_property(var, val)
clean = var.to_s.gsub(/[\?\s]/, "")
@aliased_properties[var.to_s] = clean if clean != var

instance_variable_set("@#{clean}", val)
end

sig { params(var: T.any(String, Symbol)).returns(T.untyped) }
def get_property(var)
clean = @aliased_properties.key?(var.to_s) ? @aliased_properties[var.to_s] : var

instance_variable_get("@#{clean}")
end
end
end
end
14 changes: 13 additions & 1 deletion test/clients/base_rest_resource_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,26 @@ def test_deletes_existing_resource_and_fails_on_deleting_nonexistent_resource
assert_requested(stubbed_request)
end

def test_load_unknown_attribute
def test_loads_unknown_attribute
body = { fake_resource: { id: 1, attribute: "attribute", unknown: "some-value" } }.to_json

stub_request(:get, "#{@prefix}/fake_resources/1.json").to_return(body: body)

resource = TestHelpers::FakeResource.find(id: 1, session: @session)

assert_equal("some-value", resource.unknown)
assert_equal("some-value", resource.to_hash["unknown"])
end

def test_loads_unknown_attribute_with_special_character
body = { fake_resource: { id: 1, attribute: "attribute", "unknown?": "some-value" } }.to_json

stub_request(:get, "#{@prefix}/fake_resources/1.json").to_return(body: body)

resource = TestHelpers::FakeResource.find(id: 1, session: @session)

assert_equal("some-value", resource.unknown?)
assert_equal("some-value", resource.to_hash["unknown?"])
end

def test_save_with_unknown_attribute
Expand Down

0 comments on commit d69bdf1

Please sign in to comment.