diff --git a/.rubocop.yml b/.rubocop.yml index 839868764..ed8d7cc06 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -269,9 +269,12 @@ Layout/LineLength: - 'packages/forest_admin_agent/lib/forest_admin_agent/http/forest_admin_api_requester.rb' - 'packages/forest_admin_agent/lib/forest_admin_agent/routes/resources/list.rb' - 'packages/forest_admin_agent/lib/forest_admin_agent/services/permissions.rb' + - 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/create_override_customization_context.rb' + - 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/update_override_customization_context.rb' + - 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/delete_override_customization_context.rb' + - 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/publication/publication_datasource_decorator.rb' - 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/relation/relation_collection_decorator.rb' - 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/sort/sort_collection_decorator.rb' - - 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/publication/publication_datasource_decorator.rb' - 'packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/components/query/condition_tree/condition_tree_factory.rb' - 'packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/utils/collection.rb' - 'packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/components/query/filter_factory.rb' diff --git a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/collection_customizer.rb b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/collection_customizer.rb index 8fd87896d..5132d3271 100644 --- a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/collection_customizer.rb +++ b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/collection_customizer.rb @@ -285,6 +285,18 @@ def replace_field_binary_mode(name, binary_mode) push_customization { @stack.binary.get_collection(@name).set_binary_mode(name, binary_mode) } end + def override_create(&handler) + push_customization { @stack.override.get_collection(@name).add_create_handler(handler) } + end + + def override_update(&handler) + push_customization { @stack.override.get_collection(@name).add_update_handler(handler) } + end + + def override_delete(&handler) + push_customization { @stack.override.get_collection(@name).add_delete_handler(handler) } + end + private def push_customization(&customization) diff --git a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/decorators_stack.rb b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/decorators_stack.rb index 6415d7be1..1f6b4c213 100644 --- a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/decorators_stack.rb +++ b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/decorators_stack.rb @@ -5,12 +5,13 @@ class DecoratorsStack attr_reader :datasource, :schema, :search, :early_computed, :late_computed, :action, :relation, :late_op_emulate, :early_op_emulate, :validation, :sort, :rename_field, :publication, :write, :chart, :hook, :segment, - :binary + :binary, :override def initialize(datasource) @customizations = [] last = datasource + last = @override = DatasourceDecorator.new(last, Override::OverrideCollectionDecorator) last = DatasourceDecorator.new(last, Empty::EmptyCollectionDecorator) last = DatasourceDecorator.new(last, OperatorsEquivalence::OperatorsEquivalenceCollectionDecorator) diff --git a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/create_override_customization_context.rb b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/create_override_customization_context.rb new file mode 100644 index 000000000..ab9c28d54 --- /dev/null +++ b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/create_override_customization_context.rb @@ -0,0 +1,16 @@ +module ForestAdminDatasourceCustomizer + module Decorators + module Override + module Context + class CreateOverrideCustomizationContext < ForestAdminDatasourceCustomizer::Context::CollectionCustomizationContext + attr_reader :data + + def initialize(collection, caller, data) + super(collection, caller) + @data = data + end + end + end + end + end +end diff --git a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/delete_override_customization_context.rb b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/delete_override_customization_context.rb new file mode 100644 index 000000000..178d37644 --- /dev/null +++ b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/delete_override_customization_context.rb @@ -0,0 +1,16 @@ +module ForestAdminDatasourceCustomizer + module Decorators + module Override + module Context + class DeleteOverrideCustomizationContext < ForestAdminDatasourceCustomizer::Context::CollectionCustomizationContext + attr_reader :filter + + def initialize(collection, caller, filter) + super(collection, caller) + @filter = filter + end + end + end + end + end +end diff --git a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/update_override_customization_context.rb b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/update_override_customization_context.rb new file mode 100644 index 000000000..69257fb5c --- /dev/null +++ b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/context/update_override_customization_context.rb @@ -0,0 +1,17 @@ +module ForestAdminDatasourceCustomizer + module Decorators + module Override + module Context + class UpdateOverrideCustomizationContext < ForestAdminDatasourceCustomizer::Context::CollectionCustomizationContext + attr_reader :filter, :patch + + def initialize(collection, caller, filter, patch) + super(collection, caller) + @filter = filter + @patch = patch + end + end + end + end + end +end diff --git a/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/override_collection_decorator.rb b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/override_collection_decorator.rb new file mode 100644 index 000000000..ae784635f --- /dev/null +++ b/packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/override/override_collection_decorator.rb @@ -0,0 +1,49 @@ +module ForestAdminDatasourceCustomizer + module Decorators + module Override + class OverrideCollectionDecorator < ForestAdminDatasourceToolkit::Decorators::CollectionDecorator + include Context + attr_reader :create_handler, :update_handler, :delete_handler + + def create(caller, data) + if @create_handler + context = CreateOverrideCustomizationContext.new(@child_collection, caller, data) + return @create_handler.call(context) + end + + super + end + + def add_create_handler(handler) + @create_handler = handler + end + + def update(caller, filter, patch) + if @update_handler + context = UpdateOverrideCustomizationContext.new(@child_collection, caller, filter, patch) + return @update_handler.call(context) + end + + super + end + + def add_update_handler(handler) + @update_handler = handler + end + + def delete(caller, filter) + if @delete_handler + context = DeleteOverrideCustomizationContext.new(@child_collection, caller, filter) + return @delete_handler.call(context) + end + + super + end + + def add_delete_handler(handler) + @delete_handler = handler + end + end + end + end +end diff --git a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/collection_customizer_spec.rb b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/collection_customizer_spec.rb index 560386ca0..249356228 100644 --- a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/collection_customizer_spec.rb +++ b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/collection_customizer_spec.rb @@ -532,5 +532,50 @@ module ForestAdminDatasourceCustomizer expect(@datasource_customizer.stack.binary.get_collection('book')).to have_received(:set_binary_mode) end end + + context 'when using override_create' do + it 'adds the handler to the stack' do + stack = @datasource_customizer.stack + stack.apply_queued_customizations({}) + allow(stack.override).to receive(:get_collection).with('book').and_return(@datasource_customizer.stack.override.get_collection('book')) + + customizer = described_class.new(@datasource_customizer, @datasource_customizer.stack, 'book') + handler = proc { [] } + customizer.override_create(&handler) + stack.apply_queued_customizations({}) + + expect(@datasource_customizer.stack.override.get_collection('book').create_handler).to eq(handler) + end + end + + context 'when using override_update' do + it 'adds the handler to the stack' do + stack = @datasource_customizer.stack + stack.apply_queued_customizations({}) + allow(stack.override).to receive(:get_collection).with('book').and_return(@datasource_customizer.stack.override.get_collection('book')) + + customizer = described_class.new(@datasource_customizer, @datasource_customizer.stack, 'book') + handler = proc { [] } + customizer.override_update(&handler) + stack.apply_queued_customizations({}) + + expect(@datasource_customizer.stack.override.get_collection('book').update_handler).to eq(handler) + end + end + + context 'when using override_delete' do + it 'adds the handler to the stack' do + stack = @datasource_customizer.stack + stack.apply_queued_customizations({}) + allow(stack.override).to receive(:get_collection).with('book').and_return(@datasource_customizer.stack.override.get_collection('book')) + + customizer = described_class.new(@datasource_customizer, @datasource_customizer.stack, 'book') + handler = proc { [] } + customizer.override_delete(&handler) + stack.apply_queued_customizations({}) + + expect(@datasource_customizer.stack.override.get_collection('book').delete_handler).to eq(handler) + end + end end end diff --git a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/decorators/hook/hook_collection_decorator_spec.rb b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/decorators/hook/hook_collection_decorator_spec.rb index f00a630f2..c7c37221b 100644 --- a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/decorators/hook/hook_collection_decorator_spec.rb +++ b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/decorators/hook/hook_collection_decorator_spec.rb @@ -13,7 +13,6 @@ module Hook subject(:hook_collection_decorator) { described_class } let(:caller) { instance_double(ForestAdminDatasourceToolkit::Components::Caller) } - let(:category) { @datasource_decorator.get_collection('category') } let(:aggregation) { instance_double(ForestAdminDatasourceToolkit::Components::Query::Aggregation) } before do diff --git a/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/decorators/override/override_collection_decorator_spec.rb b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/decorators/override/override_collection_decorator_spec.rb new file mode 100644 index 000000000..b5013925c --- /dev/null +++ b/packages/forest_admin_datasource_customizer/spec/lib/forest_admin_datasource_customizer/decorators/override/override_collection_decorator_spec.rb @@ -0,0 +1,117 @@ +require 'spec_helper' + +module ForestAdminDatasourceCustomizer + module Decorators + module Override + include ForestAdminDatasourceToolkit + include ForestAdminDatasourceToolkit::Components::Query + include ForestAdminDatasourceToolkit::Decorators + + describe OverrideCollectionDecorator do + subject(:override_collection_decorator) { described_class } + + let(:caller) { instance_double(ForestAdminDatasourceToolkit::Components::Caller) } + + before do + datasource = Datasource.new + @transaction = collection_build( + name: 'transaction', + schema: { + fields: { + 'id' => numeric_primary_key_build, + 'description' => column_build, + 'amount_in_euro' => column_build + } + }, + list: [], + create: {}, + update: nil, + delete: nil, + aggregate: [] + ) + datasource.add_collection(@transaction) + @decorated_datasource = DatasourceDecorator.new(datasource, override_collection_decorator) + @decorated_transaction = @decorated_datasource.get_collection('transaction') + end + + it 'schema should not be changed' do + expect(@decorated_transaction.schema).to eq(@transaction.schema) + end + + context 'when no handler are set' do + context 'when create' do + it 'calls the original collection behavior' do + allow(@decorated_transaction).to receive(:create).and_return(nil) + @decorated_transaction.create(caller, []) + + expect(@decorated_transaction).to have_received(:create) + end + end + + context 'when update' do + it 'calls the original collection behavior' do + allow(@decorated_transaction).to receive(:update).and_return(nil) + @decorated_transaction.update(caller, Filter.new, []) + + expect(@decorated_transaction).to have_received(:update) + end + end + + context 'when delete' do + it 'calls the original collection behavior' do + allow(@decorated_transaction).to receive(:delete).and_return(nil) + @decorated_transaction.delete(caller, Filter.new) + + expect(@decorated_transaction).to have_received(:delete) + end + end + end + + context 'when setting up override' do + context 'when create' do + it 'calls the handler' do + handler = instance_double(Proc, call: nil) + + @decorated_transaction.add_create_handler(handler) + @decorated_transaction.create(caller, []) + + expect(handler).to have_received(:call).once do |context| + expect(context.caller).to eq(caller) + expect(context.data).to eq([]) + end + end + end + + context 'when update' do + it 'calls the handler' do + handler = instance_double(Proc, call: nil) + + @decorated_transaction.add_update_handler(handler) + @decorated_transaction.update(caller, Filter.new, []) + + expect(handler).to have_received(:call).once do |context| + expect(context.caller).to eq(caller) + expect(context.filter).to be_a(Filter) + expect(context.patch).to eq([]) + end + end + end + + context 'when delete' do + it 'calls the handler' do + handler = instance_double(Proc, call: nil) + + @decorated_transaction.add_delete_handler(handler) + @decorated_transaction.delete(caller, Filter.new) + + expect(handler).to have_received(:call).once do |context| + expect(context.caller).to eq(caller) + expect(context.filter).to be_a(Filter) + end + end + end + end + end + end + end +end