Как установить HTTP_REFERER при тестировании в Rails?

88

Я пытаюсь протестировать контроллер и получаю эту ошибку. Я понимаю ошибку, но не знаю, как ее исправить.

test: on CREATE to :user with completely invalid email should respond with 
  redirect
(UsersControllerTest):ActionController::RedirectBackError: 
  No HTTP_REFERER was set in the request to this action, 
  so redirect_to :back could not be called successfully. 
If this is a test, make sure to specify request.env["HTTP_REFERER"].

Укажите это где? Я пробовал это:

setup { post :create, { :user => { :email => 'invalid@abc' } }, 
  { 'referer' => '/sessions/new' } }

Но получил ту же ошибку.

Уточняйте с чем именно? Я предполагаю, что URI представления, к которому я хочу вернуться:

'/sessions/new'

Это то, что они имеют в виду?


Хорошо, оказывается, они имеют в виду сделать это:

setup do
  @request.env['HTTP_REFERER'] = 'http://localhost:3000/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }, {}
end

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

Что делать, если домен не «localhost: 3000»? Что, если это "localhost: 3001" или что-то в этом роде? Можно ли это предвидеть?

Почему это не работает:

setup { post :create, { :user => { :email => 'invalid@abc' } }, 
  { 'referer' => '/sessions/new' } }

В документации Rails конкретно сказано , как вы устанавливаете заголовки.

Итан
источник

Ответы:

92

Их рекомендация означает следующее:

setup do
  @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }
end
Джеймс А. Розен
источник
1
вы можете просто указать относительный путь, как в '/ sessions / new'.
Мартин Фаартофт,
У меня это не работает, потому что я использую https => 'on'. Что делать сейчас?
Роберт Рейз
48

Принятый ответ не работает для интеграционных тестов, потому что @requestпеременная не существует.

Согласно RailsGuides , вы можете передавать заголовки помощникам.

Рельсы <= 4:

test "blah" do
  get root_path, {}, {'HTTP_REFERER' => 'http://foo.com'}
  ...
end

Рельсы> = 5:

test "blah" do
  get root_path, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://foo.com" }
  ...
end
Фотиос
источник
2
Огромное спасибо. Я искал решение 1 час. Ваш пост у меня работает!
Роберт Рейз
9
В Rails 5 заголовки задаются следующим образом: get :show, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://example.com/home" } source
golfadas
9

В ответ на вопрос:

Почему это не работает:

setup { post :create, { :user => { :email => 'invalid@abc' } }, 
{ 'referer' => '/sessions/new' } }

Это не работает, потому что документ Rails, который вы связали с документами, отличается от того, который вы, вероятно, используете.

Вы связались с ActionController::Integration:Session. Я предполагаю, что вы пишете функциональный тест (если вы используете Test :: Unit) или тест контроллера (если вы используете Rspec). В любом случае, вы, вероятно, используете его ActionController::TestCaseили его подкласс. Которая, в свою очередь, включает модуль ActionController::TestProcess.

ActionController::TestProcessпредоставляет getметод с параметрами, отличными от getметода, предоставленного ActionController::Integration:Session. (Раздражает, а?) Сигнатура метода такова:

 def get(action, parameters = nil, session = nil, flash = nil)

К сожалению, параметра заголовков нет. Но хоть настройка @request.env['HTTP_REFERER']работает.

rlkw1024
источник
1

В Rails3 я получил ту же ошибку:
чтобы избавиться от этого, в соответствующем контроллере предусмотрено спасение для "redirect_to: back".

Пример:redirect_to :back rescue redirect_to required_path

румянец
источник
0
setup do
  @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }
end

В Rails 2.2.2 указанный выше блок никогда не выполнял фактических тестов. Говоря это

post: create, {: user => {: email => 'invalid @ abc'}}

линия не запускалась. Вы можете просто избавиться от блока настройки и использовать

@request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
post :create, { :user => { :email => 'invalid@abc' } }

вместо. И он должен установить реферер


источник
0

Наиболее простое решение вышеуказанной проблемы - сделать запрос с соответствующими заголовками. Rails автоматически прочитает этот заголовок.

post '/your-custom-route', {}, {'HTTP_REFERER': 'http://www.your-allowed-domain.com'}
Нерв
источник
0

В настоящее время я использую Rails 5.2.1, мой подход к рефереру запросов заглушек внутри контроллера выглядит следующим образом:

let(:stub_referer) { some_path(some_param) }
before do
  request.headers.merge! referer: stub_referer
  get :some_action, format: :html
end
Агунг Прасетьо
источник