diff --git a/lib/active_model_serializers/adapter/json_api/resource_identifier.rb b/lib/active_model_serializers/adapter/json_api/resource_identifier.rb index 3ff7118d..4c1f56ba 100644 --- a/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +++ b/lib/active_model_serializers/adapter/json_api/resource_identifier.rb @@ -8,12 +8,13 @@ module ActiveModelSerializers end def self.for_type_with_id(type, id, options) - return nil if id.blank? type = inflect_type(type) - { - id: id.to_s, - type: type_for(:no_class_needed, type, options) - } + type = type_for(:no_class_needed, type, options) + if id.blank? + { type: type } + else + { id: id.to_s, type: type } + end end def self.raw_type_from_serializer_object(object) @@ -38,8 +39,11 @@ module ActiveModelSerializers end def as_json - return nil if id.blank? - { id: id, type: type } + if id.blank? + { type: type } + else + { id: id.to_s, type: type } + end end protected diff --git a/test/adapter/json_api/resource_identifier_test.rb b/test/adapter/json_api/resource_identifier_test.rb deleted file mode 100644 index 62b7d93b..00000000 --- a/test/adapter/json_api/resource_identifier_test.rb +++ /dev/null @@ -1,110 +0,0 @@ -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 - cache only: :id - - def id - 'special_id' - end - 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_type_with_namespace - Object.const_set(:Admin, Module.new) - model = Class.new(::Model) - Admin.const_set(:PowerUser, model) - serializer = Class.new(ActiveModel::Serializer) - Admin.const_set(:PowerUserSerializer, serializer) - with_namespace_separator '--' do - admin_user = Admin::PowerUser.new - serializer = Admin::PowerUserSerializer.new(admin_user) - expected = { - id: admin_user.id, - type: 'admin--power-users' - } - - identifier = ResourceIdentifier.new(serializer, {}) - actual = identifier.as_json - assert_equal(expected, actual) - end - 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 - 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, nil) - 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, nil) - 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 diff --git a/test/adapter/json_api/type_test.rb b/test/adapter/json_api/type_test.rb index 40b84cf2..32074e0d 100644 --- a/test/adapter/json_api/type_test.rb +++ b/test/adapter/json_api/type_test.rb @@ -1,59 +1,191 @@ require 'test_helper' -module ActiveModel - class Serializer - module Adapter - class JsonApi - class TypeTest < ActiveSupport::TestCase - class StringTypeSerializer < ActiveModel::Serializer - attribute :name - type 'profile' - end +module ActiveModelSerializers + module Adapter + class JsonApi + class TypeTest < ActiveSupport::TestCase + class StringTypeSerializer < ActiveModel::Serializer + attribute :name + type 'profile' + end - class SymbolTypeSerializer < ActiveModel::Serializer - attribute :name - type :profile - end + class SymbolTypeSerializer < ActiveModel::Serializer + attribute :name + type :profile + end - setup do - @author = Author.new(id: 1, name: 'Steve K.') - end + setup do + @author = Author.new(id: 1, name: 'Steve K.') + end - def test_config_plural - with_jsonapi_resource_type :plural do - assert_type(@author, 'authors') - end + def test_config_plural + with_jsonapi_inflection :plural do + assert_type(@author, 'authors') end + end - def test_config_singular - with_jsonapi_resource_type :singular do - assert_type(@author, 'author') - end + def test_config_singular + with_jsonapi_inflection :singular do + assert_type(@author, 'author') end + end - def test_explicit_string_type_value - assert_type(@author, 'profile', serializer: StringTypeSerializer) + def test_explicit_string_type_value + assert_type(@author, 'profile', serializer: StringTypeSerializer) + end + + def test_explicit_symbol_type_value + assert_type(@author, 'profile', serializer: SymbolTypeSerializer) + end + + private + + def assert_type(resource, expected_type, opts = {}) + opts = opts.reverse_merge(adapter: :json_api) + hash = serializable(resource, opts).serializable_hash + assert_equal(expected_type, hash.fetch(:data).fetch(:type)) + end + end + class ResourceIdentifierTest < ActiveSupport::TestCase + class WithDefinedTypeSerializer < ActiveModel::Serializer + type 'with_defined_types' + end + + class WithDefinedIdSerializer < ActiveModel::Serializer + def id + 'special_id' end + end - def test_explicit_symbol_type_value - assert_type(@author, 'profile', serializer: SymbolTypeSerializer) + class FragmentedSerializer < ActiveModel::Serializer + cache only: :id + + def id + 'special_id' end + end - private + setup do + @model = Author.new(id: 1, name: 'Steve K.') + ActionController::Base.cache_store.clear + end - def assert_type(resource, expected_type, opts = {}) - opts = opts.reverse_merge(adapter: :json_api) - hash = serializable(resource, opts).serializable_hash - assert_equal(expected_type, hash.fetch(:data).fetch(:type)) + def test_defined_type + actual = with_jsonapi_inflection :plural do + actual_resource_identifier_object(WithDefinedTypeSerializer, @model) end + expected = { id: expected_model_id(@model), type: 'with-defined-types' } + assert_equal actual, expected + end - def with_jsonapi_resource_type(inflection) - old_inflection = ActiveModelSerializers.config.jsonapi_resource_type - ActiveModelSerializers.config.jsonapi_resource_type = inflection - yield - ensure - ActiveModelSerializers.config.jsonapi_resource_type = old_inflection + def test_defined_type_not_inflected + actual = with_jsonapi_inflection :singular do + actual_resource_identifier_object(WithDefinedTypeSerializer, @model) end + expected = { id: expected_model_id(@model), type: 'with-defined-types' } + assert_equal actual, expected + end + + def test_singular_type + actual = with_jsonapi_inflection :singular do + actual_resource_identifier_object(AuthorSerializer, @model) + end + expected = { id: expected_model_id(@model), type: 'author' } + assert_equal actual, expected + end + + def test_plural_type + actual = with_jsonapi_inflection :plural do + actual_resource_identifier_object(AuthorSerializer, @model) + end + expected = { id: expected_model_id(@model), type: 'authors' } + assert_equal actual, expected + end + + def test_type_with_namespace + Object.const_set(:Admin, Module.new) + model = Class.new(::Model) + Admin.const_set(:PowerUser, model) + serializer = Class.new(ActiveModel::Serializer) + Admin.const_set(:PowerUserSerializer, serializer) + with_namespace_separator '--' do + admin_user = Admin::PowerUser.new + serializer = Admin::PowerUserSerializer.new(admin_user) + expected = { + id: admin_user.id, + type: 'admin--power-users' + } + + identifier = ResourceIdentifier.new(serializer, {}) + actual = identifier.as_json + assert_equal(expected, actual) + end + end + + def test_id_defined_on_object + actual = actual_resource_identifier_object(AuthorSerializer, @model) + expected = { id: @model.id.to_s, type: expected_model_type(@model) } + assert_equal actual, expected + end + + def test_blank_id + model = Author.new(id: nil, name: 'Steve K.') + actual = actual_resource_identifier_object(AuthorSerializer, model) + expected = { type: expected_model_type(model) } + assert_equal actual, expected + end + + def test_for_type_with_id + id = 1 + actual = ResourceIdentifier.for_type_with_id('admin_user', id, {}) + expected = { id: '1', type: 'admin-users' } + assert_equal actual, expected + end + + def test_for_type_with_id_given_blank_id + id = '' + actual = ResourceIdentifier.for_type_with_id('admin_user', id, {}) + expected = { type: 'admin-users' } + assert_equal actual, expected + end + + def test_for_type_with_id_inflected + id = 2 + actual = with_jsonapi_inflection :singular do + ResourceIdentifier.for_type_with_id('admin_users', id, {}) + end + expected = { id: '2', type: 'admin-user' } + assert_equal actual, expected + end + + def test_id_defined_on_serializer + actual = actual_resource_identifier_object(WithDefinedIdSerializer, @model) + expected = { id: 'special_id', type: expected_model_type(@model) } + assert_equal actual, expected + end + + def test_id_defined_on_fragmented + actual = actual_resource_identifier_object(FragmentedSerializer, @model) + expected = { id: 'special_id', type: expected_model_type(@model) } + assert_equal actual, expected + end + + private + + def actual_resource_identifier_object(serializer_class, model) + serializer = serializer_class.new(model) + resource_identifier = ResourceIdentifier.new(serializer, nil) + resource_identifier.as_json + end + + def expected_model_type(model, inflection = ActiveModelSerializers.config.jsonapi_resource_type) + with_jsonapi_inflection inflection do + model.class.model_name.send(inflection) + end + end + + def expected_model_id(model) + model.id.to_s end end end diff --git a/test/support/serialization_testing.rb b/test/support/serialization_testing.rb index 524a3297..4a957976 100644 --- a/test/support/serialization_testing.rb +++ b/test/support/serialization_testing.rb @@ -47,6 +47,14 @@ module SerializationTesting ActiveModelSerializers.config.replace(old_config) end + def with_jsonapi_inflection(inflection) + original_inflection = ActiveModelSerializers.config.jsonapi_resource_type + ActiveModelSerializers.config.jsonapi_resource_type = inflection + yield + ensure + ActiveModelSerializers.config.jsonapi_resource_type = original_inflection + end + def with_serializer_lookup_disabled original_serializer_lookup = ActiveModelSerializers.config.serializer_lookup_enabled ActiveModelSerializers.config.serializer_lookup_enabled = false