active_model_serializers 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +8 -1
- data/CHANGELOG.md +45 -3
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -1
- data/README.md +5 -2
- data/active_model_serializers.gemspec +2 -2
- data/docs/ARCHITECTURE.md +6 -7
- data/docs/README.md +2 -0
- data/docs/general/caching.md +7 -1
- data/docs/general/configuration_options.md +64 -0
- data/docs/general/rendering.md +35 -1
- data/docs/general/serializers.md +35 -5
- data/docs/howto/add_pagination_links.md +2 -2
- data/docs/howto/add_relationship_links.md +137 -0
- data/docs/howto/add_root_key.md +4 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +9 -2
- data/docs/howto/passing_arbitrary_options.md +2 -2
- data/docs/howto/test.md +2 -0
- data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
- data/docs/integrations/ember-and-json-api.md +41 -24
- data/lib/action_controller/serialization.rb +9 -0
- data/lib/active_model/serializer.rb +19 -22
- data/lib/active_model/serializer/association.rb +19 -4
- data/lib/active_model/serializer/collection_serializer.rb +8 -5
- data/lib/active_model/serializer/{associations.rb → concerns/associations.rb} +8 -5
- data/lib/active_model/serializer/{attributes.rb → concerns/attributes.rb} +0 -0
- data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +5 -1
- data/lib/active_model/serializer/{configuration.rb → concerns/configuration.rb} +24 -1
- data/lib/active_model/serializer/{links.rb → concerns/links.rb} +0 -0
- data/lib/active_model/serializer/{meta.rb → concerns/meta.rb} +0 -0
- data/lib/active_model/serializer/{type.rb → concerns/type.rb} +0 -0
- data/lib/active_model/serializer/reflection.rb +37 -21
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +1 -0
- data/lib/active_model_serializers/adapter/attributes.rb +3 -1
- data/lib/active_model_serializers/adapter/json_api.rb +15 -22
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +30 -19
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +23 -9
- data/lib/active_model_serializers/key_transform.rb +4 -0
- data/lib/active_model_serializers/lookup_chain.rb +80 -0
- data/lib/active_model_serializers/model.rb +1 -1
- data/lib/active_model_serializers/serializable_resource.rb +6 -5
- data/lib/generators/rails/serializer_generator.rb +1 -1
- data/test/action_controller/json_api/fields_test.rb +57 -0
- data/test/action_controller/json_api/transform_test.rb +3 -3
- data/test/action_controller/lookup_proc_test.rb +49 -0
- data/test/action_controller/namespace_lookup_test.rb +226 -0
- data/test/active_model_serializers/key_transform_test.rb +32 -0
- data/test/active_model_serializers/model_test.rb +11 -0
- data/test/adapter/attributes_test.rb +43 -0
- data/test/adapter/json/transform_test.rb +1 -1
- data/test/adapter/json_api/fields_test.rb +4 -3
- data/test/adapter/json_api/has_many_test.rb +21 -0
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +166 -0
- data/test/adapter/json_api/linked_test.rb +24 -6
- data/test/adapter/json_api/links_test.rb +1 -1
- data/test/adapter/json_api/pagination_links_test.rb +17 -2
- data/test/adapter/json_api/relationship_test.rb +309 -73
- data/test/adapter/json_api/resource_identifier_test.rb +20 -0
- data/test/adapter/json_api/transform_test.rb +4 -3
- data/test/benchmark/benchmarking_support.rb +1 -1
- data/test/benchmark/bm_active_record.rb +81 -0
- data/test/benchmark/bm_adapter.rb +38 -0
- data/test/benchmark/bm_caching.rb +1 -1
- data/test/benchmark/bm_lookup_chain.rb +83 -0
- data/test/cache_test.rb +42 -4
- data/test/collection_serializer_test.rb +1 -1
- data/test/fixtures/poro.rb +44 -41
- data/test/generators/serializer_generator_test.rb +22 -5
- data/test/serializers/association_macros_test.rb +3 -2
- data/test/serializers/associations_test.rb +97 -22
- data/test/serializers/attribute_test.rb +1 -1
- data/test/serializers/serializer_for_test.rb +3 -3
- data/test/serializers/serializer_for_with_namespace_test.rb +87 -0
- data/test/support/serialization_testing.rb +16 -0
- data/test/test_helper.rb +1 -0
- metadata +35 -14
- data/test/adapter/json_api/relationships_test.rb +0 -204
@@ -40,6 +40,27 @@ module ActiveModelSerializers
|
|
40
40
|
assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
|
41
41
|
end
|
42
42
|
|
43
|
+
test 'relationships can be whitelisted via fields' do
|
44
|
+
@adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, fields: { posts: [:author] })
|
45
|
+
result = @adapter.serializable_hash
|
46
|
+
expected = {
|
47
|
+
data: {
|
48
|
+
id: '1',
|
49
|
+
type: 'posts',
|
50
|
+
relationships: {
|
51
|
+
author: {
|
52
|
+
data: {
|
53
|
+
id: '1',
|
54
|
+
type: 'authors'
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
assert_equal expected, result
|
62
|
+
end
|
63
|
+
|
43
64
|
def test_includes_linked_comments
|
44
65
|
@adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:comments])
|
45
66
|
expected = [{
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module ActiveModel
|
4
|
+
class Serializer
|
5
|
+
module Adapter
|
6
|
+
class JsonApi
|
7
|
+
class IncludeParamTest < ActiveSupport::TestCase
|
8
|
+
IncludeParamAuthor = Class.new(::Model)
|
9
|
+
|
10
|
+
class CustomCommentLoader
|
11
|
+
def all
|
12
|
+
[{ foo: 'bar' }]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class TagSerializer < ActiveModel::Serializer
|
17
|
+
attributes :id, :name
|
18
|
+
end
|
19
|
+
|
20
|
+
class IncludeParamAuthorSerializer < ActiveModel::Serializer
|
21
|
+
class_attribute :comment_loader
|
22
|
+
|
23
|
+
has_many :tags, serializer: TagSerializer do
|
24
|
+
link :self, '//example.com/link_author/relationships/tags'
|
25
|
+
include_data :if_sideloaded
|
26
|
+
end
|
27
|
+
|
28
|
+
has_many :unlinked_tags, serializer: TagSerializer do
|
29
|
+
include_data :if_sideloaded
|
30
|
+
end
|
31
|
+
|
32
|
+
has_many :posts, serializer: PostWithTagsSerializer do
|
33
|
+
include_data :if_sideloaded
|
34
|
+
end
|
35
|
+
has_many :locations do
|
36
|
+
include_data :if_sideloaded
|
37
|
+
end
|
38
|
+
has_many :comments do
|
39
|
+
include_data :if_sideloaded
|
40
|
+
IncludeParamAuthorSerializer.comment_loader.all
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup
|
45
|
+
IncludeParamAuthorSerializer.comment_loader = Class.new(CustomCommentLoader).new
|
46
|
+
@tag = Tag.new(id: 1337, name: 'mytag')
|
47
|
+
@author = IncludeParamAuthor.new(
|
48
|
+
id: 1337,
|
49
|
+
tags: [@tag]
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_relationship_not_loaded_when_not_included
|
54
|
+
expected = {
|
55
|
+
links: {
|
56
|
+
self: '//example.com/link_author/relationships/tags'
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
@author.define_singleton_method(:read_attribute_for_serialization) do |attr|
|
61
|
+
fail 'should not be called' if attr == :tags
|
62
|
+
super(attr)
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_relationship(:tags, expected)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_relationship_included
|
69
|
+
expected = {
|
70
|
+
data: [
|
71
|
+
{
|
72
|
+
id: '1337',
|
73
|
+
type: 'tags'
|
74
|
+
}
|
75
|
+
],
|
76
|
+
links: {
|
77
|
+
self: '//example.com/link_author/relationships/tags'
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
assert_relationship(:tags, expected, include: :tags)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_sideloads_included
|
85
|
+
expected = [
|
86
|
+
{
|
87
|
+
id: '1337',
|
88
|
+
type: 'tags',
|
89
|
+
attributes: { name: 'mytag' }
|
90
|
+
}
|
91
|
+
]
|
92
|
+
hash = result(include: :tags)
|
93
|
+
assert_equal(expected, hash[:included])
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_nested_relationship
|
97
|
+
expected = {
|
98
|
+
data: [
|
99
|
+
{
|
100
|
+
id: '1337',
|
101
|
+
type: 'tags'
|
102
|
+
}
|
103
|
+
],
|
104
|
+
links: {
|
105
|
+
self: '//example.com/link_author/relationships/tags'
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
expected_no_data = {
|
110
|
+
links: {
|
111
|
+
self: '//example.com/link_author/relationships/tags'
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
assert_relationship(:tags, expected, include: [:tags, { posts: :tags }])
|
116
|
+
|
117
|
+
@author.define_singleton_method(:read_attribute_for_serialization) do |attr|
|
118
|
+
fail 'should not be called' if attr == :tags
|
119
|
+
super(attr)
|
120
|
+
end
|
121
|
+
|
122
|
+
assert_relationship(:tags, expected_no_data, include: { posts: :tags })
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_include_params_with_no_block
|
126
|
+
@author.define_singleton_method(:read_attribute_for_serialization) do |attr|
|
127
|
+
fail 'should not be called' if attr == :locations
|
128
|
+
super(attr)
|
129
|
+
end
|
130
|
+
|
131
|
+
expected = { meta: {} }
|
132
|
+
|
133
|
+
assert_relationship(:locations, expected)
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_block_relationship
|
137
|
+
expected = {
|
138
|
+
data: [
|
139
|
+
{ 'foo' => 'bar' }
|
140
|
+
]
|
141
|
+
}
|
142
|
+
|
143
|
+
assert_relationship(:comments, expected, include: [:comments])
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_node_not_included_when_no_link
|
147
|
+
expected = nil
|
148
|
+
assert_relationship(:unlinked_tags, expected)
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def result(opts)
|
154
|
+
opts = { adapter: :json_api }.merge(opts)
|
155
|
+
serializable(@author, opts).serializable_hash
|
156
|
+
end
|
157
|
+
|
158
|
+
def assert_relationship(relationship_name, expected, opts = {})
|
159
|
+
hash = result(opts)
|
160
|
+
assert_equal(expected, hash[:data][:relationships][relationship_name])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
NestedPost
|
3
|
+
class NestedPost < ::Model; end
|
4
4
|
class NestedPostSerializer < ActiveModel::Serializer
|
5
5
|
has_many :nested_posts
|
6
6
|
end
|
7
|
-
|
8
7
|
module ActiveModelSerializers
|
9
8
|
module Adapter
|
10
9
|
class JsonApi
|
@@ -224,6 +223,25 @@ module ActiveModelSerializers
|
|
224
223
|
assert_equal expected, relationships
|
225
224
|
end
|
226
225
|
|
226
|
+
def test_underscore_model_namespace_with_namespace_separator_for_linked_resource_type
|
227
|
+
spammy_post = Post.new(id: 123)
|
228
|
+
spammy_post.related = [Spam::UnrelatedLink.new(id: 456)]
|
229
|
+
serializer = SpammyPostSerializer.new(spammy_post)
|
230
|
+
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
231
|
+
relationships = with_namespace_separator '--' do
|
232
|
+
adapter.serializable_hash[:data][:relationships]
|
233
|
+
end
|
234
|
+
expected = {
|
235
|
+
related: {
|
236
|
+
data: [{
|
237
|
+
type: 'spam--unrelated-links',
|
238
|
+
id: '456'
|
239
|
+
}]
|
240
|
+
}
|
241
|
+
}
|
242
|
+
assert_equal expected, relationships
|
243
|
+
end
|
244
|
+
|
227
245
|
def test_multiple_references_to_same_resource
|
228
246
|
serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_comment, @second_comment])
|
229
247
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(
|
@@ -283,8 +301,8 @@ module ActiveModelSerializers
|
|
283
301
|
end
|
284
302
|
|
285
303
|
class NoDuplicatesTest < ActiveSupport::TestCase
|
286
|
-
Post
|
287
|
-
Author
|
304
|
+
class Post < ::Model; end
|
305
|
+
class Author < ::Model; end
|
288
306
|
|
289
307
|
class PostSerializer < ActiveModel::Serializer
|
290
308
|
type 'posts'
|
@@ -303,8 +321,8 @@ module ActiveModelSerializers
|
|
303
321
|
@author.posts << @post1
|
304
322
|
@author.posts << @post2
|
305
323
|
|
306
|
-
@nestedpost1 =
|
307
|
-
@nestedpost2 =
|
324
|
+
@nestedpost1 = NestedPost.new(id: 1, nested_posts: [])
|
325
|
+
@nestedpost2 = NestedPost.new(id: 2, nested_posts: [])
|
308
326
|
@nestedpost1.nested_posts << @nestedpost1
|
309
327
|
@nestedpost1.nested_posts << @nestedpost2
|
310
328
|
@nestedpost2.nested_posts << @nestedpost1
|
@@ -4,7 +4,7 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class LinksTest < ActiveSupport::TestCase
|
7
|
-
LinkAuthor
|
7
|
+
class LinkAuthor < ::Model; end
|
8
8
|
class LinkAuthorSerializer < ActiveModel::Serializer
|
9
9
|
link :self do
|
10
10
|
href "http://example.com/link_author/#{object.id}"
|
@@ -76,7 +76,7 @@ module ActiveModelSerializers
|
|
76
76
|
}
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
79
|
+
def expected_response_when_unpaginatable
|
80
80
|
data
|
81
81
|
end
|
82
82
|
|
@@ -87,6 +87,12 @@ module ActiveModelSerializers
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
def expected_response_without_pagination_links
|
91
|
+
{}.tap do |hash|
|
92
|
+
hash[:data] = data.values.flatten[2..3]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
90
96
|
def expected_response_with_pagination_links_and_additional_params
|
91
97
|
new_links = links[:links].each_with_object({}) { |(key, value), hash| hash[key] = "#{value}&test=test" }
|
92
98
|
{}.tap do |hash|
|
@@ -159,7 +165,7 @@ module ActiveModelSerializers
|
|
159
165
|
def test_not_showing_pagination_links
|
160
166
|
adapter = load_adapter(@array, mock_request)
|
161
167
|
|
162
|
-
assert_equal
|
168
|
+
assert_equal expected_response_when_unpaginatable, adapter.serializable_hash
|
163
169
|
end
|
164
170
|
|
165
171
|
def test_raises_descriptive_error_when_serialization_context_unset
|
@@ -172,6 +178,15 @@ module ActiveModelSerializers
|
|
172
178
|
assert_equal exception_class, exception.class
|
173
179
|
assert_match(/CollectionSerializer#paginated\?/, exception.message)
|
174
180
|
end
|
181
|
+
|
182
|
+
def test_pagination_links_not_present_when_disabled
|
183
|
+
ActiveModel::Serializer.config.jsonapi_pagination_links_enabled = false
|
184
|
+
adapter = load_adapter(using_kaminari, mock_request)
|
185
|
+
|
186
|
+
assert_equal expected_response_without_pagination_links, adapter.serializable_hash
|
187
|
+
ensure
|
188
|
+
ActiveModel::Serializer.config.jsonapi_pagination_links_enabled = true
|
189
|
+
end
|
175
190
|
end
|
176
191
|
end
|
177
192
|
end
|
@@ -4,13 +4,6 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class RelationshipTest < ActiveSupport::TestCase
|
7
|
-
setup do
|
8
|
-
@blog = Blog.new(id: 1)
|
9
|
-
@author = Author.new(id: 1, name: 'Steve K.', blog: @blog)
|
10
|
-
@serializer = BlogSerializer.new(@blog)
|
11
|
-
ActionController::Base.cache_store.clear
|
12
|
-
end
|
13
|
-
|
14
7
|
def test_relationship_with_data
|
15
8
|
expected = {
|
16
9
|
data: {
|
@@ -18,26 +11,29 @@ module ActiveModelSerializers
|
|
18
11
|
type: 'blogs'
|
19
12
|
}
|
20
13
|
}
|
21
|
-
|
14
|
+
|
15
|
+
model_attributes = { blog: Blog.new(id: 1) }
|
16
|
+
relationship_name = :blog
|
17
|
+
model = new_model(model_attributes)
|
18
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
19
|
+
has_one :blog
|
20
|
+
end
|
21
|
+
assert_equal(expected, actual)
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_relationship_with_nil_model
|
25
|
-
@serializer = BlogSerializer.new(nil)
|
26
25
|
expected = { data: nil }
|
27
|
-
test_relationship(expected, options: { include_data: true })
|
28
|
-
end
|
29
26
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
model_attributes = { blog: nil }
|
28
|
+
relationship_name = :blog
|
29
|
+
model = new_model(model_attributes)
|
30
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
31
|
+
has_one :blog
|
32
|
+
end
|
33
|
+
assert_equal(expected, actual)
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_relationship_with_data_array
|
37
|
-
posts = [Post.new(id: 1), Post.new(id: 2)]
|
38
|
-
@serializer = ActiveModel::Serializer::CollectionSerializer.new(posts)
|
39
|
-
@author.posts = posts
|
40
|
-
@author.blog = nil
|
41
37
|
expected = {
|
42
38
|
data: [
|
43
39
|
{
|
@@ -50,110 +46,350 @@ module ActiveModelSerializers
|
|
50
46
|
}
|
51
47
|
]
|
52
48
|
}
|
53
|
-
|
49
|
+
|
50
|
+
model_attributes = { posts: [Post.new(id: 1), Post.new(id: 2)] }
|
51
|
+
relationship_name = :posts
|
52
|
+
model = new_model(model_attributes)
|
53
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
54
|
+
has_many :posts
|
55
|
+
end
|
56
|
+
assert_equal(expected, actual)
|
54
57
|
end
|
55
58
|
|
56
59
|
def test_relationship_data_not_included
|
57
|
-
|
58
|
-
end
|
60
|
+
expected = { meta: {} }
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
|
62
|
+
model_attributes = { blog: :does_not_matter }
|
63
|
+
relationship_name = :blog
|
64
|
+
model = new_model(model_attributes)
|
65
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
66
|
+
has_one :blog do
|
67
|
+
include_data false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
assert_equal(expected, actual)
|
63
71
|
end
|
64
72
|
|
65
73
|
def test_relationship_many_links
|
66
|
-
links = {
|
67
|
-
self: 'a link',
|
68
|
-
related: 'another link'
|
69
|
-
}
|
70
74
|
expected = {
|
71
75
|
links: {
|
72
76
|
self: 'a link',
|
73
77
|
related: 'another link'
|
74
78
|
}
|
75
79
|
}
|
76
|
-
test_relationship(expected, links: links)
|
77
|
-
end
|
78
80
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
model_attributes = { blog: :does_not_matter }
|
82
|
+
relationship_name = :blog
|
83
|
+
model = new_model(model_attributes)
|
84
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
85
|
+
has_one :blog do
|
86
|
+
include_data false
|
87
|
+
link :self, 'a link'
|
88
|
+
link :related, 'another link'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
assert_equal(expected, actual)
|
83
92
|
end
|
84
93
|
|
85
94
|
def test_relationship_block_link_with_meta
|
86
|
-
links = {
|
87
|
-
self: proc do
|
88
|
-
href object.id.to_s
|
89
|
-
meta(id: object.id)
|
90
|
-
end
|
91
|
-
}
|
92
95
|
expected = {
|
93
96
|
links: {
|
94
97
|
self: {
|
95
|
-
href:
|
96
|
-
meta: { id:
|
98
|
+
href: '1',
|
99
|
+
meta: { id: 1 }
|
97
100
|
}
|
98
101
|
}
|
99
102
|
}
|
100
|
-
|
103
|
+
|
104
|
+
model_attributes = { blog: Blog.new(id: 1) }
|
105
|
+
relationship_name = :blog
|
106
|
+
model = new_model(model_attributes)
|
107
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
108
|
+
has_one :blog do
|
109
|
+
include_data false
|
110
|
+
link :self do
|
111
|
+
href object.blog.id.to_s
|
112
|
+
meta(id: object.blog.id)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
assert_equal(expected, actual)
|
101
117
|
end
|
102
118
|
|
103
119
|
def test_relationship_simple_meta
|
104
|
-
|
105
|
-
|
106
|
-
|
120
|
+
expected = { meta: { id: '1' } }
|
121
|
+
|
122
|
+
model_attributes = { blog: Blog.new(id: 1) }
|
123
|
+
relationship_name = :blog
|
124
|
+
model = new_model(model_attributes)
|
125
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
126
|
+
has_one :blog do
|
127
|
+
include_data false
|
128
|
+
meta(id: object.blog.id.to_s)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
assert_equal(expected, actual)
|
107
132
|
end
|
108
133
|
|
109
134
|
def test_relationship_block_meta
|
110
|
-
meta = proc do
|
111
|
-
{ id: object.id }
|
112
|
-
end
|
113
135
|
expected = {
|
114
136
|
meta: {
|
115
|
-
id:
|
137
|
+
id: 1
|
116
138
|
}
|
117
139
|
}
|
118
|
-
|
140
|
+
|
141
|
+
model_attributes = { blog: Blog.new(id: 1) }
|
142
|
+
relationship_name = :blog
|
143
|
+
model = new_model(model_attributes)
|
144
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
145
|
+
has_one :blog do
|
146
|
+
include_data false
|
147
|
+
meta(id: object.blog.id)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
assert_equal(expected, actual)
|
119
151
|
end
|
120
152
|
|
121
|
-
def
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
153
|
+
def test_relationship_simple_link
|
154
|
+
expected = {
|
155
|
+
data: {
|
156
|
+
id: '1337',
|
157
|
+
type: 'bios'
|
158
|
+
},
|
159
|
+
links: {
|
160
|
+
self: '//example.com/link_author/relationships/bio'
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
model_attributes = { bio: Bio.new(id: 1337) }
|
165
|
+
relationship_name = :bio
|
166
|
+
model = new_model(model_attributes)
|
167
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
168
|
+
has_one :bio do
|
169
|
+
link :self, '//example.com/link_author/relationships/bio'
|
127
170
|
end
|
171
|
+
end
|
172
|
+
assert_equal(expected, actual)
|
173
|
+
end
|
128
174
|
|
175
|
+
def test_relationship_block_link
|
176
|
+
expected = {
|
177
|
+
data: { id: '1337', type: 'profiles' },
|
178
|
+
links: { related: '//example.com/profiles/1337' }
|
129
179
|
}
|
130
|
-
|
131
|
-
|
180
|
+
|
181
|
+
model_attributes = { profile: Profile.new(id: 1337) }
|
182
|
+
relationship_name = :profile
|
183
|
+
model = new_model(model_attributes)
|
184
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
185
|
+
has_one :profile do
|
186
|
+
id = object.profile.id
|
187
|
+
link :related do
|
188
|
+
"//example.com/profiles/#{id}" if id != 123
|
189
|
+
end
|
190
|
+
end
|
132
191
|
end
|
192
|
+
assert_equal(expected, actual)
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_relationship_with_everything
|
133
196
|
expected = {
|
134
|
-
data: {
|
135
|
-
id: '1',
|
136
|
-
type: 'blogs'
|
137
|
-
},
|
197
|
+
data: [{ id: '1337', type: 'likes' }],
|
138
198
|
links: {
|
139
|
-
self: 'a link',
|
140
199
|
related: {
|
141
|
-
href: '
|
200
|
+
href: '//example.com/likes/1337',
|
201
|
+
meta: { ids: '1337' }
|
142
202
|
}
|
143
203
|
},
|
144
|
-
meta: {
|
145
|
-
|
204
|
+
meta: { liked: true }
|
205
|
+
}
|
206
|
+
|
207
|
+
model_attributes = { likes: [Like.new(id: 1337)] }
|
208
|
+
relationship_name = :likes
|
209
|
+
model = new_model(model_attributes)
|
210
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
211
|
+
has_many :likes do
|
212
|
+
link :related do
|
213
|
+
ids = object.likes.map(&:id).join(',')
|
214
|
+
href "//example.com/likes/#{ids}"
|
215
|
+
meta ids: ids
|
216
|
+
end
|
217
|
+
meta liked: object.likes.any?
|
218
|
+
end
|
219
|
+
end
|
220
|
+
assert_equal(expected, actual)
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_relationship_nil_link
|
224
|
+
expected = {
|
225
|
+
data: { id: '123', type: 'profiles' }
|
226
|
+
}
|
227
|
+
|
228
|
+
model_attributes = { profile: Profile.new(id: 123) }
|
229
|
+
relationship_name = :profile
|
230
|
+
model = new_model(model_attributes)
|
231
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
232
|
+
has_one :profile do
|
233
|
+
id = object.profile.id
|
234
|
+
link :related do
|
235
|
+
"//example.com/profiles/#{id}" if id != 123
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
assert_equal(expected, actual)
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_relationship_block_link_href
|
243
|
+
expected = {
|
244
|
+
data: [{ id: '1337', type: 'locations' }],
|
245
|
+
links: {
|
246
|
+
related: { href: '//example.com/locations/1337' }
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
model_attributes = { locations: [Location.new(id: 1337)] }
|
251
|
+
relationship_name = :locations
|
252
|
+
model = new_model(model_attributes)
|
253
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
254
|
+
has_many :locations do
|
255
|
+
link :related do
|
256
|
+
ids = object.locations.map(&:id).join(',')
|
257
|
+
href "//example.com/locations/#{ids}"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
assert_equal(expected, actual)
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_relationship_block_link_href_and_meta
|
265
|
+
expected = {
|
266
|
+
data: [{ id: '1337', type: 'posts' }],
|
267
|
+
links: {
|
268
|
+
related: {
|
269
|
+
href: '//example.com/posts/1337',
|
270
|
+
meta: { ids: '1337' }
|
271
|
+
}
|
272
|
+
}
|
273
|
+
}
|
274
|
+
|
275
|
+
model_attributes = { posts: [Post.new(id: 1337, comments: [], author: nil)] }
|
276
|
+
relationship_name = :posts
|
277
|
+
model = new_model(model_attributes)
|
278
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
279
|
+
has_many :posts do
|
280
|
+
link :related do
|
281
|
+
ids = object.posts.map(&:id).join(',')
|
282
|
+
href "//example.com/posts/#{ids}"
|
283
|
+
meta ids: ids
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
assert_equal(expected, actual)
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_relationship_block_link_meta
|
291
|
+
expected = {
|
292
|
+
data: [{ id: '1337', type: 'comments' }],
|
293
|
+
links: {
|
294
|
+
self: {
|
295
|
+
meta: { ids: [1] }
|
296
|
+
}
|
146
297
|
}
|
147
298
|
}
|
148
|
-
|
299
|
+
|
300
|
+
model_attributes = { comments: [Comment.new(id: 1337)] }
|
301
|
+
relationship_name = :comments
|
302
|
+
model = new_model(model_attributes)
|
303
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
304
|
+
has_many :comments do
|
305
|
+
link :self do
|
306
|
+
meta ids: [1]
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
assert_equal(expected, actual)
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_relationship_meta
|
314
|
+
expected = {
|
315
|
+
data: [{ id: 'from-serializer-method', type: 'roles' }],
|
316
|
+
meta: { count: 1 }
|
317
|
+
}
|
318
|
+
|
319
|
+
model_attributes = { roles: [Role.new(id: 'from-record')] }
|
320
|
+
relationship_name = :roles
|
321
|
+
model = new_model(model_attributes)
|
322
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
323
|
+
has_many :roles do |serializer|
|
324
|
+
meta count: object.roles.count
|
325
|
+
serializer.cached_roles
|
326
|
+
end
|
327
|
+
def cached_roles
|
328
|
+
[
|
329
|
+
Role.new(id: 'from-serializer-method')
|
330
|
+
]
|
331
|
+
end
|
332
|
+
end
|
333
|
+
assert_equal(expected, actual)
|
334
|
+
end
|
335
|
+
|
336
|
+
def test_relationship_not_including_data
|
337
|
+
expected = {
|
338
|
+
links: { self: '//example.com/link_author/relationships/blog' }
|
339
|
+
}
|
340
|
+
|
341
|
+
model_attributes = { blog: Object }
|
342
|
+
relationship_name = :blog
|
343
|
+
model = new_model(model_attributes)
|
344
|
+
model.define_singleton_method(:read_attribute_for_serialization) do |attr|
|
345
|
+
fail 'should not be called' if attr == :blog
|
346
|
+
super(attr)
|
347
|
+
end
|
348
|
+
assert_nothing_raised do
|
349
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
350
|
+
has_one :blog do
|
351
|
+
link :self, '//example.com/link_author/relationships/blog'
|
352
|
+
include_data false
|
353
|
+
end
|
354
|
+
end
|
355
|
+
assert_equal(expected, actual)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_relationship_including_data_explicit
|
360
|
+
expected = {
|
361
|
+
data: { id: '1337', type: 'authors' },
|
362
|
+
meta: { name: 'Dan Brown' }
|
363
|
+
}
|
364
|
+
|
365
|
+
model_attributes = { reviewer: Author.new(id: 1337) }
|
366
|
+
relationship_name = :reviewer
|
367
|
+
model = new_model(model_attributes)
|
368
|
+
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
369
|
+
belongs_to :reviewer do
|
370
|
+
meta name: 'Dan Brown'
|
371
|
+
include_data true
|
372
|
+
end
|
373
|
+
end
|
374
|
+
assert_equal(expected, actual)
|
149
375
|
end
|
150
376
|
|
151
377
|
private
|
152
378
|
|
153
|
-
def
|
154
|
-
|
155
|
-
|
156
|
-
|
379
|
+
def build_serializer_and_serialize_relationship(model, relationship_name, &block)
|
380
|
+
serializer_class = Class.new(ActiveModel::Serializer, &block)
|
381
|
+
hash = serializable(model, serializer: serializer_class, adapter: :json_api).serializable_hash
|
382
|
+
hash[:data][:relationships][relationship_name]
|
383
|
+
end
|
384
|
+
|
385
|
+
def new_model(model_attributes)
|
386
|
+
Class.new(ActiveModelSerializers::Model) do
|
387
|
+
attr_accessor(*model_attributes.keys)
|
388
|
+
|
389
|
+
def self.name
|
390
|
+
'TestModel'
|
391
|
+
end
|
392
|
+
end.new(model_attributes)
|
157
393
|
end
|
158
394
|
end
|
159
395
|
end
|