Reputation: 5836
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
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
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
Capybara behaves like a browser, so it can receive some cookies from rails app.
Capybara can test app like operating a browser using 'fill_in' and 'visit'.
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.
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.
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