mirror of
https://github.com/ditkrg/jsonapi-deserializable.git
synced 2026-01-22 13:56:50 +00:00
Make resource deserialization local. (#17)
This commit is contained in:
parent
046c1de821
commit
1707ec44f5
@ -35,9 +35,9 @@ module JSONAPI
|
||||
new(payload).to_h
|
||||
end
|
||||
|
||||
def initialize(payload)
|
||||
@document = payload
|
||||
@data = @document['data'] || {}
|
||||
def initialize(payload, root: '/data')
|
||||
@data = payload || {}
|
||||
@root = root
|
||||
@type = @data['type']
|
||||
@id = @data['id']
|
||||
@attributes = @data['attributes'] || {}
|
||||
@ -58,7 +58,7 @@ module JSONAPI
|
||||
|
||||
def register_mappings(keys, path)
|
||||
keys.each do |k|
|
||||
@reverse_mapping[k] = path
|
||||
@reverse_mapping[k] = @root + path
|
||||
end
|
||||
end
|
||||
|
||||
@ -74,7 +74,7 @@ module JSONAPI
|
||||
return {} unless block
|
||||
|
||||
hash = block.call(@type)
|
||||
register_mappings(hash.keys, '/data/type')
|
||||
register_mappings(hash.keys, '/type')
|
||||
hash
|
||||
end
|
||||
|
||||
@ -83,7 +83,7 @@ module JSONAPI
|
||||
return {} unless @id && block
|
||||
|
||||
hash = block.call(@id)
|
||||
register_mappings(hash.keys, '/data/id')
|
||||
register_mappings(hash.keys, '/id')
|
||||
hash
|
||||
end
|
||||
|
||||
@ -98,7 +98,7 @@ module JSONAPI
|
||||
return {} unless block
|
||||
|
||||
hash = block.call(val, self.class.key_formatter.call(key))
|
||||
register_mappings(hash.keys, "/data/attributes/#{key}")
|
||||
register_mappings(hash.keys, "/attributes/#{key}")
|
||||
hash
|
||||
end
|
||||
|
||||
@ -125,7 +125,7 @@ module JSONAPI
|
||||
id = val['data'] && val['data']['id']
|
||||
type = val['data'] && val['data']['type']
|
||||
hash = block.call(val, id, type, self.class.key_formatter.call(key))
|
||||
register_mappings(hash.keys, "/data/relationships/#{key}")
|
||||
register_mappings(hash.keys, "/relationships/#{key}")
|
||||
hash
|
||||
end
|
||||
# rubocop: enable Metrics/AbcSize
|
||||
@ -139,7 +139,7 @@ module JSONAPI
|
||||
ids = val['data'].map { |ri| ri['id'] }
|
||||
types = val['data'].map { |ri| ri['type'] }
|
||||
hash = block.call(val, ids, types, self.class.key_formatter.call(key))
|
||||
register_mappings(hash.keys, "/data/relationships/#{key}")
|
||||
register_mappings(hash.keys, "/relationships/#{key}")
|
||||
hash
|
||||
end
|
||||
# rubocop: enable Metrics/AbcSize
|
||||
|
||||
@ -5,11 +5,9 @@ describe JSONAPI::Deserializable::Resource, '.attribute' do
|
||||
context 'when a block is specified' do
|
||||
it 'creates corresponding field' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => { 'foo' => 'bar' }
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attribute(:foo) { |foo| Hash[foo: foo] }
|
||||
end
|
||||
@ -23,11 +21,9 @@ describe JSONAPI::Deserializable::Resource, '.attribute' do
|
||||
context 'when no block is specified' do
|
||||
it 'defaults to creating a field with same name' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => { 'foo' => 'bar' }
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attribute(:foo)
|
||||
end
|
||||
@ -41,7 +37,7 @@ describe JSONAPI::Deserializable::Resource, '.attribute' do
|
||||
|
||||
context 'when attribute is absent' do
|
||||
it 'does not create corresponding field if attribute is absent' do
|
||||
payload = { 'data' => { 'type' => 'foo', 'attributes' => {} } }
|
||||
payload = { 'type' => 'foo', 'attributes' => {} }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attribute(:foo) { |foo| Hash[foo: foo] }
|
||||
end
|
||||
@ -54,7 +50,7 @@ describe JSONAPI::Deserializable::Resource, '.attribute' do
|
||||
|
||||
context 'when attributes member is absent' do
|
||||
it 'does not create corresponding field if no attribute specified' do
|
||||
payload = { 'data' => { 'type' => 'foo' } }
|
||||
payload = { 'type' => 'foo' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attribute(:foo) { |foo| Hash[foo: foo] }
|
||||
end
|
||||
|
||||
@ -5,11 +5,9 @@ describe JSONAPI::Deserializable::Resource, '.attributes' do
|
||||
context 'when no keys are specified' do
|
||||
it 'defaults to creating fields with same name' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => { 'foo' => 'bar', 'baz' => 'foo' }
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attributes
|
||||
end
|
||||
@ -23,11 +21,9 @@ describe JSONAPI::Deserializable::Resource, '.attributes' do
|
||||
context 'when keys are specified' do
|
||||
it 'creates fields with same name for whitelisted attributes' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => { 'foo' => 'bar', 'baz' => 'foo', 'bar' => 'foo' }
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attributes :foo, :baz
|
||||
end
|
||||
@ -43,11 +39,9 @@ describe JSONAPI::Deserializable::Resource, '.attributes' do
|
||||
context 'when no keys are specified' do
|
||||
it 'defaults to creating fields with same name' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => { 'foo' => 'bar', 'baz' => 'foo' }
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attributes do |val, key|
|
||||
Hash["#{key}_attr".to_sym => val]
|
||||
@ -63,11 +57,9 @@ describe JSONAPI::Deserializable::Resource, '.attributes' do
|
||||
context 'when keys are specified' do
|
||||
it 'creates customized fields for whitelisted attributes' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => { 'foo' => 'bar', 'baz' => 'foo', 'bar' => 'foo' }
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attributes(:foo, :baz) do |val, key|
|
||||
Hash["#{key}_attr".to_sym => val]
|
||||
|
||||
@ -12,7 +12,6 @@ describe JSONAPI::Deserializable::Resource, '.has_many' do
|
||||
context 'relationship is not empty' do
|
||||
let(:payload) do
|
||||
{
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {
|
||||
'foo' => {
|
||||
@ -23,13 +22,12 @@ describe JSONAPI::Deserializable::Resource, '.has_many' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates corresponding fields' do
|
||||
actual = deserializable_foo.call(payload)
|
||||
expected = { foo_ids: %w(bar baz), foo_types: %w(foo foo),
|
||||
foo_rel: payload['data']['relationships']['foo'] }
|
||||
foo_rel: payload['relationships']['foo'] }
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
@ -48,7 +46,6 @@ describe JSONAPI::Deserializable::Resource, '.has_many' do
|
||||
context 'relationship is empty' do
|
||||
it 'creates corresponding fields' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {
|
||||
'foo' => {
|
||||
@ -56,10 +53,9 @@ describe JSONAPI::Deserializable::Resource, '.has_many' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
actual = deserializable_foo.call(payload)
|
||||
expected = { foo_ids: [], foo_types: [],
|
||||
foo_rel: payload['data']['relationships']['foo'] }
|
||||
foo_rel: payload['relationships']['foo'] }
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
@ -68,11 +64,9 @@ describe JSONAPI::Deserializable::Resource, '.has_many' do
|
||||
context 'relationship is absent' do
|
||||
it 'does not create corresponding fields' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {}
|
||||
}
|
||||
}
|
||||
actual = deserializable_foo.call(payload)
|
||||
expected = {}
|
||||
|
||||
@ -82,11 +76,7 @@ describe JSONAPI::Deserializable::Resource, '.has_many' do
|
||||
|
||||
context 'there is no relationships member' do
|
||||
it 'does not create corresponding fields' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo'
|
||||
}
|
||||
}
|
||||
payload = { 'type' => 'foo' }
|
||||
actual = deserializable_foo.call(payload)
|
||||
expected = {}
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ describe JSONAPI::Deserializable::Resource, '.has_one' do
|
||||
context 'relationship is not nil' do
|
||||
let(:payload) do
|
||||
{
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {
|
||||
'foo' => {
|
||||
@ -20,13 +19,12 @@ describe JSONAPI::Deserializable::Resource, '.has_one' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates corresponding fields' do
|
||||
actual = deserializable_foo.call(payload)
|
||||
expected = { foo_id: 'bar', foo_type: 'foo',
|
||||
foo_rel: payload['data']['relationships']['foo'] }
|
||||
foo_rel: payload['relationships']['foo'] }
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
@ -45,7 +43,6 @@ describe JSONAPI::Deserializable::Resource, '.has_one' do
|
||||
context 'relationship value is nil' do
|
||||
it 'creates corresponding fields' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {
|
||||
'foo' => {
|
||||
@ -53,11 +50,10 @@ describe JSONAPI::Deserializable::Resource, '.has_one' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual = deserializable_foo.call(payload)
|
||||
expected = { foo_id: nil, foo_type: nil,
|
||||
foo_rel: payload['data']['relationships']['foo'] }
|
||||
foo_rel: payload['relationships']['foo'] }
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
@ -66,11 +62,9 @@ describe JSONAPI::Deserializable::Resource, '.has_one' do
|
||||
context 'relationship is absent' do
|
||||
it 'does not create corresponding fields' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {}
|
||||
}
|
||||
}
|
||||
actual = deserializable_foo.call(payload)
|
||||
expected = {}
|
||||
|
||||
@ -80,11 +74,7 @@ describe JSONAPI::Deserializable::Resource, '.has_one' do
|
||||
|
||||
context 'there is no relationships member' do
|
||||
it 'does not create corresponding fields' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo'
|
||||
}
|
||||
}
|
||||
payload = { 'type' => 'foo' }
|
||||
actual = deserializable_foo.call(payload)
|
||||
expected = {}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ require 'spec_helper'
|
||||
|
||||
describe JSONAPI::Deserializable::Resource, '.id' do
|
||||
it 'creates corresponding field if id is present' do
|
||||
payload = { 'data' => { 'type' => 'foo', 'id' => 'bar' } }
|
||||
payload = { 'type' => 'foo', 'id' => 'bar' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
id { |i| Hash[id: i] }
|
||||
end
|
||||
@ -13,7 +13,7 @@ describe JSONAPI::Deserializable::Resource, '.id' do
|
||||
end
|
||||
|
||||
it 'does not create corresponding field if id is absent' do
|
||||
payload = { 'data' => { 'type' => 'foo' } }
|
||||
payload = { 'type' => 'foo' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
id { |i| Hash[id: i] }
|
||||
end
|
||||
@ -24,7 +24,7 @@ describe JSONAPI::Deserializable::Resource, '.id' do
|
||||
end
|
||||
|
||||
it 'defaults to creating an id field' do
|
||||
payload = { 'data' => { 'type' => 'foo', 'id' => 'bar' } }
|
||||
payload = { 'type' => 'foo', 'id' => 'bar' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
id
|
||||
end
|
||||
|
||||
@ -5,7 +5,6 @@ describe JSONAPI::Deserializable::Resource, '.key_format' do
|
||||
|
||||
let(:payload) do
|
||||
{
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => { 'foo' => 'bar', 'foo-bar' => 'baz' },
|
||||
'relationships' => {
|
||||
@ -17,7 +16,6 @@ describe JSONAPI::Deserializable::Resource, '.key_format' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'when all fields are whitelisted' do
|
||||
|
||||
@ -2,7 +2,7 @@ require 'spec_helper'
|
||||
|
||||
describe JSONAPI::Deserializable::Resource, '.type' do
|
||||
it 'creates corresponding field' do
|
||||
payload = { 'data' => { 'type' => 'foo' } }
|
||||
payload = { 'type' => 'foo' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
type { |t| Hash[type: t] }
|
||||
end
|
||||
@ -13,7 +13,7 @@ describe JSONAPI::Deserializable::Resource, '.type' do
|
||||
end
|
||||
|
||||
it 'defaults to creating a type field' do
|
||||
payload = { 'data' => { 'type' => 'foo' } }
|
||||
payload = { 'type' => 'foo' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
type
|
||||
end
|
||||
|
||||
@ -2,7 +2,7 @@ require 'spec_helper'
|
||||
|
||||
describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
it 'generates reverse mapping for default type' do
|
||||
payload = { 'data' => { 'type' => 'foo' } }
|
||||
payload = { 'type' => 'foo' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
type
|
||||
end
|
||||
@ -13,7 +13,7 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
end
|
||||
|
||||
it 'generates reverse mapping for overriden type' do
|
||||
payload = { 'data' => { 'type' => 'foo' } }
|
||||
payload = { 'type' => 'foo' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
type { |t| { custom_type: t } }
|
||||
end
|
||||
@ -24,7 +24,7 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
end
|
||||
|
||||
it 'generates reverse mapping for default id' do
|
||||
payload = { 'data' => { 'type' => 'foo', 'id' => 'bar' } }
|
||||
payload = { 'type' => 'foo', 'id' => 'bar' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
id
|
||||
end
|
||||
@ -35,7 +35,7 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
end
|
||||
|
||||
it 'generates reverse mapping for overriden id' do
|
||||
payload = { 'data' => { 'type' => 'foo', 'id' => 'bar' } }
|
||||
payload = { 'type' => 'foo', 'id' => 'bar' }
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
id { |i| { custom_id: i } }
|
||||
end
|
||||
@ -47,14 +47,12 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
|
||||
it 'generates reverse mapping for default attributes' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => {
|
||||
'foo' => 'bar',
|
||||
'baz' => 'fiz'
|
||||
}
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attributes
|
||||
end
|
||||
@ -67,14 +65,12 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
|
||||
it 'generates reverse mapping for locally overriden attributes' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => {
|
||||
'foo' => 'bar',
|
||||
'baz' => 'fiz'
|
||||
}
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attribute(:foo) { |foo| { custom_foo: foo } }
|
||||
end
|
||||
@ -86,14 +82,12 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
|
||||
it 'generates reverse mapping for globally overriden attributes' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'attributes' => {
|
||||
'foo' => 'bar',
|
||||
'baz' => 'fiz'
|
||||
}
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attributes do |value, key|
|
||||
{ "custom_#{key}".to_sym => value }
|
||||
@ -109,7 +103,6 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
|
||||
it 'generates reverse mapping for default has_one' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {
|
||||
'foo' => {
|
||||
@ -120,7 +113,6 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
has_one
|
||||
end
|
||||
@ -135,7 +127,6 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
|
||||
it 'generates reverse mapping for overriden has_one' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {
|
||||
'foo' => {
|
||||
@ -146,7 +137,6 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
has_one do |_val, id, type, key|
|
||||
{ "custom_#{key}_id".to_sym => id,
|
||||
@ -169,7 +159,6 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
|
||||
it 'generates reverse mapping for default has_many' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {
|
||||
'foo' => {
|
||||
@ -180,7 +169,6 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
has_many
|
||||
end
|
||||
@ -195,7 +183,6 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
|
||||
it 'generates reverse mapping for overriden has_many' do
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'foo',
|
||||
'relationships' => {
|
||||
'foo' => {
|
||||
@ -206,7 +193,6 @@ describe JSONAPI::Deserializable::Resource, '#reverse_mapping' do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
has_many do |_val, ids, types, key|
|
||||
{ "custom_#{key}_ids".to_sym => ids,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user