-
Notifications
You must be signed in to change notification settings - Fork 7
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
Bugs/aperta 12001 cancel passive events on rr submit #3820
Bugs/aperta 12001 cancel passive events on rr submit #3820
Conversation
601dd39
to
f59ab5d
Compare
f59ab5d
to
97ec21b
Compare
client/app/models/scheduled-event.js
Outdated
@@ -18,8 +18,9 @@ export default DS.Model.extend({ | |||
|
|||
updateState: function(newState) { | |||
const url = `/api/scheduled_events/${this.get('id')}/update_state`; | |||
return this.get('restless').put(url, {state: newState}).then(() => { | |||
this.set('state', newState); | |||
return this.get('restless').put(url, {state: newState}).then((data) => { |
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.
the UI wasn't refreshing because the object was dirty and not reloading.
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.
Just a drive-by comment/question. I could not tell from the ember code: does pushing the payload update the state? If not, is the this.set still needed?
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.
indeed this.store.pushPayload
will update this ember object's state, hence I removed the this.set('state', newState);
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.
What you did seems like an improvement to me, but I get the willies from this type of un-restful stuff in ember. Every call to 'restless' seems like tech debt to me, especially since the semantics are almost identical to a model update. Something like this would make me feel a lot better:
updateState(newState) {
this.set('state', 'newState'})
return this.save();
}
which is trivial to the point of being unnecessary (hence an indication that we're actually using ember data properly.
I wont insist that you change it, but just wanted to express my reservations about the pattern.
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.
agreed, I'm not sure why the scheduled_events_controller.rb
was setup that way... I'd be down to refactor that in an empowerment ticket.
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.
Just a note that my question about whether the state was updated would have been unnecessary with this implementation.
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.
okay, i've fixed this, gonna push.
@@ -170,6 +170,6 @@ def thank_reviewer | |||
end | |||
|
|||
def cancel_reminders | |||
scheduled_events.active.map(&:cancel!) | |||
scheduled_events.cancelable.each(&:cancel!) |
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.
props on spelling cancelable correctly. I definitely did not.
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.
machty/ember-concurrency#41 my fav
spec/models/reviewer_report_spec.rb
Outdated
subject.scheduled_events.first.switch_off! # passive state | ||
subject.scheduled_events.last.cancel! # cancel state | ||
cancelable = subject.scheduled_events.select(&:may_cancel?) # omg it compares object ids and not row id. | ||
allow(subject.scheduled_events).to receive(:cancelable).and_return(cancelable) |
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.
What's the motivation behind stubbing this instead of using the real scope? If it's so you can test the scope in a non-tautological way it's probably worth breaking out a separate test for the scope.
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.
@egh watched me struggle with this, basically when cancelable
gets called, it returns an array of objects that while containing the same active record objects, they have different ruby object ids, which screws with rspec. so this ensures they have the right object ids.
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.
ah yeah, I just talked to @egh. I understand now that this was necessary for the subsequent message expectations to be set up properly (otherwise they're set up on different objects than those used inside of cancel_reminders
).
However, if you ditch those expectations (my comment below), you can also ditch this stubbing and make the test a lot more clear.
spec/models/reviewer_report_spec.rb
Outdated
allow(subject.scheduled_events).to receive(:cancelable).and_return(cancelable) | ||
subject.scheduled_events.each do |event| | ||
count = event.canceled? ? 0 : 1 | ||
expect(event).to receive(:cancel!).exactly(count).times |
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.
WDYTA setting up expectations about the ending data state rather than setting up message expectations? I think a test that essentially said "all three scheduled events should be cancelled" rather than "some number of models should have the cancel!
messaged passed to them" is easier to follow, and more resilient to implementation changes.
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.
In my old age, I've started to shy away from test mocks and stubs unless there's a really good reason to use them (test speed, or an external service). I find that it's nice to get the extra coverage of integrations where you're able.
I'm going to paste this article without reading it: https://blog.kentcdodds.com/write-tests-not-too-many-mostly-integration-5e8c7fff591c hopefully it supports my point.
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.
diff --git a/spec/models/reviewer_report_spec.rb b/spec/models/reviewer_report_spec.rb
index ff46118346..79079bd9d0 100644
--- a/spec/models/reviewer_report_spec.rb
+++ b/spec/models/reviewer_report_spec.rb
@@ -173,13 +173,8 @@ describe ReviewerReport do
subject.set_due_datetime # makes 3 scheduled events with active state
subject.scheduled_events.first.switch_off! # passive state
subject.scheduled_events.last.cancel! # cancel state
- cancelable = subject.scheduled_events.select(&:may_cancel?) # omg it compares object ids and not row id.
- allow(subject.scheduled_events).to receive(:cancelable).and_return(cancelable)
- subject.scheduled_events.each do |event|
- count = event.canceled? ? 0 : 1
- expect(event).to receive(:cancel!).exactly(count).times
- end
subject.send(:cancel_reminders)
+ expect(subject.scheduled_events.all?(&:canceled?)).to be(true)
end
end
end
does that look good?
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.
love it. Thanks ben!
@@ -8,7 +8,8 @@ export default Ember.Component.extend({ | |||
actions: { | |||
changeEventState(newVal) { | |||
const state = newVal ? 'active' : 'passive'; | |||
this.get('event').updateState(state); | |||
this.set('event.state', state); | |||
this.get('event').save(); |
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.
yay, we're using ember now :)
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.
Great changes here. In particular, thanks for the changes to make updating scheduled_events more restful. 👍
4f95a60
to
518f0ea
Compare
518f0ea
to
0b33211
Compare
[60] pry(main)> ReviewerReport.joins(:due_datetime).where(state: ['submitted', 'invitation_not_accepted']).select { |x| x.scheduled_events.any?(&:may_cancel?) }.count
=> 1 So from my somewhat recent prod snapshot, there's only one outstanding reviewer report that would need migrating. If that's still the case, i'd just sweep it under the rug, it will go away once that decision is made (I think). |
|
||
before_save :deactivate, if: :should_deactivate? |
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 grepped pretty hard, I think this event is only used internally.
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 believe you
@benjaminkreen "on hold" or "merge when green"? :) |
its good from a PO stance, I just wanted to run my last commit by @slimeate |
@@ -38,12 +41,13 @@ def finished? | |||
state :errored | |||
state :passive | |||
state :canceled # Canceled automatically after a qualifying event, e.g., a review is submitted | |||
state :deactivated | |||
|
|||
event(:reactivate) do | |||
transitions from: [:completed, :inactive], to: :active |
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'll probably want to add the ability to reactivate disabled events. Ensure that we haven't reintroduced APERTA-11985.
Btw, check out my comment here: https://jira.plos.org/jira/browse/APERTA-11985?focusedCommentId=193071&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-193071 seems related to the issue you're dealing with now. Specifically, it may be possible to reactivate events to have the correct toggle state now that we have the new deactivated
state.
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.
Does this need addressing before we merge 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.
we chatted offline, its resolved :)
spec/models/reviewer_report_spec.rb
Outdated
subject.scheduled_events.first.switch_off! # passive state | ||
subject.scheduled_events.last.cancel! # cancel state | ||
subject.send(:cancel_reminders) | ||
expect(subject.scheduled_events.none?(&:may_cancel?)).to be(true) |
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.
might be good to be a bit more specific here--asserting the actual data states you expect, or asserting that the number of events which may_cancel?
changes before and after cancel_reminders
. It's possible that an error in the definition of may_cancel?
would cause this test to pass when it actually shouldn't. For instance, if none of the events may_cancel?
in the initial conditions, cancel_reminders
would essentially no-op and this assertion would still pass.
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.
diff --git a/spec/models/reviewer_report_spec.rb b/spec/models/reviewer_report_spec.rb
index d7f5a99e6b..2dc8747ab0 100644
--- a/spec/models/reviewer_report_spec.rb
+++ b/spec/models/reviewer_report_spec.rb
@@ -173,8 +173,9 @@ describe ReviewerReport do
subject.set_due_datetime # makes 3 scheduled events with active state
subject.scheduled_events.first.switch_off! # passive state
subject.scheduled_events.last.cancel! # cancel state
- subject.send(:cancel_reminders)
- expect(subject.scheduled_events.none?(&:may_cancel?)).to be(true)
+ old_states = subject.scheduled_events.map(&:state)
+ new_states = old_states.map { |x| x == 'passive' ? 'deactivated' : 'canceled' }
+ expect { subject.send(:cancel_reminders) }.to change { subject.scheduled_events.reload.map(&:state) }.from(old_states).to(new_states)
end
end
JIRA issue: https://jira.plos.org/jira/browse/APERTA-12001
What this PR does:
Submitting a reviewer report should cancel scheduled events in the passive state as well.
Special instructions for Review or PO:
See ticket for issue repro instructions.
Code Review Tasks:
Author tasks (delete tasks that don't apply to your PR, this list should be finished before code review):
Reviewer tasks (these should be checked or somehow noted before passing on to PO):