Skip to content

Commit 0b9e400

Browse files
committed
Add tests to make sure nested after_rollback blocks are called in the proper time
1 parent b7228b8 commit 0b9e400

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

spec/plugins/sequel_models_spec.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,75 @@ class InvalidAfterRollbackOperation < MyOperation
764764
.with_message('must provide either a step or a block but not both')
765765
end
766766
end
767+
768+
context 'when nesting operations with rollback callbacks' do
769+
class InnerFailingOperation < MyOperation
770+
context :notifier
771+
772+
process do
773+
transaction do
774+
after_rollback :notify_inner_rollback
775+
step :fail_step
776+
end
777+
step :after_transaction_step
778+
end
779+
780+
def fail_step(state)
781+
@notifier.inner_fail_step
782+
error(:inner_operation_failed)
783+
end
784+
785+
def notify_inner_rollback(state)= @notifier.inner_rollback
786+
def after_transaction_step(state)= @notifier.inner_after_transaction
787+
end
788+
789+
class OuterOperationWithRollback < MyOperation
790+
context :notifier
791+
792+
process do
793+
transaction do
794+
after_rollback :notify_outer_rollback
795+
step :call_inner_operation
796+
step :after_inner_call_step
797+
step :fail_again
798+
end
799+
step :final_step
800+
end
801+
802+
def call_inner_operation(state)
803+
state[:inner_result] = InnerFailingOperation.call({ notifier: @notifier }, state[:input])
804+
state
805+
end
806+
807+
def fail_again(state)
808+
@notifier.outter_fail_step
809+
810+
error(:outter_operation_failed) if state[:inner_result].failure?
811+
end
812+
813+
def notify_outer_rollback(state)= @notifier.outer_rollback
814+
def after_inner_call_step(state)= @notifier.after_inner_call_step
815+
def final_step(state)= @notifier.final_step
816+
end
817+
818+
let(:notifier) { spy }
819+
let(:operation) { OuterOperationWithRollback.new(notifier: notifier) }
820+
821+
it 'executes rollback callbacks in the correct order when inner operation fails' do
822+
expect(notifier).to receive(:inner_fail_step)
823+
expect(notifier).to receive(:inner_rollback)
824+
expect(notifier).to receive(:after_inner_call_step)
825+
expect(notifier).to receive(:outter_fail_step)
826+
expect(notifier).to receive(:outer_rollback)
827+
828+
# Verify calls that should NOT happen
829+
expect(notifier).to_not receive(:inner_after_transaction)
830+
expect(notifier).to_not receive(:final_step)
831+
832+
expect(operation).to fail_on(zzz: :XXXXXXXXXXXXX)
833+
.with_type(:outter_operation_failed)
834+
end
835+
end
767836
end
768837
end
769838

0 commit comments

Comments
 (0)