active_model_serializers 0.10.4 → 0.10.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -3
- data/CHANGELOG.md +25 -1
- data/README.md +4 -4
- data/active_model_serializers.gemspec +1 -1
- data/appveyor.yml +9 -3
- data/docs/general/logging.md +7 -0
- data/docs/general/serializers.md +3 -3
- data/docs/howto/add_pagination_links.md +13 -13
- data/docs/howto/add_relationship_links.md +24 -21
- data/docs/howto/outside_controller_use.md +3 -2
- data/docs/howto/serialize_poro.md +46 -5
- data/docs/howto/upgrade_from_0_8_to_0_10.md +1 -1
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +8 -0
- data/lib/active_model_serializers/model.rb +108 -30
- data/lib/active_model_serializers/test/schema.rb +2 -2
- data/lib/generators/rails/resource_override.rb +1 -1
- data/test/action_controller/adapter_selector_test.rb +11 -2
- data/test/action_controller/json_api/fields_test.rb +15 -6
- data/test/action_controller/json_api/transform_test.rb +11 -3
- data/test/action_controller/namespace_lookup_test.rb +14 -8
- data/test/action_controller/serialization_scope_name_test.rb +12 -6
- data/test/action_controller/serialization_test.rb +1 -1
- data/test/active_model_serializers/model_test.rb +122 -2
- data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +37 -19
- data/test/adapter/attributes_test.rb +2 -5
- data/test/adapter/json/has_many_test.rb +10 -2
- data/test/adapter/json_api/fields_test.rb +11 -3
- data/test/adapter/json_api/has_many_test.rb +10 -2
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +22 -5
- data/test/adapter/json_api/linked_test.rb +3 -3
- data/test/adapter/json_api/links_test.rb +1 -1
- data/test/adapter/json_api/relationship_test.rb +1 -1
- data/test/adapter/json_api/transform_test.rb +11 -3
- data/test/cache_test.rb +100 -28
- data/test/collection_serializer_test.rb +23 -10
- data/test/fixtures/active_record.rb +45 -10
- data/test/fixtures/poro.rb +115 -176
- data/test/generators/serializer_generator_test.rb +1 -0
- data/test/grape_test.rb +20 -2
- data/test/serializers/associations_test.rb +28 -7
- data/test/serializers/attribute_test.rb +4 -2
- data/test/serializers/caching_configuration_test_isolated.rb +6 -6
- data/test/serializers/options_test.rb +17 -6
- data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
- data/test/serializers/serialization_test.rb +2 -2
- data/test/serializers/serializer_for_test.rb +6 -6
- data/test/serializers/serializer_for_with_namespace_test.rb +6 -5
- data/test/support/rails_app.rb +2 -0
- data/test/test_helper.rb +12 -0
- metadata +13 -7
@@ -4,11 +4,13 @@ require 'support/isolated_unit'
|
|
4
4
|
class RailtieTest < ActiveSupport::TestCase
|
5
5
|
include ActiveSupport::Testing::Isolation
|
6
6
|
|
7
|
-
class
|
7
|
+
class WithRailsRequiredFirst < RailtieTest
|
8
8
|
setup do
|
9
9
|
require 'rails'
|
10
10
|
require 'active_model_serializers'
|
11
|
-
make_basic_app
|
11
|
+
make_basic_app do |app|
|
12
|
+
app.config.action_controller.perform_caching = true
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
16
|
test 'mixes ActionController::Serialization into ActionController::Base' do
|
@@ -32,14 +34,17 @@ class RailtieTest < ActiveSupport::TestCase
|
|
32
34
|
|
33
35
|
test 'it is configured for caching' do
|
34
36
|
assert_equal ActionController::Base.cache_store, ActiveModelSerializers.config.cache_store
|
35
|
-
assert_equal Rails.configuration.action_controller.perform_caching
|
37
|
+
assert_equal true, Rails.configuration.action_controller.perform_caching
|
38
|
+
assert_equal true, ActiveModelSerializers.config.perform_caching
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
39
|
-
class
|
42
|
+
class WithoutRailsRequiredFirst < RailtieTest
|
40
43
|
setup do
|
41
44
|
require 'active_model_serializers'
|
42
|
-
make_basic_app
|
45
|
+
make_basic_app do |app|
|
46
|
+
app.config.action_controller.perform_caching = true
|
47
|
+
end
|
43
48
|
end
|
44
49
|
|
45
50
|
test 'does not mix ActionController::Serialization into ActionController::Base' do
|
@@ -56,8 +61,8 @@ class RailtieTest < ActiveSupport::TestCase
|
|
56
61
|
test 'it is not configured for caching' do
|
57
62
|
refute_nil ActionController::Base.cache_store
|
58
63
|
assert_nil ActiveModelSerializers.config.cache_store
|
59
|
-
|
60
|
-
|
64
|
+
assert_equal true, Rails.configuration.action_controller.perform_caching
|
65
|
+
assert_nil ActiveModelSerializers.config.perform_caching
|
61
66
|
end
|
62
67
|
end
|
63
68
|
end
|
@@ -12,7 +12,17 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def render_with_jsonapi_renderer
|
15
|
-
|
15
|
+
permitted_params = params.permit(data: [:id, :type, attributes: [:name]])
|
16
|
+
permitted_params = permitted_params.to_h.with_indifferent_access
|
17
|
+
attributes =
|
18
|
+
if permitted_params[:data]
|
19
|
+
permitted_params[:data][:attributes].merge(id: permitted_params[:data][:id])
|
20
|
+
else
|
21
|
+
# Rails returns empty params when no mime type can be negotiated.
|
22
|
+
# (Until https://github.com/rails/rails/pull/26632 is reviewed.)
|
23
|
+
permitted_params
|
24
|
+
end
|
25
|
+
author = Author.new(attributes)
|
16
26
|
render jsonapi: author
|
17
27
|
end
|
18
28
|
|
@@ -32,6 +42,17 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
32
42
|
assert_equal(expected, TestController.last_request_parameters)
|
33
43
|
end
|
34
44
|
|
45
|
+
def define_author_model_and_serializer
|
46
|
+
TestController.const_set(:Author, Class.new(ActiveModelSerializers::Model) do
|
47
|
+
attributes :id, :name
|
48
|
+
end)
|
49
|
+
TestController.const_set(:AuthorSerializer, Class.new(ActiveModel::Serializer) do
|
50
|
+
type 'users'
|
51
|
+
attribute :id
|
52
|
+
attribute :name
|
53
|
+
end)
|
54
|
+
end
|
55
|
+
|
35
56
|
class WithoutRenderer < JsonApiRendererTest
|
36
57
|
setup do
|
37
58
|
require 'rails'
|
@@ -47,6 +68,7 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
47
68
|
match ':action', to: TestController, via: [:get, :post]
|
48
69
|
end
|
49
70
|
end
|
71
|
+
define_author_model_and_serializer
|
50
72
|
end
|
51
73
|
|
52
74
|
def test_jsonapi_parser_not_registered
|
@@ -59,18 +81,12 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
59
81
|
end
|
60
82
|
|
61
83
|
def test_jsonapi_renderer_not_registered
|
62
|
-
|
63
|
-
'data' => {
|
64
|
-
'attributes' => {
|
65
|
-
'name' => 'Johnny Rico'
|
66
|
-
},
|
67
|
-
'type' => 'users'
|
68
|
-
}
|
69
|
-
}
|
70
|
-
payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "authors"}}'
|
84
|
+
payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
|
71
85
|
headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
|
72
86
|
post '/render_with_jsonapi_renderer', params: payload, headers: headers
|
73
|
-
|
87
|
+
assert_equal '', response.body
|
88
|
+
assert_equal 500, response.status
|
89
|
+
assert_equal ActionView::MissingTemplate, request.env['action_dispatch.exception'].class
|
74
90
|
end
|
75
91
|
|
76
92
|
def test_jsonapi_parser
|
@@ -98,6 +114,7 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
98
114
|
match ':action', to: TestController, via: [:get, :post]
|
99
115
|
end
|
100
116
|
end
|
117
|
+
define_author_model_and_serializer
|
101
118
|
end
|
102
119
|
|
103
120
|
def test_jsonapi_parser_registered
|
@@ -113,16 +130,16 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
113
130
|
def test_jsonapi_renderer_registered
|
114
131
|
expected = {
|
115
132
|
'data' => {
|
116
|
-
'
|
117
|
-
|
118
|
-
}
|
119
|
-
'type' => 'users'
|
133
|
+
'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765',
|
134
|
+
'type' => 'users',
|
135
|
+
'attributes' => { 'name' => 'Johnny Rico' }
|
120
136
|
}
|
121
137
|
}
|
122
|
-
|
138
|
+
|
139
|
+
payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
|
123
140
|
headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
|
124
141
|
post '/render_with_jsonapi_renderer', params: payload, headers: headers
|
125
|
-
|
142
|
+
assert_equal expected.to_json, response.body
|
126
143
|
end
|
127
144
|
|
128
145
|
def test_jsonapi_parser
|
@@ -132,10 +149,11 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
132
149
|
'attributes' => {
|
133
150
|
'name' => 'John Doe'
|
134
151
|
},
|
135
|
-
'type' => 'users'
|
152
|
+
'type' => 'users',
|
153
|
+
'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765'
|
136
154
|
}
|
137
155
|
},
|
138
|
-
'{"data": {"attributes": {"name": "John Doe"}, "type": "users"}}',
|
156
|
+
'{"data": {"attributes": {"name": "John Doe"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}',
|
139
157
|
'CONTENT_TYPE' => 'application/vnd.api+json'
|
140
158
|
)
|
141
159
|
end
|
@@ -3,11 +3,8 @@ require 'test_helper'
|
|
3
3
|
module ActiveModelSerializers
|
4
4
|
module Adapter
|
5
5
|
class AttributesTest < ActiveSupport::TestCase
|
6
|
-
class Person
|
7
|
-
|
8
|
-
include ActiveModel::Serialization
|
9
|
-
|
10
|
-
attr_accessor :first_name, :last_name
|
6
|
+
class Person < ActiveModelSerializers::Model
|
7
|
+
attributes :first_name, :last_name
|
11
8
|
end
|
12
9
|
|
13
10
|
class PersonSerializer < ActiveModel::Serializer
|
@@ -4,6 +4,10 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class Json
|
6
6
|
class HasManyTestTest < ActiveSupport::TestCase
|
7
|
+
class ModelWithoutSerializer < ::Model
|
8
|
+
attributes :id, :name
|
9
|
+
end
|
10
|
+
|
7
11
|
def setup
|
8
12
|
ActionController::Base.cache_store.clear
|
9
13
|
@author = Author.new(id: 1, name: 'Steve K.')
|
@@ -16,7 +20,7 @@ module ActiveModelSerializers
|
|
16
20
|
@second_comment.post = @post
|
17
21
|
@blog = Blog.new(id: 1, name: 'My Blog!!')
|
18
22
|
@post.blog = @blog
|
19
|
-
@tag =
|
23
|
+
@tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
|
20
24
|
@post.tags = [@tag]
|
21
25
|
end
|
22
26
|
|
@@ -30,7 +34,11 @@ module ActiveModelSerializers
|
|
30
34
|
end
|
31
35
|
|
32
36
|
def test_has_many_with_no_serializer
|
33
|
-
|
37
|
+
post_serializer_class = Class.new(ActiveModel::Serializer) do
|
38
|
+
attributes :id
|
39
|
+
has_many :tags
|
40
|
+
end
|
41
|
+
serializer = post_serializer_class.new(@post)
|
34
42
|
adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
|
35
43
|
assert_equal({
|
36
44
|
id: 42,
|
@@ -4,9 +4,17 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class FieldsTest < ActiveSupport::TestCase
|
7
|
-
class Post < ::Model
|
8
|
-
|
9
|
-
|
7
|
+
class Post < ::Model
|
8
|
+
attributes :title, :body
|
9
|
+
associations :author, :comments
|
10
|
+
end
|
11
|
+
class Author < ::Model
|
12
|
+
attributes :name, :birthday
|
13
|
+
end
|
14
|
+
class Comment < ::Model
|
15
|
+
attributes :body
|
16
|
+
associations :author, :post
|
17
|
+
end
|
10
18
|
|
11
19
|
class PostSerializer < ActiveModel::Serializer
|
12
20
|
type 'posts'
|
@@ -4,6 +4,10 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class HasManyTest < ActiveSupport::TestCase
|
7
|
+
class ModelWithoutSerializer < ::Model
|
8
|
+
attributes :id, :name
|
9
|
+
end
|
10
|
+
|
7
11
|
def setup
|
8
12
|
ActionController::Base.cache_store.clear
|
9
13
|
@author = Author.new(id: 1, name: 'Steve K.')
|
@@ -26,7 +30,7 @@ module ActiveModelSerializers
|
|
26
30
|
@blog.articles = [@post]
|
27
31
|
@post.blog = @blog
|
28
32
|
@post_without_comments.blog = nil
|
29
|
-
@tag =
|
33
|
+
@tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
|
30
34
|
@post.tags = [@tag]
|
31
35
|
@serializer = PostSerializer.new(@post)
|
32
36
|
@adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
|
@@ -129,7 +133,11 @@ module ActiveModelSerializers
|
|
129
133
|
end
|
130
134
|
|
131
135
|
def test_has_many_with_no_serializer
|
132
|
-
|
136
|
+
post_serializer_class = Class.new(ActiveModel::Serializer) do
|
137
|
+
attributes :id
|
138
|
+
has_many :tags
|
139
|
+
end
|
140
|
+
serializer = post_serializer_class.new(@post)
|
133
141
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
134
142
|
|
135
143
|
assert_equal({
|
@@ -5,18 +5,30 @@ module ActiveModel
|
|
5
5
|
module Adapter
|
6
6
|
class JsonApi
|
7
7
|
class IncludeParamTest < ActiveSupport::TestCase
|
8
|
-
IncludeParamAuthor = Class.new(::Model)
|
8
|
+
IncludeParamAuthor = Class.new(::Model) do
|
9
|
+
associations :tags, :posts
|
10
|
+
end
|
9
11
|
|
10
12
|
class CustomCommentLoader
|
11
13
|
def all
|
12
14
|
[{ foo: 'bar' }]
|
13
15
|
end
|
14
16
|
end
|
17
|
+
class Tag < ::Model
|
18
|
+
attributes :id, :name
|
19
|
+
end
|
15
20
|
|
16
21
|
class TagSerializer < ActiveModel::Serializer
|
22
|
+
type 'tags'
|
17
23
|
attributes :id, :name
|
18
24
|
end
|
19
25
|
|
26
|
+
class PostWithTagsSerializer < ActiveModel::Serializer
|
27
|
+
type 'posts'
|
28
|
+
attributes :id
|
29
|
+
has_many :tags
|
30
|
+
end
|
31
|
+
|
20
32
|
class IncludeParamAuthorSerializer < ActiveModel::Serializer
|
21
33
|
class_attribute :comment_loader
|
22
34
|
|
@@ -144,20 +156,25 @@ module ActiveModel
|
|
144
156
|
end
|
145
157
|
|
146
158
|
def test_node_not_included_when_no_link
|
147
|
-
expected =
|
148
|
-
assert_relationship(:unlinked_tags, expected)
|
159
|
+
expected = { meta: {} }
|
160
|
+
assert_relationship(:unlinked_tags, expected, key_transform: :unaltered)
|
149
161
|
end
|
150
162
|
|
151
163
|
private
|
152
164
|
|
165
|
+
def assert_relationship(relationship_name, expected, opts = {})
|
166
|
+
actual = relationship_data(relationship_name, opts)
|
167
|
+
assert_equal(expected, actual)
|
168
|
+
end
|
169
|
+
|
153
170
|
def result(opts)
|
154
171
|
opts = { adapter: :json_api }.merge(opts)
|
155
172
|
serializable(@author, opts).serializable_hash
|
156
173
|
end
|
157
174
|
|
158
|
-
def
|
175
|
+
def relationship_data(relationship_name, opts = {})
|
159
176
|
hash = result(opts)
|
160
|
-
|
177
|
+
hash[:data][:relationships][relationship_name]
|
161
178
|
end
|
162
179
|
end
|
163
180
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class NestedPost < ::Model; end
|
3
|
+
class NestedPost < ::Model; associations :nested_posts end
|
4
4
|
class NestedPostSerializer < ActiveModel::Serializer
|
5
5
|
has_many :nested_posts
|
6
6
|
end
|
@@ -301,8 +301,8 @@ module ActiveModelSerializers
|
|
301
301
|
end
|
302
302
|
|
303
303
|
class NoDuplicatesTest < ActiveSupport::TestCase
|
304
|
-
class Post < ::Model; end
|
305
|
-
class Author < ::Model; end
|
304
|
+
class Post < ::Model; associations :author end
|
305
|
+
class Author < ::Model; associations :posts, :roles, :bio end
|
306
306
|
|
307
307
|
class PostSerializer < ActiveModel::Serializer
|
308
308
|
type 'posts'
|
@@ -4,7 +4,7 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class LinksTest < ActiveSupport::TestCase
|
7
|
-
class LinkAuthor < ::Model; end
|
7
|
+
class LinkAuthor < ::Model; associations :posts end
|
8
8
|
class LinkAuthorSerializer < ActiveModel::Serializer
|
9
9
|
link :self do
|
10
10
|
href "http://example.com/link_author/#{object.id}"
|
@@ -4,9 +4,17 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class KeyCaseTest < ActiveSupport::TestCase
|
7
|
-
class Post < ::Model
|
8
|
-
|
9
|
-
|
7
|
+
class Post < ::Model
|
8
|
+
attributes :title, :body, :publish_at
|
9
|
+
associations :author, :comments
|
10
|
+
end
|
11
|
+
class Author < ::Model
|
12
|
+
attributes :first_name, :last_name
|
13
|
+
end
|
14
|
+
class Comment < ::Model
|
15
|
+
attributes :body
|
16
|
+
associations :author, :post
|
17
|
+
end
|
10
18
|
|
11
19
|
class PostSerializer < ActiveModel::Serializer
|
12
20
|
type 'posts'
|
data/test/cache_test.rb
CHANGED
@@ -4,6 +4,20 @@ require 'tempfile'
|
|
4
4
|
|
5
5
|
module ActiveModelSerializers
|
6
6
|
class CacheTest < ActiveSupport::TestCase
|
7
|
+
class Article < ::Model
|
8
|
+
attributes :title
|
9
|
+
# To confirm error is raised when cache_key is not set and cache_key option not passed to cache
|
10
|
+
undef_method :cache_key
|
11
|
+
end
|
12
|
+
class ArticleSerializer < ActiveModel::Serializer
|
13
|
+
cache only: [:place], skip_digest: true
|
14
|
+
attributes :title
|
15
|
+
end
|
16
|
+
|
17
|
+
class Author < ::Model
|
18
|
+
attributes :id, :name
|
19
|
+
associations :posts, :bio, :roles
|
20
|
+
end
|
7
21
|
# Instead of a primitive cache key (i.e. a string), this class
|
8
22
|
# returns a list of objects that require to be expanded themselves.
|
9
23
|
class AuthorWithExpandableCacheElements < Author
|
@@ -27,22 +41,73 @@ module ActiveModelSerializers
|
|
27
41
|
]
|
28
42
|
end
|
29
43
|
end
|
30
|
-
|
31
44
|
class UncachedAuthor < Author
|
32
45
|
# To confirm cache_key is set using updated_at and cache_key option passed to cache
|
33
46
|
undef_method :cache_key
|
34
47
|
end
|
48
|
+
class AuthorSerializer < ActiveModel::Serializer
|
49
|
+
cache key: 'writer', skip_digest: true
|
50
|
+
attributes :id, :name
|
35
51
|
|
36
|
-
|
37
|
-
|
38
|
-
|
52
|
+
has_many :posts
|
53
|
+
has_many :roles
|
54
|
+
has_one :bio
|
39
55
|
end
|
40
56
|
|
41
|
-
class
|
42
|
-
|
43
|
-
|
57
|
+
class Blog < ::Model
|
58
|
+
attributes :name
|
59
|
+
associations :writer
|
44
60
|
end
|
61
|
+
class BlogSerializer < ActiveModel::Serializer
|
62
|
+
cache key: 'blog'
|
63
|
+
attributes :id, :name
|
64
|
+
|
65
|
+
belongs_to :writer
|
66
|
+
end
|
67
|
+
|
68
|
+
class Comment < ::Model
|
69
|
+
attributes :id, :body
|
70
|
+
associations :post, :author
|
45
71
|
|
72
|
+
# Uses a custom non-time-based cache key
|
73
|
+
def cache_key
|
74
|
+
"comment/#{id}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
class CommentSerializer < ActiveModel::Serializer
|
78
|
+
cache expires_in: 1.day, skip_digest: true
|
79
|
+
attributes :id, :body
|
80
|
+
belongs_to :post
|
81
|
+
belongs_to :author
|
82
|
+
end
|
83
|
+
|
84
|
+
class Post < ::Model
|
85
|
+
attributes :id, :title, :body
|
86
|
+
associations :author, :comments, :blog
|
87
|
+
end
|
88
|
+
class PostSerializer < ActiveModel::Serializer
|
89
|
+
cache key: 'post', expires_in: 0.1, skip_digest: true
|
90
|
+
attributes :id, :title, :body
|
91
|
+
|
92
|
+
has_many :comments
|
93
|
+
belongs_to :blog
|
94
|
+
belongs_to :author
|
95
|
+
end
|
96
|
+
|
97
|
+
class Role < ::Model
|
98
|
+
attributes :name, :description, :special_attribute
|
99
|
+
associations :author
|
100
|
+
end
|
101
|
+
class RoleSerializer < ActiveModel::Serializer
|
102
|
+
cache only: [:name, :slug], skip_digest: true
|
103
|
+
attributes :id, :name, :description
|
104
|
+
attribute :friendly_id, key: :slug
|
105
|
+
belongs_to :author
|
106
|
+
|
107
|
+
def friendly_id
|
108
|
+
"#{object.name}-#{object.id}"
|
109
|
+
end
|
110
|
+
end
|
46
111
|
class InheritedRoleSerializer < RoleSerializer
|
47
112
|
cache key: 'inherited_role', only: [:name, :special_attribute]
|
48
113
|
attribute :special_attribute
|
@@ -51,10 +116,10 @@ module ActiveModelSerializers
|
|
51
116
|
setup do
|
52
117
|
cache_store.clear
|
53
118
|
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
54
|
-
@post = Post.new(title: 'New Post', body: 'Body')
|
119
|
+
@post = Post.new(id: 'post', title: 'New Post', body: 'Body')
|
55
120
|
@bio = Bio.new(id: 1, content: 'AMS Contributor')
|
56
|
-
@author = Author.new(name: 'Joao M. D. Moura')
|
57
|
-
@blog = Blog.new(id: 999, name: 'Custom blog', writer: @author
|
121
|
+
@author = Author.new(id: 'author', name: 'Joao M. D. Moura')
|
122
|
+
@blog = Blog.new(id: 999, name: 'Custom blog', writer: @author)
|
58
123
|
@role = Role.new(name: 'Great Author')
|
59
124
|
@location = Location.new(lat: '-23.550520', lng: '-46.633309')
|
60
125
|
@place = Place.new(name: 'Amazing Place')
|
@@ -117,7 +182,7 @@ module ActiveModelSerializers
|
|
117
182
|
def test_cache_key_definition
|
118
183
|
assert_equal('post', @post_serializer.class._cache_key)
|
119
184
|
assert_equal('writer', @author_serializer.class._cache_key)
|
120
|
-
|
185
|
+
assert_nil(@comment_serializer.class._cache_key)
|
121
186
|
end
|
122
187
|
|
123
188
|
def test_cache_key_interpolation_with_updated_at_when_cache_key_is_not_defined_on_object
|
@@ -160,7 +225,7 @@ module ActiveModelSerializers
|
|
160
225
|
|
161
226
|
def test_cache_options_definition
|
162
227
|
assert_equal({ expires_in: 0.1, skip_digest: true }, @post_serializer.class._cache_options)
|
163
|
-
|
228
|
+
assert_nil(@blog_serializer.class._cache_options)
|
164
229
|
assert_equal({ expires_in: 1.day, skip_digest: true }, @comment_serializer.class._cache_options)
|
165
230
|
end
|
166
231
|
|
@@ -171,8 +236,8 @@ module ActiveModelSerializers
|
|
171
236
|
|
172
237
|
def test_associations_separately_cache
|
173
238
|
cache_store.clear
|
174
|
-
|
175
|
-
|
239
|
+
assert_nil(cache_store.fetch(@post.cache_key))
|
240
|
+
assert_nil(cache_store.fetch(@comment.cache_key))
|
176
241
|
|
177
242
|
Timecop.freeze(Time.current) do
|
178
243
|
render_object_with_cache(@post)
|
@@ -244,7 +309,7 @@ module ActiveModelSerializers
|
|
244
309
|
# rubocop:disable Metrics/AbcSize
|
245
310
|
def test_a_serializer_rendered_by_two_adapter_returns_differently_fetch_attributes
|
246
311
|
Object.const_set(:Alert, Class.new(ActiveModelSerializers::Model) do
|
247
|
-
|
312
|
+
attributes :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
248
313
|
end)
|
249
314
|
Object.const_set(:UncachedAlertSerializer, Class.new(ActiveModel::Serializer) do
|
250
315
|
attributes :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
@@ -271,7 +336,7 @@ module ActiveModelSerializers
|
|
271
336
|
ended_at: nil,
|
272
337
|
updated_at: alert.updated_at,
|
273
338
|
created_at: alert.created_at
|
274
|
-
}
|
339
|
+
}.with_indifferent_access
|
275
340
|
expected_cached_jsonapi_attributes = {
|
276
341
|
id: '1',
|
277
342
|
type: 'alerts',
|
@@ -283,15 +348,15 @@ module ActiveModelSerializers
|
|
283
348
|
updated_at: alert.updated_at,
|
284
349
|
created_at: alert.created_at
|
285
350
|
}
|
286
|
-
}
|
351
|
+
}.with_indifferent_access
|
287
352
|
|
288
353
|
# Assert attributes are serialized correctly
|
289
354
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :attributes)
|
290
|
-
attributes_serialization = serializable_alert.as_json
|
355
|
+
attributes_serialization = serializable_alert.as_json.with_indifferent_access
|
291
356
|
assert_equal expected_fetch_attributes, alert.attributes
|
292
357
|
assert_equal alert.attributes, attributes_serialization
|
293
358
|
attributes_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
294
|
-
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key)
|
359
|
+
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key).with_indifferent_access
|
295
360
|
|
296
361
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :json_api)
|
297
362
|
jsonapi_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
@@ -303,7 +368,7 @@ module ActiveModelSerializers
|
|
303
368
|
serializable_alert = serializable(alert, serializer: UncachedAlertSerializer, adapter: :json_api)
|
304
369
|
assert_equal serializable_alert.as_json, jsonapi_serialization
|
305
370
|
|
306
|
-
cached_serialization = cache_store.fetch(jsonapi_cache_key)
|
371
|
+
cached_serialization = cache_store.fetch(jsonapi_cache_key).with_indifferent_access
|
307
372
|
assert_equal expected_cached_jsonapi_attributes, cached_serialization
|
308
373
|
ensure
|
309
374
|
Object.send(:remove_const, :Alert)
|
@@ -314,12 +379,14 @@ module ActiveModelSerializers
|
|
314
379
|
|
315
380
|
def test_uses_file_digest_in_cache_key
|
316
381
|
render_object_with_cache(@blog)
|
317
|
-
|
382
|
+
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
383
|
+
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{file_digest}"
|
318
384
|
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
319
385
|
end
|
320
386
|
|
321
387
|
def test_cache_digest_definition
|
322
|
-
|
388
|
+
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
389
|
+
assert_equal(file_digest, @post_serializer.class._cache_digest)
|
323
390
|
end
|
324
391
|
|
325
392
|
def test_object_cache_keys
|
@@ -329,11 +396,15 @@ module ActiveModelSerializers
|
|
329
396
|
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
|
330
397
|
|
331
398
|
assert_equal 3, actual.size
|
332
|
-
|
333
|
-
assert actual.any? { |key| key
|
334
|
-
|
399
|
+
expected_key = "comment/1/#{serializable.adapter.cache_key}"
|
400
|
+
assert actual.any? { |key| key == expected_key }, "actual '#{actual}' should include #{expected_key}"
|
401
|
+
expected_key = %r{post/post-\d+}
|
402
|
+
assert actual.any? { |key| key =~ expected_key }, "actual '#{actual}' should match '#{expected_key}'"
|
403
|
+
expected_key = %r{author/author-\d+}
|
404
|
+
assert actual.any? { |key| key =~ expected_key }, "actual '#{actual}' should match '#{expected_key}'"
|
335
405
|
end
|
336
406
|
|
407
|
+
# rubocop:disable Metrics/AbcSize
|
337
408
|
def test_fetch_attributes_from_cache
|
338
409
|
serializers = ActiveModel::Serializer::CollectionSerializer.new([@comment, @comment])
|
339
410
|
|
@@ -344,10 +415,10 @@ module ActiveModelSerializers
|
|
344
415
|
adapter_options = {}
|
345
416
|
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
346
417
|
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
347
|
-
cached_attributes = adapter_options.fetch(:cached_attributes)
|
418
|
+
cached_attributes = adapter_options.fetch(:cached_attributes).with_indifferent_access
|
348
419
|
|
349
420
|
include_directive = ActiveModelSerializers.default_include_directive
|
350
|
-
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
421
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive).with_indifferent_access
|
351
422
|
assert_equal manual_cached_attributes, cached_attributes
|
352
423
|
|
353
424
|
assert_equal cached_attributes["#{@comment.cache_key}/#{adapter_instance.cache_key}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
|
@@ -358,6 +429,7 @@ module ActiveModelSerializers
|
|
358
429
|
assert_equal cached_attributes["#{writer_cache_key}/#{adapter_instance.cache_key}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
359
430
|
end
|
360
431
|
end
|
432
|
+
# rubocop:enable Metrics/AbcSize
|
361
433
|
|
362
434
|
def test_cache_read_multi_with_fragment_cache_enabled
|
363
435
|
post_serializer = Class.new(ActiveModel::Serializer) do
|
@@ -516,7 +588,7 @@ module ActiveModelSerializers
|
|
516
588
|
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
517
589
|
assert_equal(role_hash, expected_result)
|
518
590
|
|
519
|
-
role.
|
591
|
+
role.id = 'this has been updated'
|
520
592
|
role.name = 'this was cached'
|
521
593
|
|
522
594
|
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|