Rails - Проигрышный сеанс с интеграционными тестами и капибарой - CSRF связаны? - PullRequest
14 голосов
/ 07 июля 2011

Я использую Rails 3.1.0.rc4 и работаю над интеграционными тестами с новыми Steak-подобными DSL и Rspec от Capybara (с использованием аутентификации Devise)

У меня проблема в том, чтокогда я запускаю интеграционный тест, драйвер стоечного теста из капибары, похоже, просто полностью теряет пользователя, вошедшего в сеанс, фактически, сеанс, кажется, просто полностью очищается.

После нескольких дней отладки ям в полной растерянности относительно того, почему.Идя построчно через стек промежуточного программного обеспечения, я полагаю, что я решил проблему до того, что происходит в ActiveRecord::SessionStore, что вызывает это.Я прочитал здесь , что Rails очистит сессию, если не сможет проверить токен CSRF, что заставляет меня поверить, что я что-то настроил неправильно, и по какой-то причине этот тестнеправильно аутентифицирует токен CSRF.

Это то, что находится в моем файле session_store.rb в каталоге / initializers:

MyApp::Application.config.session_store :active_record_store

Есть ли у кого-нибудь, кто знает о защите CSRF в рельсах,почему это может происходить?

Также обратите внимание на некоторые вещи:

  • вещь, которую я пытаюсь протестировать, на самом деле работает в самом браузере, только один этот тест сбрасывает сессию
  • кажется, что сеанс прерывается после отправки формы, к которой URL-адрес действия относится к другому серверу.Я использую гем VCR для захвата запросов / ответов на этот внешний сервер в тесте, и хотя я считаю, что я управлял внешним запросом как проблемой, это может иметь непосредственное отношение к тому, что токен CSRF не аутентифицируется,таким образом очищая сеанс.
  • другие тесты, включающие вход в систему / использование сеансов, не отбрасывают сеансы

Может кто-нибудь дать мне какие-либо указания относительно того, что именно здесь происходит, и почемукажется, что один тест произвольно отбрасывает свою сессию и проваливается на мне?Я сделал много отладок и перепробовал все, что только мог придумать.

Ответы [ 4 ]

20 голосов
/ 26 июля 2011

Я тоже новичок в капибаре, и у меня была похожая проблема.

Я пытался войти в систему пользователя, делая что-то вроде этого:

post user_session_path, :user => {:email => user.email, :password => 'superpassword'}

И это работало нормальнопока я не попытался что-то сделать с капибарой, например, посетив страницу и просто проверив, вошел ли пользователь в систему. Этот простой тест не прошел:

visit root_path
page.should have_content("logout") #if the user is logged in then the logout link should be present

Сначала я думал, что капибара очищает сессии, ноЯ был неправ.Мне потребовалось некоторое время, чтобы осознать, что драйвер-капибара использует собственные сессии, поэтому с точки зрения капибары мой пользователь никогда не входил в систему. Для этого вам нужно сделать это следующим образом

page.driver.post user_session_path, :user => {:email => user.email, :password => 'superpassword'}

Не уверен, что это ваш случай, но надеюсь, что это поможет.

7 голосов
/ 10 декабря 2011

Ручной способ сделать это очень просто:

it "does something after login" do
  password = "secretpass"
  user = Factory(:user, :password => password)
  visit login_path
  fill_in "Email", :with => user.email
  fill_in "Password", :with => password
  click_button "Log in"
  visit # somewhere else and do something
end

Затем вы можете разбить это на функцию в вашем 'spec_helper.rb':

# at the bottom of 'spec_helper.rb'
def make_user_and_login
  password = "secretpass"
  @user = Factory(:user, :password => password)
  visit login_path
  fill_in "Email", :with => @user.email
  fill_in "Password", :with => password
  click_button "Log in"
end

и используйте его в любом из ваших тестов (возможно, запросите спецификации):

it "does something after login" do
  make_user_and_login
  # now test something that requires a logged in user
  # you have access to the @user instance variable
end
5 голосов
/ 16 апреля 2015

Мне удалось исправить эту ошибку, установив для этого значения значение true в config / initializer / test.rb

# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection = true

Ранее теги CSRF <meta> не распечатывались на <head>. После изменения этого значения они наконец появляются.

0 голосов
/ 04 апреля 2014

Это может быть далеко, но я считаю, что после click_button 'Sign in' мы в конечном итоге в плохом состоянии и сразу после этого вызываем visit elsewhere.

Моя теория такова, что когда мы нажимаем кнопку, запрос не 'еще не завершено, и мы уничтожаем его, посещая другой путь.

Из документации на Capybara:

При выдаче инструкций для DSL, таких как:

click_link('foo') click_link('bar') expect(page).to have_content('baz')

Если нажатие на ссылку foo запускает асинхронный процесс, такой как запрос Ajax, который, когда завершится, добавит ссылку на панель на страницу, ожидается, что нажатие на ссылку на панель будет неудачным, посколькуссылка еще не существует Однако Капибара достаточно умен, чтобы попытаться найти ссылку на короткий промежуток времени, прежде чем отказаться от и выдать ошибку.

В этом случае решение простое: датьКапибара что-то ищет и позволяет подождать, пока запрос не будет выполнен.Это может быть так просто, как добавление:

expect(page).to have_text('Signed in as bob@example.com')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...