Skip to content
This repository has been archived by the owner on Dec 29, 2024. It is now read-only.

Commit

Permalink
Fix dual call issue with interactors with deferred after_performs
Browse files Browse the repository at this point in the history
If an Interactor that has deferred after_performs is called from an Organizer and then...later...directly, the after_performs are skipped when calling directly.

This is due to how Organizers handle Interactors with deferred logic. In such a case, the Organizer modifies the Interactor's callback so that it is skipped. However, this does not account for cases where an Interactor is called both as part of an Organizer and on it's own. In this case, the Interactor believes it should skip handling the after_performs forever, and rely instead on the Organizer to call them at the appropriate time.

This change updates the logic so that the callback is only skipped if the organizer property is not present. This property is used to tell the Interactor that and by what it is being "organized".
  • Loading branch information
mjonas87 committed Mar 26, 2024
1 parent 3cf86f4 commit 1151baf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/active_interactor/organizer/interactor_interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def skip_deferred_after_perform_callbacks
return unless deferred_after_perform_callbacks.present?

deferred_after_perform_callbacks.each do |callback|
interactor_class.skip_callback(:perform, :after, callback.filter, raise: false)
interactor_class.skip_callback(:perform, :after, callback.filter, raise: false, if: -> { self.options.organizer.present? })
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

after_perform do
context.steps << 'after_perform_1a'
context.called_test_after_perform = true
end

after_perform do
Expand Down Expand Up @@ -57,6 +58,8 @@ def perform
organize TestInteractor1, TestInteractor2, TestInteractor3
end
end

let(:organizer) { interactor_class }

include_examples 'a class with interactor methods'
include_examples 'a class with interactor callback methods'
Expand Down Expand Up @@ -147,5 +150,31 @@ def perform
]
)}
end

context 'when interactor is called via organizer' do
context 'and interactor is called individually prior' do
it 'calls the after_perform callbacks in both cases' do
result = test_interactor_1.perform
expect(result).to be_success
expect(result.called_test_after_perform).to be(true)

result = organizer.perform
expect(result).to be_success
expect(result.called_test_after_perform).to be(true)
end
end

context 'and interactor is called individually after' do
it 'calls the after_perform callbacks in both cases' do
result = organizer.perform
expect(result).to be_success
expect(result.called_test_after_perform).to be(true)

result = test_interactor_1.perform
expect(result).to be_success
expect(result.called_test_after_perform).to be(true)
end
end
end
end
end

0 comments on commit 1151baf

Please sign in to comment.