-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DEV: Refactor DiscourseAutomation::DestroyAutomation
a bit
#29891
Conversation
@@ -0,0 +1,43 @@ | |||
# frozen_string_literal: true | |||
|
|||
class DiscourseAutomation::Destroy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the name to Destroy
instead of DestroyAutomation
as we already have the namespace indicating this is DiscourseAutomation
, it seemed redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I'm always mixed on this, to me a namespace, is a namespace and is not conveying which resource is going to be impacted... but Im fine with the change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s not necessarily a resource, the idea is more of using a namespace describing a business concept. But then, most of the model names are business concepts.
# @option params [Integer] :automation_id | ||
# @return [Service::Base::Context] | ||
|
||
policy :can_destroy_automation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the policy to be the first step, as it only relies on guardian
. So we can stop the execution flow even before validating any param or fetching any model.
# @return [Service::Base::Context] | ||
|
||
policy :can_destroy_automation | ||
params do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the steps are grouped together, I know you don’t like it for the ones having blocks, it’s not to annoy you, I swear 😅 I saw that originally you added blank lines around params
, but not around transaction
. One thing I’d like for us to do is defining a consistent rule on this. This way, we could create a rubocop rule that will apply this and possibly even autocorrect the format.
So it boils down to choosing between having something like:
policy :can_destroy_automation
params do
attribute :automation_id, :integer
validates :automation_id, presence: true
end
model :automation
transaction do
step :log_action
step :destroy_automation
end
versus
policy :can_destroy_automation
params do
attribute :automation_id, :integer
validates :automation_id, presence: true
end
model :automation
transaction do
step :log_action
step :destroy_automation
end
I prefer the first version, I think you prefer the second one, but my goal is to have consistency so, in the end, I won’t care that much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I very much prefer the second one, but feel free to make a quick poll in dev-xp channel, no need to ask everyone
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so the second one won 😅
def log_action(automation:, guardian:) | ||
StaffActionLogger.new(guardian.user).log_custom( | ||
"delete_automation", | ||
**automation.slice(:id, :name, :script, :trigger), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the parameter names are 1-to-1 with the model, we can simply use #slice
here.
describe described_class::Contract, type: :model do | ||
subject(:contract) { described_class.new } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not necessary, as the default subject
provided by RSpec is described_class.new
.
end | ||
|
||
it "destroys the automation" do | ||
expect { result }.to change { DiscourseAutomation::Automation.count }.by(-1) | ||
context "when data is invalid" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were missing a test to make sure the contract is properly called inside the service.
fab!(:user) { Fabricate(:user) } | ||
|
||
it { is_expected.to fail_a_policy(:can_destroy_automation) } | ||
context "when everything's ok" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a context for the happy path (as we usually do this), but I moved it after the failing examples. That’s something I can move back, no worries. Here also, I was wondering if we should decide on which order we should enforce. (happy path first then failing examples, or possible failing examples, then at the end you have the happy path).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 No strong opinions on this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, let’s roll with this then.
Small followup to 932bd6b.
3fd73b5
to
7f41235
Compare
Small followup to 932bd6b.