27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

284 CHAPTER 10 Tracking state<br />

it "cannot transition a state by passing through state_id" do<br />

post :create, { :comment => { :text => "Hacked!",<br />

:state_id => state.id },<br />

:ticket_id => ticket.id }<br />

ticket.reload<br />

B Reload Ticket object<br />

ticket.state.should eql(nil)<br />

end<br />

end<br />

This spec uses a before to sign in as the user before the example runs. Inside the<br />

example, you use the post method to make a POST request to the create action<br />

inside CommentsController, passing in the specified parameters. It’s this state_id<br />

parameter that should be ignored in the action.<br />

After the post method, you use a new method :reload B. When you call reload<br />

on an Active Record object, it will fetch the object again from the database and update<br />

the attributes for it. You use this because the create action acts on a different Ticket<br />

object and doesn’t touch the one you’ve set up for your spec.<br />

The final line here asserts that the ticket.state should be nil. When you run<br />

this spec by running bundle exec rspec spec/controllers/comments_controller<br />

_spec.rb, this final line will be the one to fail:<br />

Failure/Error: ticket.state.should eql(nil)<br />

expected nil<br />

got #<br />

The ticket.state is returning a state object because the user has been able to post<br />

it through the parameter hash. With a failing spec now in place, you can go about<br />

stopping this state parameter from going unchecked. To ignore this parameter, you<br />

can remove it from the params hash if the user doesn’t have permission to change<br />

states. At the top of the create action, inside of CommentsController, put the following<br />

lines:<br />

if cannot?(:"change states", @ticket.project)<br />

params[:comment].delete(:state_id)<br />

end<br />

This code will remove the state_id key from the params[:comment] hash if the user<br />

doesn’t have permission to change the states on the ticket’s project, thereby preventing<br />

them from being able to change the state. If you rerun your spec using bin/rspec spec<br />

/controllers/comments_controller_spec.rb, you’ll see that it passes:<br />

1 example, 0 failures<br />

Great! Now nobody without permission will be able to download the ticket page, make<br />

modifications to it to add a state field, and then be able to change the states.<br />

You’re done with this feature now so it’s time to make sure you didn’t break anything<br />

with your changes by running rake cucumber:ok spec. You should see that<br />

everything is squeaky clean:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!