Skip to content
This repository was archived by the owner on Jul 24, 2020. It is now read-only.

[1645] blackout conflict checking #1651

Merged
merged 1 commit into from
Feb 4, 2017
Merged

Conversation

yongjie-lin
Copy link
Contributor

No description provided.

Copy link
Collaborator

@esoterik esoterik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good overall! There's some refactoring to do; let me know if you have any questions.

@@ -93,10 +93,30 @@ def create # rubocop:disable MethodLength
end

def update
p = blackout_params
p[:created_by] = current_user.id
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be updating created_by -- we want the record of whoever originally created the blackout

.active

# save and exit
if res.empty? && @blackout.update_attributes(p)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little hesitant to do both of these at the same time -- I think we should only attempt to update the blackout if there aren't any conflicting reservations.

This is also a great opportunity to create a service object to handle blackout updating. PR #1624 has an example of a service object for reservation creation.

Essentially, this method should only get the params and pass them to the service object, which will handle the update process and return the appropriate messages (e.g. errors or the updated object)

@@ -143,7 +143,7 @@
it { is_expected.to render_template(:new) }
it 'should not save the blackout' do
expect { post :create, blackout: attributes }.not_to\
change { Blackout.all.count }
change { Blackout.all.count }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace error!

start_date: Time.zone.today)

it_behaves_like 'does not update blackout', attributes
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are pretty good, but they should probably be replaced with tests of the service object that you'll write. PR #1625 has examples of this.

else
if res.any?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this if block -- we want the detailed reservation info always.

@esoterik esoterik changed the title 1645 blackout conflict checking [1645] blackout conflict checking Nov 20, 2016
@esoterik esoterik self-assigned this Nov 22, 2016
@esoterik
Copy link
Collaborator

@yongjie-lin is this ready for re-review?

@yongjie-lin
Copy link
Contributor Author

yongjie-lin commented Jan 18, 2017 via email

Copy link
Collaborator

@esoterik esoterik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a just few small changes to be made! I know you had questions about test coverage, and I think it's fine, but I have to run right now so I will review that more thoroughly tonight.

update_p: blackout_params)
result = updater.update!

if result[:error]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you don't need to pull out these methods here (though I realize you were following my example, apologies!)

@@ -0,0 +1,37 @@
class BlackoutUpdater
# Service Object to update blackouts in the blackouts controller
def initialize(blackout:, update_p:)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update_p should be renamed to either params, new_attrs, or update_params, take your pick!

conflicts.each do |conflict|
message += "#{conflict.md_link}, "
end
return message[0, message.length - 2]\
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this array index necessary?

list_conflicts(conflicts)
end

def list_conflicts(conflicts)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to error_string

end
return message[0, message.length - 2]\
+ '. Please update their due dates and try again.'
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the processing of the conflicts should be pulled out to a separate method so that this method reads: "The following reservation(s) will be unable to be returned #{conflicts_string}. Please update their due dates and try again."

before { put :update, id: FactoryGirl.create(:blackout),
blackout: attributes }

it { is_expected.to set_flash }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should specify set_flash[:error]

it 'should not save the blackout' do
expect(attributes).not_to be_nil
expect(assigns(:blackout)).not_to be_nil
expect(assigns(:blackout)[:notice]).not_to eq(attributes[:notice])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be split up into separate tests / refactored to only have one expect

describe BlackoutUpdater do
describe 'update!' do
let!(:blackout) {instance_spy(Blackout, :update_attributes => nil)}
let!(:cf) {double("conflict", :md_link => "Test")}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not as DRY, but it's preferred to not use let! and just declare the variables you need inside your tests. This way, every individual test is readable and doesn't depend on things declared elsewhere.

:active).and_return([])
updater = BlackoutUpdater.new(blackout: blackout, update_p: {})
@results = updater.update!
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with this before block.

:active).and_return([cf])
updater = BlackoutUpdater.new(blackout: blackout, update_p: {})
@results = updater.update!
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this before too

@yongjie-lin
Copy link
Contributor Author

