diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bd18c868..e8802a516 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ Fixes: - [#1488](https://github.com/rails-api/active_model_serializers/pull/1488) Require ActiveSupport's string inflections (@nate00) Misc: +- [#1543](https://github.com/rails-api/active_model_serializers/pull/1543) Add the changes missing from #1535. (@groyoh) +- [#1535](https://github.com/rails-api/active_model_serializers/pull/1535) Move the adapter and adapter folder to + active_model_serializers folder and changes the module namespace. (@domitian @bf4) - [#1497](https://github.com/rails-api/active_model_serializers/pull/1497) Add JRuby-9000 to appveyor.yml(@corainchicago) ### v0.10.0.rc4 (2016/01/27 11:00 +00:00) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 64bff0eca..bbf296fa3 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -23,6 +23,7 @@ class Serializer include Links include Meta include Type + require 'active_model/serializer/adapter' # @param resource [ActiveRecord::Base, ActiveModelSerializers::Model] # @return [ActiveModel::Serializer] @@ -44,7 +45,7 @@ def self.serializer_for(resource, options = {}) # @see ActiveModelSerializers::Adapter.lookup # Deprecated def self.adapter - warn 'Calling adapter method in Serializer, please use the ActiveModelSerializers::configured_adapter' + warn 'Calling adapter method in Serializer, please use the ActiveModelSerializers::Adapter.configured_adapter' ActiveModelSerializers::Adapter.lookup(config.adapter) end diff --git a/lib/active_model/serializer/adapter.rb b/lib/active_model/serializer/adapter.rb new file mode 100644 index 000000000..88f3165c7 --- /dev/null +++ b/lib/active_model/serializer/adapter.rb @@ -0,0 +1,59 @@ +module ActiveModel + class Serializer + module Adapter + class << self + def create(resource, options = {}) + warn "Calling deprecated ActiveModel::Serializer::Adater in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter" + ActiveModelSerializers::Adapter.create(resource, options) + end + + # @see ActiveModel::Serializer::Adapter.lookup + def adapter_class(adapter) + warn "Calling deprecated ActiveModel::Serializer::Adater in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter" + ActiveModelSerializers::Adapter.adapter_class(adapter) + end + + # @return Hash + def adapter_map + warn "Calling deprecated ActiveModel::Serializer::Adater in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter" + ActiveModelSerializers::Adapter.adapter_map + end + + # @return [Array] list of adapter names + def adapters + warn "Calling deprecated ActiveModel::Serializer::Adater in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter" + ActiveModelSerializers::Adapter.adapters + end + + # Adds an adapter 'klass' with 'name' to the 'adapter_map' + # Names are stringified and underscored + # @param name [Symbol, String, Class] name of the registered adapter + # @param klass [Class] adapter class itself, optional if name is the class + # @example + # AMS::Adapter.register(:my_adapter, MyAdapter) + # @note The registered name strips out 'ActiveModel::Serializer::Adapter::' + # so that registering 'ActiveModel::Serializer::Adapter::Json' and + # 'Json' will both register as 'json'. + def register(name, klass = name) + warn "Calling deprecated ActiveModel::Serializer::Adater in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter" + ActiveModelSerializers::Adapter.register(name, klass) + end + + # @param adapter [String, Symbol, Class] name to fetch adapter by + # @return [ActiveModel::Serializer::Adapter] subclass of Adapter + # @raise [UnknownAdapterError] + def lookup(adapter) + warn "Calling deprecated ActiveModel::Serializer::Adater in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter" + ActiveModelSerializers::Adapter.lookup(adapter) + end + end + + # Gotta be at the bottom to use the code above it :( + require 'active_model/serializer/adapter/base' + require 'active_model/serializer/adapter/null' + require 'active_model/serializer/adapter/attributes' + require 'active_model/serializer/adapter/json' + require 'active_model/serializer/adapter/json_api' + end + end +end diff --git a/lib/active_model/serializer/adapter/attributes.rb b/lib/active_model/serializer/adapter/attributes.rb new file mode 100644 index 000000000..e5ea842bc --- /dev/null +++ b/lib/active_model/serializer/adapter/attributes.rb @@ -0,0 +1,12 @@ +module ActiveModel + class Serializer + module Adapter + class Attributes < DelegateClass(ActiveModelSerializers::Adapter::Attributes) + def initialize(serializer, options = {}) + warn "Calling deprecated ActiveModel::Serializer::Adater::Attributes in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter::Attributes" + super(ActiveModelSerializers::Adapter::Attributes.new(serializer, options)) + end + end + end + end +end diff --git a/lib/active_model/serializer/adapter/base.rb b/lib/active_model/serializer/adapter/base.rb new file mode 100644 index 000000000..8f08f6afa --- /dev/null +++ b/lib/active_model/serializer/adapter/base.rb @@ -0,0 +1,7 @@ +module ActiveModel + class Serializer + module Adapter + Base = ActiveModelSerializers::Adapter::Base + end + end +end diff --git a/lib/active_model/serializer/adapter/json.rb b/lib/active_model/serializer/adapter/json.rb new file mode 100644 index 000000000..7c9b6d24f --- /dev/null +++ b/lib/active_model/serializer/adapter/json.rb @@ -0,0 +1,12 @@ +module ActiveModel + class Serializer + module Adapter + class Json < DelegateClass(ActiveModelSerializers::Adapter::Json) + def initialize(serializer, options = {}) + warn "Calling deprecated ActiveModel::Serializer::Adater::Json in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter::Json" + super(ActiveModelSerializers::Adapter::Json.new(serializer, options)) + end + end + end + end +end diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb new file mode 100644 index 000000000..702999e39 --- /dev/null +++ b/lib/active_model/serializer/adapter/json_api.rb @@ -0,0 +1,12 @@ +module ActiveModel + class Serializer + module Adapter + class JsonApi < DelegateClass(ActiveModelSerializers::Adapter::JsonApi) + def initialize(serializer, options = {}) + warn "Calling deprecated ActiveModel::Serializer::Adater::JsonApi in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter::JsonApi" + super(ActiveModelSerializers::Adapter::JsonApi.new(serializer, options)) + end + end + end + end +end diff --git a/lib/active_model/serializer/adapter/json_api/api_objects.rb b/lib/active_model/serializer/adapter/json_api/api_objects.rb deleted file mode 100644 index bad3173c3..000000000 --- a/lib/active_model/serializer/adapter/json_api/api_objects.rb +++ /dev/null @@ -1,13 +0,0 @@ -module ActiveModel - class Serializer - module Adapter - class JsonApi - module ApiObjects - extend ActiveSupport::Autoload - autoload :Relationship - autoload :ResourceIdentifier - end - end - end - end -end diff --git a/lib/active_model/serializer/adapter/json_api/api_objects/relationship.rb b/lib/active_model/serializer/adapter/json_api/api_objects/relationship.rb deleted file mode 100644 index dfaabc39b..000000000 --- a/lib/active_model/serializer/adapter/json_api/api_objects/relationship.rb +++ /dev/null @@ -1,52 +0,0 @@ -module ActiveModel - class Serializer - module Adapter - class JsonApi - module ApiObjects - class Relationship - def initialize(parent_serializer, serializer, options = {}, links = {}, meta = nil) - @object = parent_serializer.object - @scope = parent_serializer.scope - - @options = options - @data = data_for(serializer, options) - @links = links.each_with_object({}) do |(key, value), hash| - hash[key] = ActiveModelSerializers::Adapter::JsonApi::Link.new(parent_serializer, value).as_json - end - @meta = meta.respond_to?(:call) ? parent_serializer.instance_eval(&meta) : meta - end - - def as_json - hash = {} - hash[:data] = data if options[:include_data] - links = self.links - hash[:links] = links if links.any? - meta = self.meta - hash[:meta] = meta if meta - - hash - end - - protected - - attr_reader :object, :scope, :data, :options, :links, :meta - - private - - def data_for(serializer, options) - if serializer.respond_to?(:each) - serializer.map { |s| ResourceIdentifier.new(s).as_json } - else - if options[:virtual_value] - options[:virtual_value] - elsif serializer && serializer.object - ResourceIdentifier.new(serializer).as_json - end - end - end - end - end - end - end - end -end diff --git a/lib/active_model/serializer/adapter/json_api/api_objects/resource_identifier.rb b/lib/active_model/serializer/adapter/json_api/api_objects/resource_identifier.rb deleted file mode 100644 index 058f06031..000000000 --- a/lib/active_model/serializer/adapter/json_api/api_objects/resource_identifier.rb +++ /dev/null @@ -1,39 +0,0 @@ -module ActiveModel - class Serializer - module Adapter - class JsonApi - module ApiObjects - class ResourceIdentifier - def initialize(serializer) - @id = id_for(serializer) - @type = type_for(serializer) - end - - def as_json - { id: id, type: type } - end - - protected - - attr_reader :id, :type - - private - - def type_for(serializer) - return serializer._type if serializer._type - if ActiveModelSerializers.config.jsonapi_resource_type == :singular - serializer.object.class.model_name.singular - else - serializer.object.class.model_name.plural - end - end - - def id_for(serializer) - serializer.read_attribute_for_serialization(:id).to_s - end - end - end - end - end - end -end diff --git a/lib/active_model/serializer/adapter/json_api/meta.rb b/lib/active_model/serializer/adapter/json_api/meta.rb deleted file mode 100644 index 8fba89861..000000000 --- a/lib/active_model/serializer/adapter/json_api/meta.rb +++ /dev/null @@ -1,29 +0,0 @@ -module ActiveModel - class Serializer - module Adapter - class JsonApi - class Meta - def initialize(serializer) - @object = serializer.object - @scope = serializer.scope - - # Use the return value of the block unless it is nil. - if serializer._meta.respond_to?(:call) - @value = instance_eval(&serializer._meta) - else - @value = serializer._meta - end - end - - def as_json - @value - end - - protected - - attr_reader :object, :scope - end - end - end - end -end diff --git a/lib/active_model/serializer/adapter/null.rb b/lib/active_model/serializer/adapter/null.rb new file mode 100644 index 000000000..264daa94f --- /dev/null +++ b/lib/active_model/serializer/adapter/null.rb @@ -0,0 +1,12 @@ +module ActiveModel + class Serializer + module Adapter + class Null < DelegateClass(ActiveModelSerializers::Adapter::Null) + def initialize(serializer, options = {}) + warn "Calling deprecated ActiveModel::Serializer::Adater::Null in #{caller[0..2].join(', ')}. Please use ActiveModelSerializers::Adapter::Null" + super(ActiveModelSerializers::Adapter::Null.new(serializer, options)) + end + end + end + end +end diff --git a/lib/active_model_serializers/adapter/json_api.rb b/lib/active_model_serializers/adapter/json_api.rb index 841185f00..eaae0703a 100644 --- a/lib/active_model_serializers/adapter/json_api.rb +++ b/lib/active_model_serializers/adapter/json_api.rb @@ -5,9 +5,10 @@ class JsonApi < Base autoload :PaginationLinks autoload :FragmentCache autoload :Link - require 'active_model/serializer/adapter/json_api/meta' + autoload :Meta autoload :Deserialization - require 'active_model/serializer/adapter/json_api/api_objects' + autoload :ResourceIdentifier + autoload :Relationship # TODO: if we like this abstraction and other API objects to it, # then extract to its own file and require it. @@ -98,7 +99,7 @@ def resource_objects_for(serializers) end def process_resource(serializer, primary) - resource_identifier = ActiveModel::Serializer::Adapter::JsonApi::ApiObjects::ResourceIdentifier.new(serializer).as_json + resource_identifier = ResourceIdentifier.new(serializer).as_json return false unless @resource_identifiers.add?(resource_identifier) resource_object = resource_object_for(serializer) @@ -134,7 +135,7 @@ def attributes_for(serializer, fields) def resource_object_for(serializer) resource_object = cache_check(serializer) do - resource_object = ActiveModel::Serializer::Adapter::JsonApi::ApiObjects::ResourceIdentifier.new(serializer).as_json + resource_object = ResourceIdentifier.new(serializer).as_json requested_fields = fieldset && fieldset.fields_for(resource_object[:type]) attributes = attributes_for(serializer, requested_fields) @@ -158,7 +159,7 @@ def resource_object_for(serializer) def relationships_for(serializer, requested_associations) include_tree = ActiveModel::Serializer::IncludeTree.from_include_args(requested_associations) serializer.associations(include_tree).each_with_object({}) do |association, hash| - hash[association.key] = ActiveModel::Serializer::Adapter::JsonApi::ApiObjects::Relationship.new( + hash[association.key] = Relationship.new( serializer, association.serializer, association.options, @@ -179,7 +180,7 @@ def pagination_links_for(serializer, options) end def meta_for(serializer) - ActiveModel::Serializer::Adapter::JsonApi::Meta.new(serializer).as_json + Meta.new(serializer).as_json end end end diff --git a/lib/active_model_serializers/adapter/json_api/meta.rb b/lib/active_model_serializers/adapter/json_api/meta.rb new file mode 100644 index 000000000..4d818e72a --- /dev/null +++ b/lib/active_model_serializers/adapter/json_api/meta.rb @@ -0,0 +1,27 @@ +module ActiveModelSerializers + module Adapter + class JsonApi + class Meta + def initialize(serializer) + @object = serializer.object + @scope = serializer.scope + + # Use the return value of the block unless it is nil. + if serializer._meta.respond_to?(:call) + @value = instance_eval(&serializer._meta) + else + @value = serializer._meta + end + end + + def as_json + @value + end + + protected + + attr_reader :object, :scope + end + end + end +end diff --git a/lib/active_model_serializers/adapter/json_api/relationship.rb b/lib/active_model_serializers/adapter/json_api/relationship.rb new file mode 100644 index 000000000..a5923d2bf --- /dev/null +++ b/lib/active_model_serializers/adapter/json_api/relationship.rb @@ -0,0 +1,51 @@ +module ActiveModelSerializers + module Adapter + class JsonApi + class Relationship + def initialize(parent_serializer, serializer, options = {}, links = {}, meta = nil) + @options = options + @data = data_for(serializer, options) + @links = links_for(parent_serializer, links) + @meta = meta_for(parent_serializer, meta) + end + + def as_json + hash = {} + hash[:data] = data if options[:include_data] + links = self.links + hash[:links] = links if links.any? + meta = self.meta + hash[:meta] = meta if meta + + hash + end + + protected + + attr_reader :data, :options, :links, :meta + + private + + def links_for(parent_serializer, links) + links.each_with_object({}) do |(key, value), hash| + hash[key] = Link.new(parent_serializer, value).as_json + end + end + + def meta_for(parent_serializer, meta) + meta.respond_to?(:call) ? parent_serializer.instance_eval(&meta) : meta + end + + def data_for(serializer, options) + if serializer.respond_to?(:each) + serializer.map { |s| ResourceIdentifier.new(s).as_json } + elsif options[:virtual_value] + options[:virtual_value] + elsif serializer && serializer.object + ResourceIdentifier.new(serializer).as_json + end + end + end + end + end +end diff --git a/lib/active_model_serializers/adapter/json_api/resource_identifier.rb b/lib/active_model_serializers/adapter/json_api/resource_identifier.rb new file mode 100644 index 000000000..9a42fa63d --- /dev/null +++ b/lib/active_model_serializers/adapter/json_api/resource_identifier.rb @@ -0,0 +1,35 @@ +module ActiveModelSerializers + module Adapter + class JsonApi + class ResourceIdentifier + def initialize(serializer) + @id = id_for(serializer) + @type = type_for(serializer) + end + + def as_json + { id: id, type: type } + end + + protected + + attr_reader :id, :type + + private + + def type_for(serializer) + return serializer._type if serializer._type + if ActiveModelSerializers.config.jsonapi_resource_type == :singular + serializer.object.class.model_name.singular + else + serializer.object.class.model_name.plural + end + end + + def id_for(serializer) + serializer.read_attribute_for_serialization(:id).to_s + end + end + end + end +end diff --git a/lib/active_model_serializers/deserialization.rb b/lib/active_model_serializers/deserialization.rb index 9eaeef44d..6b6d417b4 100644 --- a/lib/active_model_serializers/deserialization.rb +++ b/lib/active_model_serializers/deserialization.rb @@ -3,11 +3,11 @@ module Deserialization module_function def jsonapi_parse(*args) - ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse(*args) + Adapter::JsonApi::Deserialization.parse(*args) end def jsonapi_parse!(*args) - ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(*args) + Adapter::JsonApi::Deserialization.parse!(*args) end end end diff --git a/test/active_model_serializers/adapter_for_test.rb b/test/active_model_serializers/adapter_for_test.rb index 8dfbc9f3f..2707fc8e0 100644 --- a/test/active_model_serializers/adapter_for_test.rb +++ b/test/active_model_serializers/adapter_for_test.rb @@ -2,88 +2,82 @@ module ActiveModelSerializers class AdapterForTest < ActiveSupport::TestCase UnknownAdapterError = ::ActiveModelSerializers::Adapter::UnknownAdapterError - def setup - @previous_adapter = ActiveModelSerializers.config.adapter - end - - def teardown - ActiveModelSerializers.config.adapter = @previous_adapter - end - - def test_serializer_adapter_returns_configured__adapter - assert_output(nil, /ActiveModelSerializers::configured_adapter/) do + def test_serializer_adapter_returns_configured_adapter + assert_output(nil, /ActiveModelSerializers::Adapter.configured_adapter/) do assert_equal ActiveModelSerializers::Adapter.configured_adapter, ActiveModel::Serializer.adapter end end def test_returns_default_adapter - adapter = ActiveModelSerializers::Adapter.configured_adapter - assert_equal ActiveModelSerializers::Adapter::Attributes, adapter + with_adapter_config_setup do + adapter = ActiveModelSerializers::Adapter.configured_adapter + assert_equal ActiveModelSerializers::Adapter::Attributes, adapter + end end def test_overwrite_adapter_with_symbol - ActiveModelSerializers.config.adapter = :null + with_adapter_config_setup do + ActiveModelSerializers.config.adapter = :null - adapter = ActiveModelSerializers::Adapter.configured_adapter - assert_equal ActiveModelSerializers::Adapter::Null, adapter - ensure - ActiveModelSerializers.config.adapter = @previous_adapter + adapter = ActiveModelSerializers::Adapter.configured_adapter + assert_equal ActiveModelSerializers::Adapter::Null, adapter + end end def test_overwrite_adapter_with_camelcased_symbol - ActiveModelSerializers.config.adapter = :JsonApi + with_adapter_config_setup do + ActiveModelSerializers.config.adapter = :JsonApi - adapter = ActiveModelSerializers::Adapter.configured_adapter - assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter - ensure - ActiveModelSerializers.config.adapter = @previous_adapter + adapter = ActiveModelSerializers::Adapter.configured_adapter + assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter + end end def test_overwrite_adapter_with_string - ActiveModelSerializers.config.adapter = 'json_api' + with_adapter_config_setup do + ActiveModelSerializers.config.adapter = 'json_api' - adapter = ActiveModelSerializers::Adapter.configured_adapter - assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter - ensure - ActiveModelSerializers.config.adapter = @previous_adapter + adapter = ActiveModelSerializers::Adapter.configured_adapter + assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter + end end def test_overwrite_adapter_with_a_camelcased_string - ActiveModelSerializers.config.adapter = 'JsonApi' + with_adapter_config_setup do + ActiveModelSerializers.config.adapter = 'JsonApi' - adapter = ActiveModelSerializers::Adapter.configured_adapter - assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter - ensure - ActiveModelSerializers.config.adapter = @previous_adapter + adapter = ActiveModelSerializers::Adapter.configured_adapter + assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter + end end def test_overwrite_adapter_with_class - ActiveModelSerializers.config.adapter = ActiveModelSerializers::Adapter::Null + with_adapter_config_setup do + ActiveModelSerializers.config.adapter = ActiveModelSerializers::Adapter::Null - adapter = ActiveModelSerializers::Adapter.configured_adapter - assert_equal ActiveModelSerializers::Adapter::Null, adapter - ensure - ActiveModelSerializers.config.adapter = @previous_adapter + adapter = ActiveModelSerializers::Adapter.configured_adapter + assert_equal ActiveModelSerializers::Adapter::Null, adapter + end end def test_raises_exception_if_invalid_symbol_given - ActiveModelSerializers.config.adapter = :unknown + with_adapter_config_setup do + ActiveModelSerializers.config.adapter = :unknown - assert_raises UnknownAdapterError do - ActiveModelSerializers::Adapter.configured_adapter + assert_raises UnknownAdapterError do + ActiveModelSerializers::Adapter.configured_adapter + end end - ensure - ActiveModelSerializers.config.adapter = @previous_adapter end def test_raises_exception_if_it_does_not_know_hot_to_infer_adapter - ActiveModelSerializers.config.adapter = 42 + with_adapter_config_setup do + ActiveModelSerializers.config.adapter = 42 - assert_raises UnknownAdapterError do - ActiveModelSerializers::Adapter.configured_adapter + assert_raises UnknownAdapterError do + ActiveModelSerializers::Adapter.configured_adapter + end end - ensure - ActiveModelSerializers.config.adapter = @previous_adapter end def test_adapter_class_for_known_adapter @@ -199,5 +193,14 @@ def test_inherited_adapter_hooks_register_subclass_of_registered_adapter Object.send(:remove_const, :MyAdapter) Object.send(:remove_const, :MySubclassedAdapter) end + + private + + def with_adapter_config_setup + previous_adapter = ActiveModelSerializers.config.adapter + yield + ensure + ActiveModelSerializers.config.adapter = previous_adapter + end end end diff --git a/test/adapter/deprecation_test.rb b/test/adapter/deprecation_test.rb new file mode 100644 index 000000000..97bea9b32 --- /dev/null +++ b/test/adapter/deprecation_test.rb @@ -0,0 +1,87 @@ +require 'test_helper' +module ActiveModel + class Serializer + module Adapter + class DeprecationTest < ActiveSupport::TestCase + setup do + post = Post.new(id: 1) + @serializer = PostSerializer.new(post) + end + + def test_null_adapter_deprecation + assert_deprecated_adapter(Null) + end + + def test_json_adapter_deprecation + assert_deprecated_adapter(Json) + end + + def test_json_api_adapter_deprecation + assert_deprecated_adapter(JsonApi) + end + + def test_attributes_adapter_deprecation + assert_deprecated_adapter(Attributes) + end + + def test_adapter_create_deprecation + assert_deprecated do + Adapter.create(@serializer) + end + end + + def test_adapter_adapter_map_deprecation + assert_deprecated do + Adapter.adapter_map + end + end + + def test_adapter_adapters_deprecation + assert_deprecated do + Adapter.adapters + end + end + + def test_adapter_adapter_class_deprecation + assert_deprecated do + Adapter.adapter_class(:json_api) + end + end + + def test_adapter_register_deprecation + assert_deprecated do + Adapter.register(:test, Class.new(Base)) + Adapter.adapter_map.delete("test") + end + end + + def test_adapter_lookup_deprecation + assert_deprecated do + Adapter.lookup(:json_api) + end + end + + def test_adapter_subclass_deprecation + assert_deprecated do + Class.new(Base) + end + end + + private + + def assert_deprecated_adapter(adapter) + assert_deprecated do + adapter.new(@serializer) + end + end + + def assert_deprecated + message = /deprecated/ + assert_output(nil, message) do + yield + end + end + end + end + end +end diff --git a/test/adapter/json_api/api_objects/relationship_test.rb b/test/adapter/json_api/api_objects/relationship_test.rb deleted file mode 100644 index 26577bc96..000000000 --- a/test/adapter/json_api/api_objects/relationship_test.rb +++ /dev/null @@ -1,168 +0,0 @@ -require 'test_helper' - -module ActiveModel - class Serializer - module Adapter - class JsonApi - module ApiObjects - class RelationshipTest < ActiveSupport::TestCase - def setup - @blog = Blog.new(id: 1) - @author = Author.new(id: 1, name: 'Steve K.', blog: @blog) - @serializer = BlogSerializer.new(@blog) - ActionController::Base.cache_store.clear - end - - def test_relationship_with_data - expected = { - data: { - id: '1', - type: 'blogs' - } - } - test_relationship(expected, options: { include_data: true }) - end - - def test_relationship_with_nil_model - @serializer = BlogSerializer.new(nil) - expected = { data: nil } - test_relationship(expected, options: { include_data: true }) - end - - def test_relationship_with_nil_serializer - @serializer = nil - expected = { data: nil } - test_relationship(expected, options: { include_data: true }) - end - - def test_relationship_with_data_array - posts = [Post.new(id: 1), Post.new(id: 2)] - @serializer = ActiveModel::Serializer::CollectionSerializer.new(posts) - @author.posts = posts - @author.blog = nil - expected = { - data: [ - { - id: '1', - type: 'posts' - }, - { - id: '2', - type: 'posts' - } - ] - } - test_relationship(expected, options: { include_data: true }) - end - - def test_relationship_data_not_included - test_relationship({}, options: { include_data: false }) - end - - def test_relationship_simple_link - links = { self: 'a link' } - test_relationship({ links: { self: 'a link' } }, links: links) - end - - def test_relationship_many_links - links = { - self: 'a link', - related: 'another link' - } - expected = { - links: { - self: 'a link', - related: 'another link' - } - } - test_relationship(expected, links: links) - end - - def test_relationship_block_link - links = { self: proc { "#{object.id}" } } - expected = { links: { self: "#{@blog.id}" } } - test_relationship(expected, links: links) - end - - def test_relationship_block_link_with_meta - links = { - self: proc do - href "#{object.id}" - meta(id: object.id) - end - } - expected = { - links: { - self: { - href: "#{@blog.id}", - meta: { id: @blog.id } - } - } - } - test_relationship(expected, links: links) - end - - def test_relationship_simple_meta - meta = { id: '1' } - expected = { meta: meta } - test_relationship(expected, meta: meta) - end - - def test_relationship_block_meta - meta = proc do - { id: object.id } - end - expected = { - meta: { - id: @blog.id - } - } - test_relationship(expected, meta: meta) - end - - def test_relationship_with_everything - links = { - self: 'a link', - related: proc do - href "#{object.id}" - meta object.id - end - - } - meta = proc do - { id: object.id } - end - expected = { - data: { - id: '1', - type: 'blogs' - }, - links: { - self: 'a link', - related: { - href: '1', meta: 1 - } - }, - meta: { - id: @blog.id - } - } - test_relationship(expected, meta: meta, options: { include_data: true }, links: links) - end - - private - - def test_relationship(expected, params = {}) - options = params.fetch(:options, {}) - links = params.fetch(:links, {}) - meta = params[:meta] - parent_serializer = AuthorSerializer.new(@author) - relationship = Relationship.new(parent_serializer, @serializer, options, links, meta) - assert_equal(expected, relationship.as_json) - end - end - end - end - end - end -end diff --git a/test/adapter/json_api/api_objects/resource_identifier_test.rb b/test/adapter/json_api/api_objects/resource_identifier_test.rb deleted file mode 100644 index a40f07071..000000000 --- a/test/adapter/json_api/api_objects/resource_identifier_test.rb +++ /dev/null @@ -1,88 +0,0 @@ -require 'test_helper' - -module ActiveModel - class Serializer - module Adapter - class JsonApi - module ApiObjects - class ResourceIdentifierTest < ActiveSupport::TestCase - class WithDefinedTypeSerializer < Serializer - type 'with_defined_type' - end - - class WithDefinedIdSerializer < Serializer - def id - 'special_id' - end - end - - class FragmentedSerializer < Serializer; end - - def setup - @model = Author.new(id: 1, name: 'Steve K.') - ActionController::Base.cache_store.clear - end - - def test_defined_type - test_type(WithDefinedTypeSerializer, 'with_defined_type') - end - - def test_singular_type - test_type_inflection(AuthorSerializer, 'author', :singular) - end - - def test_plural_type - test_type_inflection(AuthorSerializer, 'authors', :plural) - end - - def test_id_defined_on_object - test_id(AuthorSerializer, @model.id.to_s) - end - - def test_id_defined_on_serializer - test_id(WithDefinedIdSerializer, 'special_id') - end - - def test_id_defined_on_fragmented - FragmentedSerializer.fragmented(WithDefinedIdSerializer.new(@author)) - test_id(FragmentedSerializer, 'special_id') - end - - private - - def test_type_inflection(serializer_class, expected_type, inflection) - original_inflection = ActiveModelSerializers.config.jsonapi_resource_type - ActiveModelSerializers.config.jsonapi_resource_type = inflection - test_type(serializer_class, expected_type) - ActiveModelSerializers.config.jsonapi_resource_type = original_inflection - end - - def test_type(serializer_class, expected_type) - serializer = serializer_class.new(@model) - resource_identifier = ResourceIdentifier.new(serializer) - expected = { - id: @model.id.to_s, - type: expected_type - } - - assert_equal(expected, resource_identifier.as_json) - end - - def test_id(serializer_class, id) - serializer = serializer_class.new(@model) - resource_identifier = ResourceIdentifier.new(serializer) - inflection = ActiveModelSerializers.config.jsonapi_resource_type - type = @model.class.model_name.send(inflection) - expected = { - id: id, - type: type - } - - assert_equal(expected, resource_identifier.as_json) - end - end - end - end - end - end -end diff --git a/test/adapter/json_api/relationship_test.rb b/test/adapter/json_api/relationship_test.rb index b612a9809..64d8c5494 100644 --- a/test/adapter/json_api/relationship_test.rb +++ b/test/adapter/json_api/relationship_test.rb @@ -1,190 +1,162 @@ require 'test_helper' -module ActiveModel - class Serializer - module Adapter - class JsonApi - class RelationshipTest < ActiveSupport::TestCase - RelationshipAuthor = Class.new(::Model) - class RelationshipAuthorSerializer < ActiveModel::Serializer - has_one :bio do - link :self, '//example.com/link_author/relationships/bio' - end - - has_one :profile do - link :related do - "//example.com/profiles/#{object.profile.id}" - end - end - - has_many :locations do - link :related do - ids = object.locations.map(&:id).join(',') - href "//example.com/locations/#{ids}" - end - end - - has_many :posts do - link :related do - ids = object.posts.map(&:id).join(',') - href "//example.com/posts/#{ids}" - meta ids: ids - end - end +module ActiveModelSerializers + module Adapter + class JsonApi + class RelationshipTest < ActiveSupport::TestCase + setup do + @blog = Blog.new(id: 1) + @author = Author.new(id: 1, name: 'Steve K.', blog: @blog) + @serializer = BlogSerializer.new(@blog) + ActionController::Base.cache_store.clear + end - has_many :comments do - link :self do - meta ids: [1] - end - end + def test_relationship_with_data + expected = { + data: { + id: '1', + type: 'blogs' + } + } + test_relationship(expected, options: { include_data: true }) + end - has_many :roles do - meta count: object.posts.count - end + def test_relationship_with_nil_model + @serializer = BlogSerializer.new(nil) + expected = { data: nil } + test_relationship(expected, options: { include_data: true }) + end - has_one :blog do - link :self, '//example.com/link_author/relationships/blog' - include_data false - end + def test_relationship_with_nil_serializer + @serializer = nil + expected = { data: nil } + test_relationship(expected, options: { include_data: true }) + end - belongs_to :reviewer do - meta name: 'Dan Brown' - include_data true - end + def test_relationship_with_data_array + posts = [Post.new(id: 1), Post.new(id: 2)] + @serializer = ActiveModel::Serializer::CollectionSerializer.new(posts) + @author.posts = posts + @author.blog = nil + expected = { + data: [ + { + id: '1', + type: 'posts' + }, + { + id: '2', + type: 'posts' + } + ] + } + test_relationship(expected, options: { include_data: true }) + end - has_many :likes do - link :related do - ids = object.likes.map(&:id).join(',') - href "//example.com/likes/#{ids}" - meta ids: ids - end - meta liked: object.likes.any? - end - end + def test_relationship_data_not_included + test_relationship({}, options: { include_data: false }) + end - def setup - @post = Post.new(id: 1337, comments: [], author: nil) - @blog = Blog.new(id: 1337, name: 'extra') - @bio = Bio.new(id: 1337) - @like = Like.new(id: 1337) - @role = Role.new(id: 1337) - @profile = Profile.new(id: 1337) - @location = Location.new(id: 1337) - @reviewer = Author.new(id: 1337) - @comment = Comment.new(id: 1337) - @author = RelationshipAuthor.new( - id: 1337, - posts: [@post], - blog: @blog, - reviewer: @reviewer, - bio: @bio, - likes: [@like], - roles: [@role], - locations: [@location], - profile: @profile, - comments: [@comment] - ) - end + def test_relationship_simple_link + links = { self: 'a link' } + test_relationship({ links: { self: 'a link' } }, links: links) + end - def test_relationship_simple_link - expected = { - data: { - id: '1337', - type: 'bios' - }, - links: { - self: '//example.com/link_author/relationships/bio' - } + def test_relationship_many_links + links = { + self: 'a link', + related: 'another link' + } + expected = { + links: { + self: 'a link', + related: 'another link' } - assert_relationship(:bio, expected) - end + } + test_relationship(expected, links: links) + end - def test_relationship_block_link - expected = { - data: { id: '1337', type: 'profiles' }, - links: { related: '//example.com/profiles/1337' } - } - assert_relationship(:profile, expected) - end + def test_relationship_block_link + links = { self: proc { "#{object.id}" } } + expected = { links: { self: "#{@blog.id}" } } + test_relationship(expected, links: links) + end - def test_relationship_block_link_href - expected = { - data: [{ id: '1337', type: 'locations' }], - links: { - related: { href: '//example.com/locations/1337' } + def test_relationship_block_link_with_meta + links = { + self: proc do + href "#{object.id}" + meta(id: object.id) + end + } + expected = { + links: { + self: { + href: "#{@blog.id}", + meta: { id: @blog.id } } } - assert_relationship(:locations, expected) - end + } + test_relationship(expected, links: links) + end - def test_relationship_block_link_href_and_meta - expected = { - data: [{ id: '1337', type: 'posts' }], - links: { - related: { - href: '//example.com/posts/1337', - meta: { ids: '1337' } - } - } - } - assert_relationship(:posts, expected) - end + def test_relationship_simple_meta + meta = { id: '1' } + expected = { meta: meta } + test_relationship(expected, meta: meta) + end - def test_relationship_block_link_meta - expected = { - data: [{ id: '1337', type: 'comments' }], - links: { - self: { - meta: { ids: [1] } - } - } - } - assert_relationship(:comments, expected) + def test_relationship_block_meta + meta = proc do + { id: object.id } end - - def test_relationship_meta - expected = { - data: [{ id: '1337', type: 'roles' }], - meta: { count: 1 } + expected = { + meta: { + id: @blog.id } - assert_relationship(:roles, expected) - end + } + test_relationship(expected, meta: meta) + end - def test_relationship_not_including_data - expected = { - links: { self: '//example.com/link_author/relationships/blog' } - } - assert_relationship(:blog, expected) - end + def test_relationship_with_everything + links = { + self: 'a link', + related: proc do + href "#{object.id}" + meta object.id + end - def test_relationship_including_data_explicit - expected = { - data: { id: '1337', type: 'authors' }, - meta: { name: 'Dan Brown' } - } - assert_relationship(:reviewer, expected) + } + meta = proc do + { id: object.id } end - - def test_relationship_with_everything - expected = { - data: [{ id: '1337', type: 'likes' }], - links: { - related: { - href: '//example.com/likes/1337', - meta: { ids: '1337' } - } - }, - meta: { liked: true } + expected = { + data: { + id: '1', + type: 'blogs' + }, + links: { + self: 'a link', + related: { + href: '1', meta: 1 + } + }, + meta: { + id: @blog.id } - assert_relationship(:likes, expected) - end + } + test_relationship(expected, meta: meta, options: { include_data: true }, links: links) + end - private + private - def assert_relationship(relationship_name, expected) - hash = serializable(@author, adapter: :json_api).serializable_hash - assert_equal(expected, hash[:data][:relationships][relationship_name]) - end + def test_relationship(expected, params = {}) + options = params.fetch(:options, {}) + links = params.fetch(:links, {}) + meta = params[:meta] + parent_serializer = AuthorSerializer.new(@author) + relationship = Relationship.new(parent_serializer, @serializer, options, links, meta) + assert_equal(expected, relationship.as_json) end end end diff --git a/test/adapter/json_api/relationships_test.rb b/test/adapter/json_api/relationships_test.rb new file mode 100644 index 000000000..b612a9809 --- /dev/null +++ b/test/adapter/json_api/relationships_test.rb @@ -0,0 +1,192 @@ +require 'test_helper' + +module ActiveModel + class Serializer + module Adapter + class JsonApi + class RelationshipTest < ActiveSupport::TestCase + RelationshipAuthor = Class.new(::Model) + class RelationshipAuthorSerializer < ActiveModel::Serializer + has_one :bio do + link :self, '//example.com/link_author/relationships/bio' + end + + has_one :profile do + link :related do + "//example.com/profiles/#{object.profile.id}" + end + end + + has_many :locations do + link :related do + ids = object.locations.map(&:id).join(',') + href "//example.com/locations/#{ids}" + end + end + + has_many :posts do + link :related do + ids = object.posts.map(&:id).join(',') + href "//example.com/posts/#{ids}" + meta ids: ids + end + end + + has_many :comments do + link :self do + meta ids: [1] + end + end + + has_many :roles do + meta count: object.posts.count + end + + has_one :blog do + link :self, '//example.com/link_author/relationships/blog' + include_data false + end + + belongs_to :reviewer do + meta name: 'Dan Brown' + include_data true + end + + has_many :likes do + link :related do + ids = object.likes.map(&:id).join(',') + href "//example.com/likes/#{ids}" + meta ids: ids + end + meta liked: object.likes.any? + end + end + + def setup + @post = Post.new(id: 1337, comments: [], author: nil) + @blog = Blog.new(id: 1337, name: 'extra') + @bio = Bio.new(id: 1337) + @like = Like.new(id: 1337) + @role = Role.new(id: 1337) + @profile = Profile.new(id: 1337) + @location = Location.new(id: 1337) + @reviewer = Author.new(id: 1337) + @comment = Comment.new(id: 1337) + @author = RelationshipAuthor.new( + id: 1337, + posts: [@post], + blog: @blog, + reviewer: @reviewer, + bio: @bio, + likes: [@like], + roles: [@role], + locations: [@location], + profile: @profile, + comments: [@comment] + ) + end + + def test_relationship_simple_link + expected = { + data: { + id: '1337', + type: 'bios' + }, + links: { + self: '//example.com/link_author/relationships/bio' + } + } + assert_relationship(:bio, expected) + end + + def test_relationship_block_link + expected = { + data: { id: '1337', type: 'profiles' }, + links: { related: '//example.com/profiles/1337' } + } + assert_relationship(:profile, expected) + end + + def test_relationship_block_link_href + expected = { + data: [{ id: '1337', type: 'locations' }], + links: { + related: { href: '//example.com/locations/1337' } + } + } + assert_relationship(:locations, expected) + end + + def test_relationship_block_link_href_and_meta + expected = { + data: [{ id: '1337', type: 'posts' }], + links: { + related: { + href: '//example.com/posts/1337', + meta: { ids: '1337' } + } + } + } + assert_relationship(:posts, expected) + end + + def test_relationship_block_link_meta + expected = { + data: [{ id: '1337', type: 'comments' }], + links: { + self: { + meta: { ids: [1] } + } + } + } + assert_relationship(:comments, expected) + end + + def test_relationship_meta + expected = { + data: [{ id: '1337', type: 'roles' }], + meta: { count: 1 } + } + assert_relationship(:roles, expected) + end + + def test_relationship_not_including_data + expected = { + links: { self: '//example.com/link_author/relationships/blog' } + } + assert_relationship(:blog, expected) + end + + def test_relationship_including_data_explicit + expected = { + data: { id: '1337', type: 'authors' }, + meta: { name: 'Dan Brown' } + } + assert_relationship(:reviewer, expected) + end + + def test_relationship_with_everything + expected = { + data: [{ id: '1337', type: 'likes' }], + links: { + related: { + href: '//example.com/likes/1337', + meta: { ids: '1337' } + } + }, + meta: { liked: true } + } + assert_relationship(:likes, expected) + end + + private + + def assert_relationship(relationship_name, expected) + hash = serializable(@author, adapter: :json_api).serializable_hash + assert_equal(expected, hash[:data][:relationships][relationship_name]) + end + end + end + end + end +end diff --git a/test/adapter/json_api/resource_identifier_test.rb b/test/adapter/json_api/resource_identifier_test.rb new file mode 100644 index 000000000..0fc6d33ba --- /dev/null +++ b/test/adapter/json_api/resource_identifier_test.rb @@ -0,0 +1,85 @@ +require 'test_helper' + +module ActiveModelSerializers + module Adapter + class JsonApi + class ResourceIdentifierTest < ActiveSupport::TestCase + class WithDefinedTypeSerializer < ActiveModel::Serializer + type 'with_defined_type' + end + + class WithDefinedIdSerializer < ActiveModel::Serializer + def id + 'special_id' + end + end + + class FragmentedSerializer < ActiveModel::Serializer; end + + setup do + @model = Author.new(id: 1, name: 'Steve K.') + ActionController::Base.cache_store.clear + end + + def test_defined_type + test_type(WithDefinedTypeSerializer, 'with_defined_type') + end + + def test_singular_type + test_type_inflection(AuthorSerializer, 'author', :singular) + end + + def test_plural_type + test_type_inflection(AuthorSerializer, 'authors', :plural) + end + + def test_id_defined_on_object + test_id(AuthorSerializer, @model.id.to_s) + end + + def test_id_defined_on_serializer + test_id(WithDefinedIdSerializer, 'special_id') + end + + def test_id_defined_on_fragmented + FragmentedSerializer.fragmented(WithDefinedIdSerializer.new(@author)) + test_id(FragmentedSerializer, 'special_id') + end + + private + + def test_type_inflection(serializer_class, expected_type, inflection) + original_inflection = ActiveModelSerializers.config.jsonapi_resource_type + ActiveModelSerializers.config.jsonapi_resource_type = inflection + test_type(serializer_class, expected_type) + ensure + ActiveModelSerializers.config.jsonapi_resource_type = original_inflection + end + + def test_type(serializer_class, expected_type) + serializer = serializer_class.new(@model) + resource_identifier = ResourceIdentifier.new(serializer) + expected = { + id: @model.id.to_s, + type: expected_type + } + + assert_equal(expected, resource_identifier.as_json) + end + + def test_id(serializer_class, id) + serializer = serializer_class.new(@model) + resource_identifier = ResourceIdentifier.new(serializer) + inflection = ActiveModelSerializers.config.jsonapi_resource_type + type = @model.class.model_name.send(inflection) + expected = { + id: id, + type: type + } + + assert_equal(expected, resource_identifier.as_json) + end + end + end + end +end