mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 14:29:31 +00:00
395 lines
11 KiB
Ruby
395 lines
11 KiB
Ruby
require 'test_helper'
|
|
require 'pathname'
|
|
|
|
class RenderJsonTest < ActionController::TestCase
|
|
class JsonRenderable
|
|
def as_json(options={})
|
|
hash = { a: :b, c: :d, e: :f }
|
|
hash.except!(*options[:except]) if options[:except]
|
|
hash
|
|
end
|
|
|
|
def to_json(options = {})
|
|
super except: [:c, :e]
|
|
end
|
|
end
|
|
|
|
class JsonSerializer
|
|
def initialize(object, options={})
|
|
@object, @options = object, options
|
|
end
|
|
|
|
def as_json(*)
|
|
hash = { object: serializable_hash, scope: @options[:scope].as_json }
|
|
hash.merge!(options: true) if @options[:options]
|
|
hash.merge!(check_defaults: true) if @options[:check_defaults]
|
|
hash
|
|
end
|
|
|
|
def serializable_hash
|
|
@object.as_json
|
|
end
|
|
end
|
|
|
|
class JsonSerializable
|
|
def initialize(skip=false)
|
|
@skip = skip
|
|
end
|
|
|
|
def active_model_serializer
|
|
JsonSerializer unless @skip
|
|
end
|
|
|
|
def as_json(*)
|
|
{ serializable_object: true }
|
|
end
|
|
end
|
|
|
|
class CustomSerializer
|
|
def initialize(*)
|
|
end
|
|
|
|
def as_json(*)
|
|
{ hello: true }
|
|
end
|
|
end
|
|
|
|
class AnotherCustomSerializer
|
|
def initialize(*)
|
|
end
|
|
|
|
def as_json(*)
|
|
{ rails: 'rocks' }
|
|
end
|
|
end
|
|
|
|
class DummyCustomSerializer < ActiveModel::Serializer
|
|
attributes :id
|
|
end
|
|
|
|
class HypermediaSerializable
|
|
def active_model_serializer
|
|
HypermediaSerializer
|
|
end
|
|
end
|
|
|
|
class HypermediaSerializer < ActiveModel::Serializer
|
|
def as_json(*)
|
|
{ link: hypermedia_url }
|
|
end
|
|
end
|
|
|
|
class CustomArraySerializer < ActiveModel::ArraySerializer
|
|
self.root = "items"
|
|
end
|
|
|
|
class TestController < ActionController::Base
|
|
protect_from_forgery
|
|
|
|
serialization_scope :current_user
|
|
attr_reader :current_user
|
|
|
|
def self.controller_path
|
|
'test'
|
|
end
|
|
|
|
def render_json_nil
|
|
render json: nil
|
|
end
|
|
|
|
def render_json_render_to_string
|
|
render text: render_to_string(json: '[]')
|
|
end
|
|
|
|
def render_json_hello_world
|
|
render json: ActiveSupport::JSON.encode(hello: 'world')
|
|
end
|
|
|
|
def render_json_hello_world_with_status
|
|
render json: ActiveSupport::JSON.encode(hello: 'world'), status: 401
|
|
end
|
|
|
|
def render_json_hello_world_with_callback
|
|
render json: ActiveSupport::JSON.encode(hello: 'world'), callback: 'alert'
|
|
end
|
|
|
|
def render_json_with_custom_content_type
|
|
render json: ActiveSupport::JSON.encode(hello: 'world'), content_type: 'text/javascript'
|
|
end
|
|
|
|
def render_symbol_json
|
|
render json: ActiveSupport::JSON.encode(hello: 'world')
|
|
end
|
|
|
|
def render_json_nil_with_custom_serializer
|
|
render json: nil, serializer: DummyCustomSerializer
|
|
end
|
|
|
|
|
|
def render_json_with_extra_options
|
|
render json: JsonRenderable.new, except: [:c, :e]
|
|
end
|
|
|
|
def render_json_without_options
|
|
render json: JsonRenderable.new
|
|
end
|
|
|
|
def render_json_with_serializer
|
|
@current_user = Struct.new(:as_json).new(current_user: true)
|
|
render json: JsonSerializable.new
|
|
end
|
|
|
|
def render_json_with_serializer_and_implicit_root
|
|
@current_user = Struct.new(:as_json).new(current_user: true)
|
|
render json: [JsonSerializable.new]
|
|
end
|
|
|
|
def render_json_with_serializer_and_options
|
|
@current_user = Struct.new(:as_json).new(current_user: true)
|
|
render json: JsonSerializable.new, options: true
|
|
end
|
|
|
|
def render_json_with_serializer_and_scope_option
|
|
@current_user = Struct.new(:as_json).new(current_user: true)
|
|
scope = Struct.new(:as_json).new(current_user: false)
|
|
render json: JsonSerializable.new, scope: scope
|
|
end
|
|
|
|
def render_json_with_serializer_api_but_without_serializer
|
|
@current_user = Struct.new(:as_json).new(current_user: true)
|
|
render json: JsonSerializable.new(true)
|
|
end
|
|
|
|
# To specify a custom serializer for an object, use :serializer.
|
|
def render_json_with_custom_serializer
|
|
render json: Object.new, serializer: CustomSerializer
|
|
end
|
|
|
|
# To specify a custom serializer for each item in the Array, use :each_serializer.
|
|
def render_json_array_with_custom_serializer
|
|
render json: [Object.new], each_serializer: CustomSerializer
|
|
end
|
|
|
|
def render_json_array_with_wrong_option
|
|
render json: [Object.new], serializer: CustomSerializer
|
|
end
|
|
|
|
def render_json_with_links
|
|
render json: HypermediaSerializable.new
|
|
end
|
|
|
|
def render_json_array_with_no_root
|
|
render json: [], root: false
|
|
end
|
|
|
|
def render_json_empty_array
|
|
render json: []
|
|
end
|
|
|
|
def render_json_array_with_custom_array_serializer
|
|
render json: [], serializer: CustomArraySerializer
|
|
end
|
|
|
|
|
|
private
|
|
def default_serializer_options
|
|
defaults = {}
|
|
defaults.merge!(check_defaults: true) if params[:check_defaults]
|
|
defaults.merge!(root: :awesome) if params[:check_default_root]
|
|
defaults.merge!(scope: :current_admin) if params[:check_default_scope]
|
|
defaults.merge!(serializer: AnotherCustomSerializer) if params[:check_default_serializer]
|
|
defaults.merge!(each_serializer: AnotherCustomSerializer) if params[:check_default_each_serializer]
|
|
defaults
|
|
end
|
|
end
|
|
|
|
tests TestController
|
|
|
|
def setup
|
|
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
|
|
# a more accurate simulation of what happens in "real life".
|
|
super
|
|
@controller.logger = Logger.new(nil)
|
|
|
|
@request.host = "www.nextangle.com"
|
|
end
|
|
|
|
def test_render_json_nil
|
|
get :render_json_nil
|
|
assert_equal 'null', @response.body
|
|
assert_equal 'application/json', @response.content_type
|
|
end
|
|
|
|
def test_render_json_render_to_string
|
|
get :render_json_render_to_string
|
|
assert_equal '[]', @response.body
|
|
end
|
|
|
|
def test_render_json_nil_with_custom_serializer
|
|
get :render_json_nil_with_custom_serializer
|
|
assert_equal "{\"dummy_custom\":null}", @response.body
|
|
end
|
|
|
|
def test_render_json
|
|
get :render_json_hello_world
|
|
assert_equal '{"hello":"world"}', @response.body
|
|
assert_equal 'application/json', @response.content_type
|
|
end
|
|
|
|
def test_render_json_with_status
|
|
get :render_json_hello_world_with_status
|
|
assert_equal '{"hello":"world"}', @response.body
|
|
assert_equal 401, @response.status
|
|
end
|
|
|
|
def test_render_json_with_callback
|
|
get :render_json_hello_world_with_callback
|
|
assert_equal 'alert({"hello":"world"})', @response.body
|
|
# For JSONP, Rails 3 uses application/json, but Rails 4 uses text/javascript
|
|
assert_match %r(application/json|text/javascript), @response.content_type.to_s
|
|
end
|
|
|
|
def test_render_json_with_custom_content_type
|
|
get :render_json_with_custom_content_type
|
|
assert_equal '{"hello":"world"}', @response.body
|
|
assert_equal 'text/javascript', @response.content_type
|
|
end
|
|
|
|
def test_render_symbol_json
|
|
get :render_symbol_json
|
|
assert_equal '{"hello":"world"}', @response.body
|
|
assert_equal 'application/json', @response.content_type
|
|
end
|
|
|
|
def test_render_json_forwards_extra_options
|
|
get :render_json_with_extra_options
|
|
assert_equal '{"a":"b"}', @response.body
|
|
assert_equal 'application/json', @response.content_type
|
|
end
|
|
|
|
def test_render_json_calls_to_json_from_object
|
|
get :render_json_without_options
|
|
assert_equal '{"a":"b"}', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer
|
|
get :render_json_with_serializer
|
|
assert_match '"scope":{"current_user":true}', @response.body
|
|
assert_match '"object":{"serializable_object":true}', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_checking_defaults
|
|
get :render_json_with_serializer, check_defaults: true
|
|
assert_match '"scope":{"current_user":true}', @response.body
|
|
assert_match '"object":{"serializable_object":true}', @response.body
|
|
assert_match '"check_defaults":true', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_checking_default_serailizer
|
|
get :render_json_with_serializer, check_default_serializer: true
|
|
assert_match '{"rails":"rocks"}', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_checking_default_scope
|
|
get :render_json_with_serializer, check_default_scope: true
|
|
assert_match '"scope":"current_admin"', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_and_implicit_root
|
|
get :render_json_with_serializer_and_implicit_root
|
|
assert_match '"test":[{"serializable_object":true}]', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_and_implicit_root_checking_default_each_serailizer
|
|
get :render_json_with_serializer_and_implicit_root, check_default_each_serializer: true
|
|
assert_match '"test":[{"rails":"rocks"}]', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_and_options
|
|
get :render_json_with_serializer_and_options
|
|
assert_match '"scope":{"current_user":true}', @response.body
|
|
assert_match '"object":{"serializable_object":true}', @response.body
|
|
assert_match '"options":true', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_and_scope_option
|
|
get :render_json_with_serializer_and_scope_option
|
|
assert_match '"scope":{"current_user":false}', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_and_scope_option_checking_default_scope
|
|
get :render_json_with_serializer_and_scope_option, check_default_scope: true
|
|
assert_match '"scope":{"current_user":false}', @response.body
|
|
end
|
|
|
|
def test_render_json_with_serializer_api_but_without_serializer
|
|
get :render_json_with_serializer_api_but_without_serializer
|
|
assert_match '{"serializable_object":true}', @response.body
|
|
end
|
|
|
|
def test_render_json_with_custom_serializer
|
|
get :render_json_with_custom_serializer
|
|
assert_match '{"hello":true}', @response.body
|
|
end
|
|
|
|
def test_render_json_with_custom_serializer_checking_default_serailizer
|
|
get :render_json_with_custom_serializer, check_default_serializer: true
|
|
assert_match '{"hello":true}', @response.body
|
|
end
|
|
|
|
def test_render_json_array_with_custom_serializer
|
|
get :render_json_array_with_custom_serializer
|
|
assert_match '{"test":[{"hello":true}]}', @response.body
|
|
end
|
|
|
|
def test_render_json_array_with_wrong_option
|
|
assert_raise ArgumentError do
|
|
get :render_json_array_with_wrong_option
|
|
end
|
|
end
|
|
|
|
def test_render_json_array_with_custom_serializer_checking_default_each_serailizer
|
|
get :render_json_array_with_custom_serializer, check_default_each_serializer: true
|
|
assert_match '{"test":[{"hello":true}]}', @response.body
|
|
end
|
|
|
|
def test_render_json_with_links
|
|
get :render_json_with_links
|
|
assert_match '{"link":"http://www.nextangle.com/hypermedia"}', @response.body
|
|
end
|
|
|
|
def test_render_json_array_with_no_root
|
|
get :render_json_array_with_no_root
|
|
assert_equal '[]', @response.body
|
|
end
|
|
|
|
def test_render_json_array_with_no_root_checking_default_root
|
|
get :render_json_array_with_no_root, check_default_root: true
|
|
assert_equal '[]', @response.body
|
|
end
|
|
|
|
def test_render_json_empty_array
|
|
get :render_json_empty_array
|
|
assert_equal '{"test":[]}', @response.body
|
|
end
|
|
|
|
def test_render_json_empty_array_checking_default_root
|
|
get :render_json_empty_array, check_default_root: true
|
|
assert_equal '{"awesome":[]}', @response.body
|
|
end
|
|
|
|
def test_render_json_empty_array_with_array_serializer_root_false
|
|
ActiveModel::ArraySerializer.root = false
|
|
get :render_json_empty_array
|
|
assert_equal '[]', @response.body
|
|
ensure # teardown
|
|
ActiveModel::ArraySerializer.root = nil
|
|
end
|
|
|
|
def test_render_json_array_with_custom_array_serializer
|
|
get :render_json_array_with_custom_array_serializer
|
|
assert_equal '{"items":[]}', @response.body
|
|
end
|
|
|
|
end
|