Skip to content

Commit 8ae9222

Browse files
committed
Bring back assert_serializer
The `assert_serializer` test helper was removed at some point. This patch brings back the `assert_serializer` test helper. This is the last revision[1] that has the helper. The original helper was used as base. [1]: https://github.com/rails-api/active_model_serializers/tree/610aeb2e9297fa31b8d561f0be9a4597f0258f8c
1 parent e0b74d8 commit 8ae9222

File tree

7 files changed

+189
-0
lines changed

7 files changed

+189
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### 0.10.0
22

3+
* adds `assert_serializer` test helper [@maurogeorge]
34
* adds adapters pattern
45
* adds support for `meta` and `meta_key` [@kurko]
56
* adds method to override association [@kurko]

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,34 @@ class PostSerializer < ActiveModel::Serializer
335335
end
336336
```
337337

338+
## Test helpers
339+
340+
AMS provides a `assert_serializer` method to be used on your controller tests to
341+
assert that a specific serializer was used.
342+
343+
```ruby
344+
class PostsControllerTest < ActionController::TestCase
345+
test "should render post serializer" do
346+
get :index
347+
assert_serializer "PostSerializer"
348+
# # return a custom error message
349+
# assert_serializer "PostSerializer", "PostSerializer not rendered"
350+
#
351+
# # assert that the instance of PostSerializer was rendered
352+
# assert_serializer PostSerializer
353+
#
354+
# # assert that the "PostSerializer" serializer was rendered
355+
# assert_serializer :post_serializer
356+
#
357+
# # assert that the rendered serializer starts with "Post"
358+
# assert_serializer %r{\APost.+\Z}
359+
#
360+
# # assert that no serializer was rendered
361+
# assert_serializer nil
362+
end
363+
end
364+
```
365+
338366
## Getting Help
339367

340368
If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new).
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
module ActionController
2+
module SerializationAssertions
3+
extend ActiveSupport::Concern
4+
5+
included do
6+
setup :setup_serialization_subscriptions
7+
teardown :teardown_serialization_subscriptions
8+
end
9+
10+
# Asserts that the request was rendered with the appropriate serializers.
11+
#
12+
# # assert that the "PostSerializer" serializer was rendered
13+
# assert_serializer "PostSerializer"
14+
#
15+
# # return a custom error message
16+
# assert_serializer "PostSerializer", "PostSerializer not rendered"
17+
#
18+
# # assert that the instance of PostSerializer was rendered
19+
# assert_serializer PostSerializer
20+
#
21+
# # assert that the "PostSerializer" serializer was rendered
22+
# assert_serializer :post_serializer
23+
#
24+
# # assert that the rendered serializer starts with "Post"
25+
# assert_serializer %r{\APost.+\Z}
26+
#
27+
# # assert that no serializer was rendered
28+
# assert_serializer nil
29+
#
30+
def assert_serializer(expectation, message = nil)
31+
# Force body to be read in case the template is being streamed.
32+
response.body
33+
34+
msg = message || "expecting <#{expectation.inspect}> but rendering with <#{serializers}>"
35+
36+
matches_serializer = case expectation
37+
when ->(exp) { exp.kind_of?(Class) && exp < ActiveModel::Serializer }
38+
serializers.include?(expectation.name)
39+
when Symbol
40+
expectation = expectation.to_s.camelize
41+
serializers.include?(expectation)
42+
when String
43+
!expectation.empty? && serializers.include?(expectation)
44+
when Regexp
45+
serializers.any? do |serializer|
46+
serializer.match(expectation)
47+
end
48+
when NilClass
49+
serializers.blank?
50+
else
51+
raise ArgumentError, "assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil"
52+
end
53+
assert(matches_serializer, msg)
54+
end
55+
56+
private
57+
58+
ActiveModelSerializers.silence_warnings do
59+
attr_reader :serializers
60+
end
61+
62+
def setup_serialization_subscriptions
63+
@serializers = []
64+
ActiveSupport::Notifications.subscribe(event_name) do |name, start, finish, id, payload|
65+
serializer = payload[:serializer]
66+
serializers << serializer
67+
end
68+
end
69+
70+
def teardown_serialization_subscriptions
71+
ActiveSupport::Notifications.unsubscribe(event_name)
72+
end
73+
74+
def event_name
75+
"serialize.active_model_serializers"
76+
end
77+
end
78+
end

lib/active_model/serializable_resource.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def initialize(resource, options = {})
1919
# returns the contents of the block
2020
def self.serialize(resource, options = {})
2121
serializable_resource = SerializableResource.new(resource, options)
22+
serializable_resource.instrument
2223
if block_given?
2324
yield serializable_resource
2425
else
@@ -74,6 +75,14 @@ def serializer?
7475
use_adapter? && !!(serializer)
7576
end
7677

78+
def instrument
79+
if serializer?
80+
event_name = "serialize.active_model_serializers"
81+
payload = { serializer: serializer.name }
82+
ActiveSupport::Notifications.instrument(event_name, payload)
83+
end
84+
end
85+
7786
private
7887

7988
ActiveModelSerializers.silence_warnings do

lib/active_model_serializers.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ def silence_warnings
1919
require 'active_model/serializer/version'
2020

2121
require 'action_controller/serialization'
22+
require 'action_controller/serialization_test_case'
2223
ActiveSupport.on_load(:action_controller) do
2324
include ::ActionController::Serialization
2425
ActionDispatch::Reloader.to_prepare do
2526
ActiveModel::Serializer.serializers_cache.clear
2627
end
28+
ActionController::TestCase.send(:include, ::ActionController::SerializationAssertions)
2729
end
2830

2931
require 'active_model/serializer/railtie'
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
require 'test_helper'
2+
3+
module ActionController
4+
module SerializationsAssertions
5+
class RenderSerializerTest < ActionController::TestCase
6+
class MyController < ActionController::Base
7+
def render_using_serializer
8+
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
9+
end
10+
11+
def render_text
12+
render text: 'ok'
13+
end
14+
15+
def render_template
16+
prepend_view_path "./test/fixtures"
17+
render template: "template"
18+
end
19+
end
20+
21+
tests MyController
22+
23+
def test_supports_specifying_serializers_with_a_serializer_class
24+
get :render_using_serializer
25+
assert_serializer ProfileSerializer
26+
end
27+
28+
def test_supports_specifying_serializers_with_a_regexp
29+
get :render_using_serializer
30+
assert_serializer %r{\AProfile.+\Z}
31+
end
32+
33+
def test_supports_specifying_serializers_with_a_string
34+
get :render_using_serializer
35+
assert_serializer 'ProfileSerializer'
36+
end
37+
38+
def test_supports_specifying_serializers_with_a_symbol
39+
get :render_using_serializer
40+
assert_serializer :profile_serializer
41+
end
42+
43+
def test_supports_specifying_serializers_with_a_nil
44+
get :render_text
45+
assert_serializer nil
46+
end
47+
48+
def test_raises_descriptive_error_message_when_serializer_was_not_rendered
49+
get :render_using_serializer
50+
e = assert_raise ActiveSupport::TestCase::Assertion do
51+
assert_serializer 'PostSerializer'
52+
end
53+
assert_match 'expecting <"PostSerializer"> but rendering with <["ProfileSerializer"]>', e.message
54+
end
55+
56+
def test_raises_argument_error_when_asserting_with_invalid_object
57+
get :render_using_serializer
58+
e = assert_raise ArgumentError do
59+
assert_serializer Hash
60+
end
61+
assert_match 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil', e.message
62+
end
63+
64+
def test_does_not_overwrite_notification_subscriptions
65+
get :render_template
66+
assert_template "template"
67+
end
68+
end
69+
end
70+
end

test/fixtures/template.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>Hello.</p>

0 commit comments

Comments
 (0)