Skip to content

Commit

Permalink
Merge pull request #400 from sebasjimenez10/sj/fix-multi-word-custom-…
Browse files Browse the repository at this point in the history
…endpoint

fix: Multi-word custom endpoint not respecting route format
  • Loading branch information
gaorlov committed May 2, 2024
2 parents afeb8f8 + f7a4cef commit 5d46961
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 3 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

## Unreleased

## 1.22.0

- [#400](https://github.com/JsonApiClient/json_api_client/pull/400) - Fix for multi-word custom endpoint and route format

## 1.22.0
- [#403](https://github.com/JsonApiClient/json_api_client/pull/403) - Feature: Use the association options to lookup relationship class
- [#406](https://github.com/JsonApiClient/json_api_client/pull/406) - Deep-merge nested `additional_params`

Expand Down
17 changes: 15 additions & 2 deletions lib/json_api_client/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,11 @@ def collection_endpoint(name, options = {})
metaclass = class << self
self
end
endpoint_name = _name_for_route_format(name)
metaclass.instance_eval do
define_method(name) do |*params|
request_params = params.first || {}
requestor.custom(name, options, request_params)
requestor.custom(endpoint_name, options, request_params)
end
end
end
Expand All @@ -274,10 +275,11 @@ def collection_endpoint(name, options = {})
# @param options [Hash] endpoint options
# @option options [Symbol] :request_method The request method (:get, :post, etc)
def member_endpoint(name, options = {})
endpoint_name = self._name_for_route_format(name)
define_method name do |*params|
request_params = params.first || {}
request_params[self.class.primary_key] = attributes.fetch(self.class.primary_key)
self.class.requestor.custom(name, options, request_params)
self.class.requestor.custom(endpoint_name, options, request_params)
end
end

Expand Down Expand Up @@ -348,6 +350,17 @@ def _build_connection(rebuild = false)
yield(conn) if block_given?
end
end

def _name_for_route_format(name)
case self.route_format
when :dasherized_route
name.to_s.dasherize
when :camelized_route
name.to_s.camelize(:lower)
else
name
end
end
end

# Instantiate a new resource object
Expand Down
86 changes: 86 additions & 0 deletions test/unit/custom_endpoint_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ class Country < TestResource

end

class Pet < TestResource
self.site = "http://example.com/"
self.route_format = :dasherized_route

custom_endpoint :related_pets, on: :member, request_method: :get
custom_endpoint :vip_pets, on: :collection, request_method: :get

end

class MythicBeasts < TestResource
self.site = "http://example.com/"
self.route_format = :camelized_route

custom_endpoint :related_beasts, on: :member, request_method: :get
custom_endpoint :ancient_beasts, on: :collection, request_method: :get

end

class CustomEndpointTest < Minitest::Test

def test_collection_get
Expand Down Expand Up @@ -43,4 +61,72 @@ def test_collection_methods_should_not_add_methods_to_all_classes
assert !Class.respond_to?(:autocomplete), "adding a custom method should not add methods to all classes"
end

def test_member_dasherized_route_format_converts_custom_endpoint
stub_request(:get, "http://example.com/pets/1/related-pets")
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
data: [
{id: 1, type: 'pets'},
{id: 2, type: 'pets'},
]
}.to_json)

pet = Pet.new({id: 1, name: 'Otto'})
pet.mark_as_persisted!

related_pets = pet.related_pets

assert_equal 2, related_pets.length
assert_equal [1,2], related_pets.map(&:id)
end

def test_collection_dasherized_route_format_converts_custom_endpoint
stub_request(:get, "http://example.com/pets/vip-pets")
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
data: [
{id: 4, type: 'pets'},
{id: 5, type: 'pets'},
{id: 6, type: 'pets'}
]
}.to_json)

vip_pets = Pet.vip_pets

assert_equal 3, vip_pets.length
assert_equal [4,5,6], vip_pets.map(&:id)
end

def test_member_camelized_route_format_converts_custom_endpoint
stub_request(:get, "http://example.com/mythicBeasts/1/relatedBeasts")
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
data: [
{id: 1, type: 'mythic-beasts'},
{id: 2, type: 'mythic-beasts'},
]
}.to_json)

dragon = MythicBeasts.new({id: 1, name: 'Dragon'})
dragon.mark_as_persisted!

related_beasts = dragon.related_beasts

assert_equal 2, related_beasts.length
assert_equal [1,2], related_beasts.map(&:id)
end

def test_collection_camelized_route_format_converts_custom_endpoint
stub_request(:get, "http://example.com/mythicBeasts/ancientBeasts")
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
data: [
{id: 4, type: 'mythic-beasts'},
{id: 5, type: 'mythic-beasts'},
{id: 6, type: 'mythic-beasts'}
]
}.to_json)

ancient_beasts = MythicBeasts.ancient_beasts

assert_equal 3, ancient_beasts.length
assert_equal [4,5,6], ancient_beasts.map(&:id)
end

end

0 comments on commit 5d46961

Please sign in to comment.