Skip to content

Commit

Permalink
Bring back assert_serializer
Browse files Browse the repository at this point in the history
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
  • Loading branch information
maurogeorge committed Sep 2, 2015
1 parent e0b74d8 commit 8ae9222
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### 0.10.0

* adds `assert_serializer` test helper [@maurogeorge]
* adds adapters pattern
* adds support for `meta` and `meta_key` [@kurko]
* adds method to override association [@kurko]
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,34 @@ class PostSerializer < ActiveModel::Serializer
end
```

## Test helpers

AMS provides a `assert_serializer` method to be used on your controller tests to
assert that a specific serializer was used.

```ruby
class PostsControllerTest < ActionController::TestCase
test "should render post serializer" do
get :index
assert_serializer "PostSerializer"
# # return a custom error message
# assert_serializer "PostSerializer", "PostSerializer not rendered"
#
# # assert that the instance of PostSerializer was rendered
# assert_serializer PostSerializer
#
# # assert that the "PostSerializer" serializer was rendered
# assert_serializer :post_serializer
#
# # assert that the rendered serializer starts with "Post"
# assert_serializer %r{\APost.+\Z}
#
# # assert that no serializer was rendered
# assert_serializer nil
end
end
```

## Getting Help

If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new).
Expand Down
78 changes: 78 additions & 0 deletions lib/action_controller/serialization_test_case.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
module ActionController
module SerializationAssertions
extend ActiveSupport::Concern

included do
setup :setup_serialization_subscriptions
teardown :teardown_serialization_subscriptions
end

# Asserts that the request was rendered with the appropriate serializers.
#
# # assert that the "PostSerializer" serializer was rendered
# assert_serializer "PostSerializer"
#
# # return a custom error message
# assert_serializer "PostSerializer", "PostSerializer not rendered"
#
# # assert that the instance of PostSerializer was rendered
# assert_serializer PostSerializer
#
# # assert that the "PostSerializer" serializer was rendered
# assert_serializer :post_serializer
#
# # assert that the rendered serializer starts with "Post"
# assert_serializer %r{\APost.+\Z}
#
# # assert that no serializer was rendered
# assert_serializer nil
#
def assert_serializer(expectation, message = nil)
# Force body to be read in case the template is being streamed.
response.body

msg = message || "expecting <#{expectation.inspect}> but rendering with <#{serializers}>"

matches_serializer = case expectation
when ->(exp) { exp.kind_of?(Class) && exp < ActiveModel::Serializer }
serializers.include?(expectation.name)
when Symbol
expectation = expectation.to_s.camelize
serializers.include?(expectation)
when String
!expectation.empty? && serializers.include?(expectation)
when Regexp
serializers.any? do |serializer|
serializer.match(expectation)
end
when NilClass
serializers.blank?
else
raise ArgumentError, "assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil"
end
assert(matches_serializer, msg)
end

private

ActiveModelSerializers.silence_warnings do
attr_reader :serializers
end

def setup_serialization_subscriptions
@serializers = []
ActiveSupport::Notifications.subscribe(event_name) do |name, start, finish, id, payload|
serializer = payload[:serializer]
serializers << serializer
end
end

def teardown_serialization_subscriptions
ActiveSupport::Notifications.unsubscribe(event_name)
end

def event_name
"serialize.active_model_serializers"
end
end
end
9 changes: 9 additions & 0 deletions lib/active_model/serializable_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def initialize(resource, options = {})
# returns the contents of the block
def self.serialize(resource, options = {})
serializable_resource = SerializableResource.new(resource, options)
serializable_resource.instrument
if block_given?
yield serializable_resource
else
Expand Down Expand Up @@ -74,6 +75,14 @@ def serializer?
use_adapter? && !!(serializer)
end

def instrument
if serializer?
event_name = "serialize.active_model_serializers"
payload = { serializer: serializer.name }
ActiveSupport::Notifications.instrument(event_name, payload)
end
end

private

ActiveModelSerializers.silence_warnings do
Expand Down
2 changes: 2 additions & 0 deletions lib/active_model_serializers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ def silence_warnings
require 'active_model/serializer/version'

require 'action_controller/serialization'
require 'action_controller/serialization_test_case'
ActiveSupport.on_load(:action_controller) do
include ::ActionController::Serialization
ActionDispatch::Reloader.to_prepare do
ActiveModel::Serializer.serializers_cache.clear
end
ActionController::TestCase.send(:include, ::ActionController::SerializationAssertions)
end

require 'active_model/serializer/railtie'
70 changes: 70 additions & 0 deletions test/action_controller/serialization_test_case_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require 'test_helper'

module ActionController
module SerializationsAssertions
class RenderSerializerTest < ActionController::TestCase
class MyController < ActionController::Base
def render_using_serializer
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
end

def render_text
render text: 'ok'
end

def render_template
prepend_view_path "./test/fixtures"
render template: "template"
end
end

tests MyController

def test_supports_specifying_serializers_with_a_serializer_class
get :render_using_serializer
assert_serializer ProfileSerializer
end

def test_supports_specifying_serializers_with_a_regexp
get :render_using_serializer
assert_serializer %r{\AProfile.+\Z}
end

def test_supports_specifying_serializers_with_a_string
get :render_using_serializer
assert_serializer 'ProfileSerializer'
end

def test_supports_specifying_serializers_with_a_symbol
get :render_using_serializer
assert_serializer :profile_serializer
end

def test_supports_specifying_serializers_with_a_nil
get :render_text
assert_serializer nil
end

def test_raises_descriptive_error_message_when_serializer_was_not_rendered
get :render_using_serializer
e = assert_raise ActiveSupport::TestCase::Assertion do
assert_serializer 'PostSerializer'
end
assert_match 'expecting <"PostSerializer"> but rendering with <["ProfileSerializer"]>', e.message
end

def test_raises_argument_error_when_asserting_with_invalid_object
get :render_using_serializer
e = assert_raise ArgumentError do
assert_serializer Hash
end
assert_match 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil', e.message
end

def test_does_not_overwrite_notification_subscriptions
get :render_template
assert_template "template"
end
end
end
end
1 change: 1 addition & 0 deletions test/fixtures/template.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>Hello.</p>

0 comments on commit 8ae9222

Please sign in to comment.