From 15f5d507a4ef2575e428d74d2c8b644454deb2d1 Mon Sep 17 00:00:00 2001 From: Taylor Chaparro Date: Thu, 11 Jul 2024 17:36:15 -0700 Subject: [PATCH] feat: allow kebab case for deserialization options: only, except --- .../adapter/json_api/deserialization.rb | 17 +++++--- test/adapter/json_api/parse_test.rb | 39 ++++++++++++++++--- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/lib/active_model_serializers/adapter/json_api/deserialization.rb b/lib/active_model_serializers/adapter/json_api/deserialization.rb index 1af20d94a..885dda26c 100644 --- a/lib/active_model_serializers/adapter/json_api/deserialization.rb +++ b/lib/active_model_serializers/adapter/json_api/deserialization.rb @@ -95,6 +95,9 @@ def parse(document, options = {}) attributes['id'] = primary_data['id'] if primary_data['id'] relationships = primary_data['relationships'] || {} + attributes = transform_keys(attributes, options) + relationships = transform_keys(relationships, options) + filter_fields(attributes, options) filter_fields(relationships, options) @@ -143,9 +146,11 @@ def validate_payload(payload) # @api private def filter_fields(fields, options) - if (only = options[:only]) + only = transform_keys(options[:only], options) + except = transform_keys(options[:except], options) + if only fields.slice!(*Array(only).map(&:to_s)) - elsif (except = options[:except]) + elsif except fields.except!(*Array(except).map(&:to_s)) end end @@ -157,7 +162,7 @@ def field_key(field, options) # @api private def parse_attributes(attributes, options) - transform_keys(attributes, options) + attributes .map { |(k, v)| { field_key(k, options) => v } } .reduce({}, :merge) end @@ -199,15 +204,15 @@ def parse_relationship(assoc_name, assoc_data, options) # @api private def parse_relationships(relationships, options) - transform_keys(relationships, options) + relationships .map { |(k, v)| parse_relationship(k, v['data'], options) } .reduce({}, :merge) end # @api private - def transform_keys(hash, options) + def transform_keys(hash_or_array, options = {}) transform = options[:key_transform] || :underscore - CaseTransform.send(transform, hash) + CaseTransform.send(transform, hash_or_array) end end end diff --git a/test/adapter/json_api/parse_test.rb b/test/adapter/json_api/parse_test.rb index d2b562190..bc30585f9 100644 --- a/test/adapter/json_api/parse_test.rb +++ b/test/adapter/json_api/parse_test.rb @@ -13,7 +13,8 @@ def setup 'id' => 'zorglub', 'attributes' => { 'title' => 'Ember Hamster', - 'src' => 'http://example.com/images/productivity.png' + 'src' => 'http://example.com/images/productivity.png', + 'created-at' => '2000-01-01' }, 'relationships' => { 'author' => { @@ -38,7 +39,8 @@ def setup src: 'http://example.com/images/productivity.png', author_id: nil, photographer_id: '9', - comment_ids: %w(1 2) + comment_ids: %w(1 2), + created_at: '2000-01-01' } @illformed_payloads = [nil, @@ -87,17 +89,40 @@ def test_illformed_payloads_unsafe end def test_filter_fields_only - parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, only: [:id, :title, :author]) + parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, only: [:id, :title, :author, :created_at]) + expected = { + id: 'zorglub', + title: 'Ember Hamster', + author_id: nil, + created_at: '2000-01-01' + } + assert_equal(expected, parsed_hash) + end + + def test_filter_fields_only_from_kebab_case + parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, only: [:id, :title, :author, :'created-at']) expected = { id: 'zorglub', title: 'Ember Hamster', - author_id: nil + author_id: nil, + created_at: '2000-01-01' } assert_equal(expected, parsed_hash) end def test_filter_fields_except parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, except: [:id, :title, :author]) + expected = { + src: 'http://example.com/images/productivity.png', + photographer_id: '9', + comment_ids: %w(1 2), + created_at: '2000-01-01' + } + assert_equal(expected, parsed_hash) + end + + def test_filter_fields_except_from_kebab_case + parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, except: [:id, :title, :author, :'created-at']) expected = { src: 'http://example.com/images/productivity.png', photographer_id: '9', @@ -114,7 +139,8 @@ def test_keys src: 'http://example.com/images/productivity.png', user_id: nil, photographer_id: '9', - comment_ids: %w(1 2) + comment_ids: %w(1 2), + created_at: '2000-01-01' } assert_equal(expected, parsed_hash) end @@ -128,7 +154,8 @@ def test_polymorphic author_id: nil, photographer_id: '9', photographer_type: 'Person', - comment_ids: %w(1 2) + comment_ids: %w(1 2), + created_at: '2000-01-01' } assert_equal(expected, parsed_hash) end