Jak ustawić HTTP_REFERER podczas testowania w Railsach?

88

Próbuję przetestować kontroler i mam ten błąd. Rozumiem błąd, ale nie wiem, jak go naprawić.

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"].

Określ to gdzie? Próbowałem tego:

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

Ale dostałem ten sam błąd.

Co dokładnie określisz? Domyślam się, że identyfikator URI widoku, do którego ma wrócić:

'/sessions/new'

Czy to mają na myśli?


OK, więc okazuje się, że mają na myśli:

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

Czy ktoś może mi powiedzieć, gdzie to jest udokumentowane? Chciałbym poczytać w kontekście tych informacji.

Co się stanie, jeśli domena nie jest „localhost: 3000”? A jeśli to „localhost: 3001” czy coś takiego? Można to przewidzieć?

Dlaczego to nie działa:

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

Dokumentacja Rails mówi, że właśnie tak ustawiasz nagłówki.

Ethan
źródło

Odpowiedzi:

91

Ich rekomendacja przekłada się na:

setup do
  @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }
end
James A. Rosen
źródło
1
możesz uciec, po prostu określając ścieżkę względną, jak w „/ session / new”.
Martin Faartoft
To nie działa, ponieważ używam https => „on”. Co zrobić teraz?
Robert Reiz
47

Zaakceptowana odpowiedź nie działa w przypadku testów integracyjnych, ponieważ @requestzmienna nie istnieje.

Według RailsGuides , możesz przekazywać pomocnikom nagłówki.

Szyny <= 4:

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

Szyny> = 5:

test "blah" do
  get root_path, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://foo.com" }
  ...
end
Fotios
źródło
2
Wielkie dzięki. Szukałem rozwiązania przez 1 godzinę. Twój post działa dla mnie!
Robert Reiz
9
Na Rails 5 nagłówki są określone w następujący sposób: get :show, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://example.com/home" } source
golfadas
9

W odpowiedzi na pytanie:

Dlaczego to nie działa:

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

To nie działa, ponieważ dokument Rails, który dowiązałeś do dokumentów innej klasy niż ta, której prawdopodobnie używasz.

Masz link do ActionController::Integration:Session. Zgaduję, że piszesz test funkcjonalny (jeśli używasz Test :: Unit) lub test kontrolera (jeśli używasz Rspec). Tak czy inaczej, prawdopodobnie używasz ActionController::TestCaselub jego podklasy. Który z kolei zawiera moduł ActionController::TestProcess.

ActionController::TestProcessudostępnia getmetodę o innych parametrach niż getmetoda udostępniana przez ActionController::Integration:Session. (Irytujące, co?) Podpis metody jest taki:

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

Niestety nie ma parametru nagłówków. Ale przynajmniej ustawienie @request.env['HTTP_REFERER']działa.

rlkw1024
źródło
1

W Rails3 otrzymałem ten sam błąd:
aby się tego pozbyć w odpowiednim kontrolerze dostarczono ratunek dla "redirect_to: back"

Przykład:redirect_to :back rescue redirect_to required_path

rupsray
źródło
0
setup do
  @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }
end

W Railsach 2.2.2 powyższy blok nigdy nie przeprowadzał rzeczywistego testu. Mówiąc, że

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

linia nie biegła. Możesz po prostu pozbyć się bloku konfiguracyjnego i użyć

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

zamiast. I to powinno ustawić sędziego


źródło
0

Najprostszym rozwiązaniem powyższego problemu jest wysłanie żądania z powiązanymi nagłówkami. Railsy automatycznie odczytują ten nagłówek.

post '/your-custom-route', {}, {'HTTP_REFERER': 'http://www.your-allowed-domain.com'}
Nerw
źródło
0

Obecnie używałem Rails 5.2.1, moje podejście do referer żądań skrótów wewnątrz kontrolera jest takie jak poniżej:

let(:stub_referer) { some_path(some_param) }
before do
  request.headers.merge! referer: stub_referer
  get :some_action, format: :html
end
Agung Prasetyo
źródło