Сбой тестов учебника Hartl Rails в конце раздела 9.2.3

В этом разделе я должен ограничить пользователь может редактировать и обновлять только свой профиль. Все мои тесты проходят до этого момента, кроме этого:

     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

В частности, последняя часть, перенаправление, это то, что я получаю, когда запускаю тест:

  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)>'

Но на веб-сайте, когда я пытаюсь сделать то же самое, все работает нормально, пользователь перенаправляется на root_path приложения.


person 8vius    schedule 21.08.2012    source источник
comment
Я не уверен, какое описание теста не работает. Метод тестирования sign_in определен? См. листинг 9.6. спецификация/support/utilities.rb   -  person utwang    schedule 22.08.2012
comment
Я собирался закрыть этот вопрос, но не смог, потому что закрыл другие, проблема заключалась в том, что, поместив частные методы перед остальными моими методами в моем пользовательском контроллере, я приватизировал все методы.   -  person 8vius    schedule 22.08.2012
comment
Я решил изменить свой вопрос, так как столкнулся с другой загвоздкой, и я не могу найти проблему.   -  person 8vius    schedule 22.08.2012


Ответы (2)


Я проверил ваш код в вашем репозитории Github, и кажется, что ваши изменения в app/helpers /sessions_helper.rb несут ответственность за ваши неудачные тесты. Сравните ваш файл с файл руководства. Вы используете хэш session вместо хэша cookies в своих методах. Я исправил ваши ошибки "submitting a PUT request to the Users#update action" и "submitting a DELETE request to the Users#destroy action", изменив код следующим образом:

приложение/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

В версии Rails Tutorial для Rails 3.0 было упражнение, где вы полностью заменили хэш cookies на хэш session, но я помню, что никогда не мог сделать это должным образом, и это похоже, его нет в версии 3.2 в любом случае, поэтому кажется, что безопаснее использовать хэш cookies в этом файле .

person Paul Fioravanti    schedule 27.08.2012
comment
На самом деле это упоминается в упражнениях главы 8 в Rails Cast, а затем он переключается на использование в разделе 10, поэтому я просто переключился на него. Это исправило это, спасибо, что нашли время, чтобы сделать это. И еще, раз уж мы в теме, что лучше? Используя файлы cookie или переменную сеанса? - person 8vius; 27.08.2012
comment
Это то, что мне тоже пришлось изучить, но, похоже, основное отличие состоит в том, что данные сеанса хранятся на сервере, а файлы cookie хранятся на клиенте (браузере) и что вы должны использовать файлы cookie для хранения значений на стороне клиента, которые вы хотите запомнить между сеансами. Таким образом, для целей запоминающегося токена хэш cookies кажется наиболее подходящим. - person Paul Fioravanti; 27.08.2012
comment
Тогда возникает проблема, что вы можете изменить файлы cookie, поэтому для защиты пользователя было бы лучше сохранить их в сеансе, не так ли? - person 8vius; 27.08.2012
comment
Хороший вопрос... к сожалению, я не могу высказать свое мнение, кроме того, что я прочитал в другом месте (например, содержание в ссылках выше). Вы можете опросить экспертов по StackOverflow, задав этот вопрос как отдельный вопрос, если вы не можете найти ответ в другом месте. - person Paul Fioravanti; 27.08.2012

Этот код в листинге 9.6 написан в вашем коде?

# Sign in when not using Capybara as well.
cookies[:remember_token] = user.remember_token
  1. Capybara ведет себя как браузер, поэтому он может получать некоторые файлы cookie из приложения rails.

  2. Capybara может тестировать приложение так же, как работу в браузере, с помощью «fill_in» и «visit».

  3. Чтобы выполнить запрос «PUT /users/1» в Capybara, нужно перейти «/users/1/edit», а затем нажать ссылку «edit». Но ваше приложение rails не позволяет пользователю получить доступ к другому пользователю, который передается в предыдущем тестовом примере.

  4. Мы не можем ввести «PUT /users/1» непосредственно в Capybara. Вместо этого нам нужно использовать «пут». Rspec не может получать файлы cookie от приложения. Итак, нам нужно установить файлы cookie, как показано в листинге 9.6.

  5. Если тестовый пример выдает запрос «PUT /users/1» без Remember_token в файлах cookie, он будет перенаправлен на страницу входа в качестве пользователя, не вошедшего в систему. Но этот тест предполагает, что он перенаправляется на корневую страницу, поскольку авторизованный пользователь отправляет запрос на размещение напрямую на ресурс другого пользователя.

person utwang    schedule 22.08.2012
comment
Да, это включено в мой код, тест на DELETE не проходит точно так же. - person 8vius; 23.08.2012