You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a resource includes some field that is false, trying to read it through the Link class will result in the value being returned as nil instead of false.
Test case:
diff --git a/test/hyperclient/link_test.rb b/test/hyperclient/link_test.rb
index 823efa6..20e8872 100644
--- a/test/hyperclient/link_test.rb+++ b/test/hyperclient/link_test.rb@@ -479,6 +479,16 @@ module Hyperclient
resource.orders.first.id.must_equal 1
end
+ it 'can handle false values in the response' do+ resource = Resource.new({ '_links' => { 'orders' => { 'href' => '/orders' } } }, entry_point)++ stub_request(entry_point.connection) do |stub|+ stub.get('http://api.example.org/orders') { [200, {}, { 'any' => false }] }+ end++ resource.orders.any.must_equal false+ end+
it "doesn't delegate when link key doesn't match" do
resource = Resource.new({ '_links' => { 'foos' => { 'href' => '/orders' } } }, entry_point)
# Internal: Delegate the method further down the API if the resource cannot serve it.defmethod_missing(method, *args, &block)if_resource.respond_to?(method.to_s)_resource.send(method, *args, &block) || delegate_method(method, *args, &block)elsesuperendend
In this case, _resource.send(method, *args, &block) is returning false, which we are mistaking for the case where we're trying to call an array method on the resource, and thus instead of returning false we are calling delegate_method (which will then return the nil).
I was thinking about it and it seems to me that changing it to treat false differently would fix the issue:
diff --git a/lib/hyperclient/link.rb b/lib/hyperclient/link.rb
index 1fd1169..cc5b635 100644
--- a/lib/hyperclient/link.rb+++ b/lib/hyperclient/link.rb@@ -126,7 +126,8 @@ module Hyperclient
# Internal: Delegate the method further down the API if the resource cannot serve it.
def method_missing(method, *args, &block)
if _resource.respond_to?(method.to_s)
- _resource.send(method, *args, &block) || delegate_method(method, *args, &block)+ result = _resource.send(method, *args, &block)+ result.nil? ? delegate_method(method, *args, &block) : result
else
super
end
But I was not entirely sure, hence I decided to open an issue first, instead of jumping straight to a PR. Any thoughts on this approach?
The text was updated successfully, but these errors were encountered:
Whenever a resource includes a field that is `false`, trying to access
it through a `Link` returned `nil`, rather than `false`.
This is because `Link` confused the `false` response with the resource
not actually handling the value, and then tried to use the delegation as
if a collection method was being called on the resource.
Fixes#126
Whenever a resource includes a field that is `false`, trying to access
it through a `Link` returned `nil`, rather than `false`.
This is because `Link` confused the `false` response with the resource
not actually handling the value, and then tried to use the delegation as
if a collection method was being called on the resource.
Fixes#126
* Fix link delegation returning nil for field with value false
Whenever a resource includes a field that is `false`, trying to access
it through a `Link` returned `nil`, rather than `false`.
This is because `Link` confused the `false` response with the resource
not actually handling the value, and then tried to use the delegation as
if a collection method was being called on the resource.
Fixes#126
* Update CHANGELOG
When a resource includes some field that is
false
, trying to read it through theLink
class will result in the value being returned asnil
instead offalse
.Test case:
Current result:
This seems to me to be due to a bad interaction in
Link#method_missing
(https://github.com/codegram/hyperclient/blob/master/lib/hyperclient/link.rb#L129):In this case,
_resource.send(method, *args, &block)
is returningfalse
, which we are mistaking for the case where we're trying to call an array method on the resource, and thus instead of returningfalse
we are callingdelegate_method
(which will then return thenil
).I was thinking about it and it seems to me that changing it to treat
false
differently would fix the issue:But I was not entirely sure, hence I decided to open an issue first, instead of jumping straight to a PR. Any thoughts on this approach?
The text was updated successfully, but these errors were encountered: