From 9378d9208160817fd3bb518797f5031e59fd75b8 Mon Sep 17 00:00:00 2001 From: Randy Villanueva Date: Thu, 22 Apr 2021 18:18:36 -0700 Subject: [PATCH 1/6] feat: Add the ability to create a subclass of JsonApiClient::Resource to have a modified id method that returns the id as an integer. This gives the application code the flexibility to match against attributes of other resources that are integers. --- lib/json_api_client/included_data.rb | 2 +- test/unit/integer_id_test.rb | 183 +++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 test/unit/integer_id_test.rb diff --git a/lib/json_api_client/included_data.rb b/lib/json_api_client/included_data.rb index 8cf689c7..3018f751 100644 --- a/lib/json_api_client/included_data.rb +++ b/lib/json_api_client/included_data.rb @@ -24,7 +24,7 @@ def initialize(result_set, data) end grouped_included_set.each do |type, resources| - grouped_included_set[type] = resources.index_by(&:id) + grouped_included_set[type] = resources.index_by { |resource| resource.attributes[:id] } end @data = grouped_included_set diff --git a/test/unit/integer_id_test.rb b/test/unit/integer_id_test.rb new file mode 100644 index 00000000..ec3cbb0e --- /dev/null +++ b/test/unit/integer_id_test.rb @@ -0,0 +1,183 @@ +# frozen_string_literal: true + +require 'test_helper' + +## +# Test checks to see if overriding id as integer +# prserves the ability to lazy load, or +class BaseResource < JsonApiClient::Resource + self.site = 'http://example.com/' + def id + attributes[:id].to_i if attributes[:id].present? + end +end + +class Actor < BaseResource + has_many :movies +end + +class Movie < BaseResource + belongs_to :actor, shallow_path: true + has_one :director, shallow_path: true +end + +class Director < BaseResource + has_many :movies +end + +class IntegerIdTestAssociationTest < MiniTest::Test + def included_document_test_id_from_method_as_integer + stub_request(:get, 'http://example.com/movies/1?include=actor') + .to_return(headers: { content_type: 'application/vnd.api+json', + accept: 'application/vnd.api+json' }, + body: { + data: { + id: '1', + type: 'movie', + attributes: { + actor_id: 1, + director_id: 1, + created_at: '2021-04-20T17:27:06-07:00', + updated_at: '2021-04-20T17:27:07-07:00' + }, + relationships: { + actor: { + data: { + id: '1', + type: 'actor' + } + }, + director: { + data: { + id: '1', + type: 'director' + } + } + } + }, + included: [ + { + id: '1', + type: 'actor', + attributes: { + name: 'Keanu', + updated_at: '2021-04-22T13:50:19-07:00', + created_at: '2021-04-19T16:20:13-07:00' + } + } + ] + }.to_json) + movie = Movie.includes(:actor).find(1).last + assert_equal(Integer, movie.id.class) + assert_equal(1, movie.id) + assert_equal(String, movie.attributes[:id].class) + assert_equal('1', movie.attributes[:id]) + assert_equal(Owner, movie.actor.class) + assert_equal(Integer, movie.actor.id.class) + assert_equal(1, movie.actor.id) + assert_equal('1', movie.actor.attributes[:id]) + assert_equal(movie.actor_id, movie.actor.id) + end + + def test_not_included_data_document + stub_request(:get, 'http://example.com/movies/1') + .to_return(headers: { content_type: 'application/vnd.api+json', + accept: 'application/vnd.api+json' }, + body: { + data: { + id: '1', + type: 'movie', + attributes: { + actor_id: 1, + created_at: '2021-04-20T17:27:06-07:00', + updated_at: '2021-04-20T17:27:07-07:00' + }, + relationships: { + actor: { + data: { + id: '1', + type: 'actor' + }, + director: { + data: { + id: '1', + type: 'director' + } + } + } + } + } + }.to_json) + movie = Movie.find(1).last + assert_equal(Integer, movie.id.class) + assert_equal(1, movie.id) + assert_equal(String, movie.attributes[:id].class) + assert_equal('1', movie.attributes[:id]) + assert_nil(movie.actor) + end + + def test_not_included_data_document_with_relationships_links + stub_request(:get, 'http://example.com/movies/1') + .to_return(headers: { content_type: 'application/vnd.api+json', + accept: 'application/vnd.api+json' }, + body: { + data: { + id: '1', + type: 'movie', + attributes: { + actor_id: 1, + created_at: '2021-04-20T17:27:06-07:00', + updated_at: '2021-04-20T17:27:07-07:00' + }, + relationships: { + actor: { + links: { + self: '/movies/1', + related: '/actors/1' + } + }, + director: { + links: { + self: '/movies/1', + related: '/directors/1' + } + } + } + } + }.to_json) + stub_request(:get, 'http://example.com/directors/1') + .to_return(headers: { content_type: 'application/vnd.api+json', + accept: 'application/vnd.api+json' }, + body: { + data: { + id: '1', + type: 'movie', + attributes: { + actor_id: 1, + created_at: '2021-04-20T17:27:06-07:00', + updated_at: '2021-04-20T17:27:07-07:00' + }, + relationships: { + actor: { + links: { + self: '/movies/1', + related: '/actors/1' + } + }, + director: { + links: { + self: '/movies/1', + related: '/directors/1' + } + } + } + } + }.to_json) + movie = Movie.find(1).last + assert_equal(Integer, movie.id.class) + assert_equal(1, movie.id) + assert_equal(String, movie.attributes[:id].class) + assert_equal('1', movie.attributes[:id]) + assert_equal(Director, movie.director.class) + end +end From 5f533b157b56045d042017a9508341bd3cd50cfd Mon Sep 17 00:00:00 2001 From: Randy Villanueva Date: Tue, 30 May 2023 17:20:09 -0700 Subject: [PATCH 2/6] task: add to unreleased changelog pull 378 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92fd7a55..d7b824b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Unreleased +- [378](https://github.com/JsonApiClient/json_api_client/pull/378) - Add the ability to create a subclass of JsonApiClient::Resource to have a modified id method ## 1.21.0 - [#395](https://github.com/JsonApiClient/json_api_client/pull/395) - relaxing faraday dependency to anything less than 2.0 From 464363c537408cc88900e55e0e20b53341571689 Mon Sep 17 00:00:00 2001 From: Randy Villanueva Date: Tue, 30 May 2023 17:25:27 -0700 Subject: [PATCH 3/6] task: test cleanup --- test/unit/integer_id_test.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/unit/integer_id_test.rb b/test/unit/integer_id_test.rb index ec3cbb0e..6cc7a51c 100644 --- a/test/unit/integer_id_test.rb +++ b/test/unit/integer_id_test.rb @@ -2,9 +2,6 @@ require 'test_helper' -## -# Test checks to see if overriding id as integer -# prserves the ability to lazy load, or class BaseResource < JsonApiClient::Resource self.site = 'http://example.com/' def id From a45fdc87852e3861b53c753a145d3c2738380642 Mon Sep 17 00:00:00 2001 From: Randy Villanueva Date: Tue, 30 May 2023 17:37:11 -0700 Subject: [PATCH 4/6] fix: minitest --- test/unit/integer_id_test.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/unit/integer_id_test.rb b/test/unit/integer_id_test.rb index 6cc7a51c..051cb253 100644 --- a/test/unit/integer_id_test.rb +++ b/test/unit/integer_id_test.rb @@ -23,7 +23,8 @@ class Director < BaseResource end class IntegerIdTestAssociationTest < MiniTest::Test - def included_document_test_id_from_method_as_integer + + def test_included_document_test_id_from_method_as_integer stub_request(:get, 'http://example.com/movies/1?include=actor') .to_return(headers: { content_type: 'application/vnd.api+json', accept: 'application/vnd.api+json' }, @@ -69,7 +70,7 @@ def included_document_test_id_from_method_as_integer assert_equal(1, movie.id) assert_equal(String, movie.attributes[:id].class) assert_equal('1', movie.attributes[:id]) - assert_equal(Owner, movie.actor.class) + assert_equal(Actor, movie.actor.class) assert_equal(Integer, movie.actor.id.class) assert_equal(1, movie.actor.id) assert_equal('1', movie.actor.attributes[:id]) From 51b4849a08bf800c4b0de7428412e434a855d398 Mon Sep 17 00:00:00 2001 From: Randy Villanueva Date: Fri, 2 Jun 2023 11:01:53 -0700 Subject: [PATCH 5/6] fix: minitest for ruby < 2.4 --- test/unit/integer_id_test.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/unit/integer_id_test.rb b/test/unit/integer_id_test.rb index 051cb253..a2cc6b74 100644 --- a/test/unit/integer_id_test.rb +++ b/test/unit/integer_id_test.rb @@ -22,6 +22,9 @@ class Director < BaseResource has_many :movies end + +NUMERIC_ASSERTION = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.4') ? Fixnum : Integer + class IntegerIdTestAssociationTest < MiniTest::Test def test_included_document_test_id_from_method_as_integer @@ -66,12 +69,12 @@ def test_included_document_test_id_from_method_as_integer ] }.to_json) movie = Movie.includes(:actor).find(1).last - assert_equal(Integer, movie.id.class) + assert_equal(NUMERIC_ASSERTION, movie.id.class) assert_equal(1, movie.id) assert_equal(String, movie.attributes[:id].class) assert_equal('1', movie.attributes[:id]) assert_equal(Actor, movie.actor.class) - assert_equal(Integer, movie.actor.id.class) + assert_equal(NUMERIC_ASSERTION, movie.actor.id.class) assert_equal(1, movie.actor.id) assert_equal('1', movie.actor.attributes[:id]) assert_equal(movie.actor_id, movie.actor.id) @@ -107,7 +110,7 @@ def test_not_included_data_document } }.to_json) movie = Movie.find(1).last - assert_equal(Integer, movie.id.class) + assert_equal(NUMERIC_ASSERTION, movie.id.class) assert_equal(1, movie.id) assert_equal(String, movie.attributes[:id].class) assert_equal('1', movie.attributes[:id]) @@ -172,7 +175,7 @@ def test_not_included_data_document_with_relationships_links } }.to_json) movie = Movie.find(1).last - assert_equal(Integer, movie.id.class) + assert_equal(NUMERIC_ASSERTION, movie.id.class) assert_equal(1, movie.id) assert_equal(String, movie.attributes[:id].class) assert_equal('1', movie.attributes[:id]) From 2b02acf7a043adc69a86f41859e930d243a2d985 Mon Sep 17 00:00:00 2001 From: Randy Villanueva Date: Fri, 2 Jun 2023 11:02:23 -0700 Subject: [PATCH 6/6] fix: remove extra newline --- test/unit/integer_id_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/integer_id_test.rb b/test/unit/integer_id_test.rb index a2cc6b74..8c8bf04d 100644 --- a/test/unit/integer_id_test.rb +++ b/test/unit/integer_id_test.rb @@ -22,7 +22,6 @@ class Director < BaseResource has_many :movies end - NUMERIC_ASSERTION = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.4') ? Fixnum : Integer class IntegerIdTestAssociationTest < MiniTest::Test