From 350ddb5c8de23f2642473fbc3776adc286c32b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82?= <720354+jembezmamy@users.noreply.github.com> Date: Fri, 22 Jul 2022 15:12:14 +0200 Subject: [PATCH 1/2] failing test --- ...conditional_fields_with_key_format_spec.rb | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 spec/resource/conditional_fields_with_key_format_spec.rb diff --git a/spec/resource/conditional_fields_with_key_format_spec.rb b/spec/resource/conditional_fields_with_key_format_spec.rb new file mode 100644 index 0000000..0146b1a --- /dev/null +++ b/spec/resource/conditional_fields_with_key_format_spec.rb @@ -0,0 +1,168 @@ +require 'spec_helper' + +describe JSONAPI::Serializable::Resource do + let(:klass) do + Class.new(JSONAPI::Serializable::Resource) do + type 'foo' + id { 'bar' } + end + end + + let(:object) { User.new } + let(:resource) do + klass.new(object: object, conditional: conditional) + end + + context 'when the attribute is conditional and keys are formatted' do + before do + klass.class_eval do + extend JSONAPI::Serializable::Resource::KeyFormat + key_format -> (k) { k.to_s.upcase } + extend JSONAPI::Serializable::Resource::ConditionalFields + end + end + + subject { resource.as_jsonapi[:attributes] } + + context 'via :if' do + before do + klass.class_eval do + attribute :name, if: proc { @conditional } do + 'foo' + end + end + end + + context 'and the clause is true' do + let(:conditional) { true } + + it { is_expected.to eq(NAME: 'foo') } + end + + context 'and the clause is false' do + let(:conditional) { false } + + it { is_expected.to be_nil } + end + end + + context 'via :unless' do + before do + klass.class_eval do + attribute :name, unless: proc { @conditional } do + 'foo' + end + end + end + + context 'and the clause is true' do + let(:conditional) { true } + + it { is_expected.to be_nil } + end + + context 'and the clause is false' do + let(:conditional) { false } + + it { is_expected.to eq(NAME: 'foo') } + end + end + end + + context 'when relationship is conditional and keys are formatted' do + before do + klass.class_eval do + extend JSONAPI::Serializable::Resource::KeyFormat + key_format -> (k) { k.to_s.upcase } + extend JSONAPI::Serializable::Resource::ConditionalFields + + relationship :posts, if: -> { false } + end + end + + subject { resource.as_jsonapi[:relationships] } + + context 'and the clause is false' do + let(:conditional) { false } + + it { is_expected.to be_nil } + end + end + + context 'when a link is conditional and keys are formatted' do + before do + klass.class_eval do + extend JSONAPI::Serializable::Resource::KeyFormat + key_format -> (k) { k.to_s.upcase } + extend JSONAPI::Serializable::Resource::ConditionalFields + + link :self, if: proc { @conditional } do + 'https://example.com/users/42' + end + end + end + + subject { resource.as_jsonapi[:links] } + + context 'and the clause is true' do + let(:conditional) { true } + + it { is_expected.to eq(self: 'https://example.com/users/42') } + end + + context 'and the clause is false' do + let(:conditional) { false } + + it { is_expected.to be_nil } + end + end + + context 'when inheriting and keys are formatted' do + before do + klass.class_eval do + extend JSONAPI::Serializable::Resource::KeyFormat + key_format -> (k) { k.to_s.upcase } + extend JSONAPI::Serializable::Resource::ConditionalFields + + relationship :posts, if: -> { false } + end + end + + let(:subclass) { Class.new(klass) } + let(:resource) { subclass.new(object: object) } + + subject { resource.as_jsonapi[:relationships] } + + context 'and the clause is false' do + let(:conditional) { false } + + it { is_expected.to be_nil } + end + end + + context 'when a field and a link have the same name and keys are formatted' do + before do + klass.class_eval do + extend JSONAPI::Serializable::Resource::KeyFormat + key_format -> (k) { k.to_s.upcase } + extend JSONAPI::Serializable::Resource::ConditionalFields + + attribute :name, if: proc { @conditional } do + 'attribute' + end + + link :name, unless: proc { @conditional } do + 'link' + end + end + end + + let(:conditional) { true } + subject { resource.as_jsonapi } + + it "doesn't override previously registered condition" do + expect(subject[:attributes]).to eq(NAME: 'attribute') + expect(subject).not_to have_key(:links) + end + end +end From efebfb76b6def20991de8b28a89a059581feb00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82?= <720354+jembezmamy@users.noreply.github.com> Date: Fri, 22 Jul 2022 15:31:51 +0200 Subject: [PATCH 2/2] fixed conditional fields with key format --- .../serializable/resource/conditional_fields.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/jsonapi/serializable/resource/conditional_fields.rb b/lib/jsonapi/serializable/resource/conditional_fields.rb index a0b9e8c..de79b71 100644 --- a/lib/jsonapi/serializable/resource/conditional_fields.rb +++ b/lib/jsonapi/serializable/resource/conditional_fields.rb @@ -46,6 +46,7 @@ def inherited(klass) # def attribute(name, options = {}, &block) super + name = _format_key_for_condition(name) _register_condition(field_condition_blocks, name, options) end @@ -57,6 +58,7 @@ def attribute(name, options = {}, &block) # def relationship(name, options = {}, &block) super + name = _format_key_for_condition(name) _register_condition(field_condition_blocks, name, options) end @@ -87,6 +89,15 @@ def _register_condition(condition_blocks, name, options) proc { !instance_exec(&options[:unless]) } end end + + def _format_key_for_condition(name) + ancestors = self.singleton_class.included_modules + if ancestors.include?(KeyFormat) && ancestors.index(KeyFormat) > ancestors.index(ConditionalFields) + _key_formatter.call(name) + else + name + end + end end module InstanceMethods