8vius
8vius

Reputation: 5836

Hartl Rails tutorial tests failing at the end of section 9.2.3

In this section I'm supposed to restrict the user to edit and update only his own profile. All my tests pass up to this point, except for this one:

     describe "as wrong user" do
       let(:user) { FactoryGirl.create(:user) }
       let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") }
       before { sign_in user }

       describe "visiting Users#edit page" do
         before { visit edit_user_path(wrong_user) }
         it { should_not have_selector('title', text: full_title('Edit user')) }
       end

       describe "submitting a PUT request to the Users#update action" do
         before { put user_path(wrong_user) }
         specify { response.should redirect_to(root_path) }
       end
     end

Specifically the last part, the redirection, this is what I get when I run the test:

  1) Authentication authorization as wrong user submitting a PUT request to the Users#update action 
     Failure/Error: specify { response.should redirect_to(root_path) }
       Expected response to be a redirect to <http://www.example.com/> but was a redirect to <http://www.example.com/signin>
     # ./spec/requests/authentication_spec.rb:86:in `block (5 levels) in <top (required)>'

But in the website, when I attempt to do this same thing it works just fine, the user is redirected to the root_path of the application.

Upvotes: 0

Views: 692

Answers (2)

Paul Fioravanti
Paul Fioravanti

Reputation: 16793

I checked out your code from your Github repo, and it seems that your modifications to app/helpers/sessions_helper.rb are responsible for your failing tests. Compare your file to the tutorial's file. You are using a session hash instead of a cookies hash in your methods. I fixed your "submitting a PUT request to the Users#update action" and "submitting a DELETE request to the Users#destroy action" errors by changing the code thus:

app/helpers/sessions_helper.rb

module SessionsHelper
  # ...

  def sign_in(user)
    # session[:remember_token] = user.remember_token
    cookies.permanent[:remember_token] = user.remember_token
    self.current_user = user
  end

  def sign_out
    self.current_user = nil
    # session.delete(:remember_token)
    cookies.delete(:remember_token)
  end

  def current_user
    # @current_user ||= User.find_by_remember_token(session[:remember_token])
    @current_user ||= User.find_by_remember_token(cookies[:remember_token])
  end

  # ...
end

There was an exercise in Rails 3.0 version of The Rails Tutorial where you replaced the cookies hash completely with a session hash, but I recall never being able to do it properly, and it doesn't seem to be in the 3.2 version anyway, so it would seem that you're safest sticking with a cookies hash in this file.

Upvotes: 2

utwang
utwang

Reputation: 1484

Is this code in Listing 9.6 written in your code?

# Sign in when not using Capybara as well.
cookies[:remember_token] = user.remember_token
  1. Capybara behaves like a browser, so it can receive some cookies from rails app.

  2. Capybara can test app like operating a browser using 'fill_in' and 'visit'.

  3. To issue "PUT /users/1" request in Capybara, it needs to go "/users/1/edit", then click "edit" link. But your rails app doesn't allow user to access other user, which is passed in previous test example.

  4. We can't issue "PUT /users/1" directly in Capybara. Instead, we need to use "put". Rspec can't receive any cookies from app. So we need to set cookies as Listing 9.6.

  5. If test example issues "PUT /users/1" request without remember_token in cookies, it will be redirected to sign in page as a non-signed in user. But this test intends that it is redirected to root page as signed in user send a put request to other user's resource directly.

Upvotes: 1

Related Questions