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.

The projects API<br />

file at spec/api/v1/authentication_spec.rb, which will be filled with the content from<br />

the following listing.<br />

require "spec_helper"<br />

describe "API errors", :type => :api do<br />

end<br />

Listing 13.5 spec/api/v1/authentication_spec.rb<br />

it "making a request with no token" do<br />

get "/api/v1/projects.json", :token => ""<br />

error = { :error => "Token is invalid." }<br />

last_response.body.should eql(error.to_json)<br />

end<br />

You’re using Rack::Test::Methods in the spec again, and you’ve set up the token to<br />

be a blank string so get will pass this through as the token. Let’s run this spec to make<br />

sure it’s failing first with bin/rspec spec/api/v1/authentication_spec.rb:<br />

Failures:<br />

1) API errors making a request with no token<br />

Failure/Error: get "/api/v1/projects.json", :token => ""<br />

NoMethodError:<br />

undefined method `admin?' for nil:NilClass<br />

# ./app/models/project.rb:13:in `for'<br />

# ./app/controllers/api/v1/projects_controller.rb:3:in `index'<br />

# ./spec/api/v1/<br />

authentication_spec.rb:6:in `block (2 levels) in '<br />

1 example, 1 failure<br />

Yup, definitely looks like it’s failing. Line 13 of app/models/project.rb attempts to call<br />

admin? on the User object passed in to the for method. If you attempt to make a<br />

request without a valid token, the call to User.find_by_authentication_token will<br />

return nil, resulting in the error you see here. You should check if the user has been<br />

found, and if not then you’ll show the error. To make your authenticate_user<br />

method do this in app/controllers/api/v1/base_controller.rb, you’ll change it to what<br />

is shown in the following listing.<br />

Listing 13.6 app/controllers/api/v1/base_controller.rb<br />

def authenticate_user<br />

@current_user = User.find_by_authentication_token(params[:token])<br />

unless @current_user<br />

respond_with({:error => "Token is invalid." })<br />

end<br />

end<br />

If the @current_user variable is nil here, you set the response’s body to be the JSONform<br />

of { :error => "Token is invalid" } and respond_with that object. Does this<br />

work? Let’s find out with bin/rspec spec/api/v1/authentication_spec.rb:<br />

1 example, 0 failures<br />

357

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

Saved successfully!

Ooh no, something went wrong!