yongjie-lin commented Jan 21, 2017

I've made the requested changes, please review!

Edit: just realized I forgot to implement the conditional

@esoterik
Copy link
Collaborator

before I review, I just noticed that you have a merge commit in your branch -- you should revert it and rebase your branch on top of master instead (git rebase -i master)

Copy link
Collaborator

@esoterik esoterik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

almost there!

context 'with conflicting blackout' do
it 'does not update blackout' do
blackout = instance_spy(Blackout, update_attributes: nil)
cf = double('conflict', md_link: 'Test')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be either an instance_spy('Reservation') or a ReservationMock.new, not just a plain double

end
end
context 'with errors' do
context 'with conflicting blackout' do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be with a conflicting reservation, right?

results = updater.update!
expect(results[:error]).to eq('The following reservation(s) will be'\
' unable to be returned: Test. Please update their due dates and '\
'try again.')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of testing the whole string, test if it includes the reservation's md_link

@yongjie-lin yongjie-lin force-pushed the 1645_blackout_conflict_checking branch 2 times, most recently from 9f2161f to b67cf26 Compare January 29, 2017 00:30
@yongjie-lin
Copy link
Contributor Author

Ready for review!

Copy link
Collaborator

@esoterik esoterik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly small changes, but I found one bug in the error handling


def error
return 'Invalid blackout parameters. Please try again.' unless
@blackout.validate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't work -- this is checking that the blackout is valid before you try to update it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, this wasn't caught by any tests -- there should be a controller-level test that checks the response to attempting to update a blackout with invalid attributes

return 'Invalid blackout parameters. Please try again.' unless
@blackout.validate
conflicts
return unless @conflicts.any?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can get rid of the line above and just have return unless conflicts.any?


def update_handler
blackout.update_attributes(params)
{ result: 'Blackout was successfully updated.', error: nil }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in order to check for a successful update and return error messages if necessary, this should read

if blackout.update_attributes(params)
  return { success hash }
else
  return { result: nil, error: blackout.errors.full_messages }
end

it 'does not update blackout' do
blackout = instance_spy(Blackout, update_attributes: nil,
validate: true)
cf = instance_spy('conflict', md_link: 'Dummy conflict')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be instance_spy('Reservation', ...) not instance_spy('conflict', ...)

it 'does not return a result' do
blackout = instance_spy(Blackout, update_attributes: nil,
validate: true)
cf = instance_spy('conflict', md_link: 'Dummy conflict')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be instance_spy('Reservation', ...) not instance_spy('conflict', ...)

@yongjie-lin
Copy link
Contributor Author

Ready for review!

Copy link
Collaborator

@esoterik esoterik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a couple of tests to get rid of, then this is ready to squash and merge

it { is_expected.to render_template(:edit) }
it 'should have attributes' do
expect(attributes).not_to be_nil
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is unnecessary -- you're testing that the shared example wasn't given nil, which you have control over

end
it 'should have a blackout to update' do
expect(assigns(:blackout)).not_to be_nil
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also unnecessary

@yongjie-lin yongjie-lin force-pushed the 1645_blackout_conflict_checking branch from cbeb3fc to 07a3be5 Compare February 4, 2017 19:23
closes #1645
- change app/controllers/blackouts_controller.rb
- add lib/blackout_updater.rb
- change spec/controllers/blackouts_controller_spec.rb
- add spec/lib/blackout_updater_spec.rb
- add service object for updating blackouts
- add checking of conflicting reservation when updating blackouts
@yongjie-lin yongjie-lin force-pushed the 1645_blackout_conflict_checking branch from 07a3be5 to 93608aa Compare February 4, 2017 19:26
@esoterik esoterik merged commit ac2ade3 into master Feb 4, 2017
@esoterik
Copy link
Collaborator

esoterik commented Feb 4, 2017

@yongjie-lin don't forget to add this to the changelog (branch v630_changelog)

@esoterik esoterik deleted the 1645_blackout_conflict_checking branch February 4, 2017 20:57
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants