Skip to content

Commit 646e438

Browse files
authored
Merge pull request #831 from cerebris/complex_includes_tests_fix
Complex includes tests fix
2 parents ab99cba + d6f7a4f commit 646e438

8 files changed

Lines changed: 162 additions & 1 deletion

File tree

lib/jsonapi/resource_serializer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ def add_included_object(id, object_hash, primary = false)
348348
@included_objects[type] = {} unless @included_objects.key?(type)
349349

350350
if already_serialized?(type, id)
351-
@included_objects[type][id][:object_hash].merge!(object_hash)
351+
@included_objects[type][id][:object_hash].deep_merge!(object_hash)
352352
set_primary(type, id) if primary
353353
else
354354
@included_objects[type].store(id, primary: primary, object_hash: object_hash)

test/controllers/controller_test.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3599,3 +3599,70 @@ def test_whitelisted_error_in_controller
35993599
$PostProcessorRaisesErrors = false
36003600
end
36013601
end
3602+
3603+
3604+
class Api::BoxesControllerTest < ActionController::TestCase
3605+
def test_complex_includes_base
3606+
get :index
3607+
assert_response :success
3608+
end
3609+
3610+
def test_complex_includes_two_level
3611+
get :index, params: {include: 'things,things.user'}
3612+
3613+
assert_response :success
3614+
3615+
assert_equal '1', json_response['included'][0]['id']
3616+
assert_equal 'users', json_response['included'][0]['type']
3617+
assert_nil json_response['included'][0]['relationships']['things']['data']
3618+
3619+
# The test is hardcoded with the include order. This should be changed at some point since either thing could come first and still be valid
3620+
assert_equal '1', json_response['included'][1]['id']
3621+
assert_equal 'things', json_response['included'][1]['type']
3622+
assert_equal '1', json_response['included'][1]['relationships']['user']['data']['id']
3623+
assert_nil json_response['included'][1]['relationships']['things']['data']
3624+
3625+
assert_equal '2', json_response['included'][2]['id']
3626+
assert_equal 'things', json_response['included'][2]['type']
3627+
assert_equal '1', json_response['included'][2]['relationships']['user']['data']['id']
3628+
assert_nil json_response['included'][2]['relationships']['things']['data']
3629+
end
3630+
3631+
def test_complex_includes_things_nested_things
3632+
get :index, params: {include: 'things,things.things'}
3633+
3634+
assert_response :success
3635+
3636+
# The test is hardcoded with the include order. This should be changed at some point since either thing could come first and still be valid
3637+
assert_equal '2', json_response['included'][0]['id']
3638+
assert_equal 'things', json_response['included'][0]['type']
3639+
assert_nil json_response['included'][0]['relationships']['user']['data']
3640+
assert_equal '1', json_response['included'][0]['relationships']['things']['data'][0]['id']
3641+
3642+
assert_equal '1', json_response['included'][1]['id']
3643+
assert_equal 'things', json_response['included'][1]['type']
3644+
assert_nil json_response['included'][1]['relationships']['user']['data']
3645+
assert_equal '2', json_response['included'][1]['relationships']['things']['data'][0]['id']
3646+
end
3647+
3648+
def test_complex_includes_nested_things_secondary_users
3649+
get :index, params: {include: 'things,things.user,things.things'}
3650+
3651+
assert_response :success
3652+
3653+
assert_equal '1', json_response['included'][0]['id']
3654+
assert_equal 'users', json_response['included'][0]['type']
3655+
assert_nil json_response['included'][0]['relationships']['things']['data']
3656+
3657+
# The test is hardcoded with the include order. This should be changed at some point since either thing could come first and still be valid
3658+
assert_equal '2', json_response['included'][1]['id']
3659+
assert_equal 'things', json_response['included'][1]['type']
3660+
assert_equal '1', json_response['included'][1]['relationships']['user']['data']['id']
3661+
assert_equal '1', json_response['included'][1]['relationships']['things']['data'][0]['id']
3662+
3663+
assert_equal '1', json_response['included'][2]['id']
3664+
assert_equal 'things', json_response['included'][2]['type']
3665+
assert_equal '1', json_response['included'][2]['relationships']['user']['data']['id']
3666+
assert_equal '2', json_response['included'][2]['relationships']['things']['data'][0]['id']
3667+
end
3668+
end

test/fixtures/active_record.rb

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,33 @@
248248

249249
create_table :questionables, force: true do |t|
250250
end
251+
252+
create_table :boxes, force: true do |t|
253+
t.string :name
254+
t.timestamps null: false
255+
end
256+
257+
create_table :things, force: true do |t|
258+
t.string :name
259+
t.references :user
260+
t.references :box
261+
262+
t.timestamps null: false
263+
end
264+
265+
create_table :users, force: true do |t|
266+
t.string :name
267+
t.timestamps null: false
268+
end
269+
270+
create_table :related_things, force: true do |t|
271+
t.string :name
272+
t.references :from, references: :thing
273+
t.references :to, references: :thing
274+
275+
t.timestamps null: false
276+
end
277+
251278
# special cases
252279
end
253280

@@ -538,6 +565,27 @@ class Make < ActiveRecord::Base
538565
class WebPage < ActiveRecord::Base
539566
end
540567

568+
class Box < ActiveRecord::Base
569+
has_many :things
570+
end
571+
572+
class User < ActiveRecord::Base
573+
has_many :things
574+
end
575+
576+
class Thing < ActiveRecord::Base
577+
belongs_to :box
578+
belongs_to :user
579+
580+
has_many :related_things, foreign_key: :from_id
581+
has_many :things, through: :related_things, source: :to
582+
end
583+
584+
class RelatedThing < ActiveRecord::Base
585+
belongs_to :from, class_name: Thing, foreign_key: :from_id
586+
belongs_to :to, class_name: Thing, foreign_key: :to_id
587+
end
588+
541589
module Api
542590
module V7
543591
class Client < Customer
@@ -794,6 +842,11 @@ class NumerosTelefoneController < JSONAPI::ResourceController
794842
end
795843
end
796844

845+
module Api
846+
class BoxesController < JSONAPI::ResourceController
847+
end
848+
end
849+
797850
### RESOURCES
798851
class BaseResource < JSONAPI::Resource
799852
abstract
@@ -1668,6 +1721,23 @@ def show
16681721
end
16691722
end
16701723

1724+
module Api
1725+
class BoxResource < JSONAPI::Resource
1726+
has_many :things
1727+
end
1728+
1729+
class ThingResource < JSONAPI::Resource
1730+
has_one :box
1731+
has_one :user
1732+
1733+
has_many :things
1734+
end
1735+
1736+
class UserResource < JSONAPI::Resource
1737+
has_many :things
1738+
end
1739+
end
1740+
16711741
### PORO Data - don't do this in a production app
16721742
$breed_data = BreedData.new
16731743
$breed_data.add(Breed.new(0, 'persian'))

test/fixtures/boxes.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
box_1:
2+
id: 1

test/fixtures/related_things.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
related_thing_1:
2+
id: 1
3+
from_id: 1
4+
to_id: 2
5+
6+
related_thing_2:
7+
id: 2
8+
from_id: 2
9+
to_id: 1

test/fixtures/things.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
thing_1:
2+
id: 1
3+
user_id: 1
4+
box_id: 1
5+
6+
thing_2:
7+
id: 2
8+
user_id: 1
9+
box_id: 1

test/fixtures/users.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
user_1:
2+
id: 1

test/test_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ class CatResource < JSONAPI::Resource
276276
jsonapi_resources :authors
277277

278278
namespace :api do
279+
jsonapi_resources :boxes
280+
279281
namespace :v1 do
280282
jsonapi_resources :people
281283
jsonapi_resources :comments

0 commit comments

Comments
 (0)