Comment définir HTTP_REFERER lors d'un test dans Rails?

87

J'essaie de tester un contrôleur et j'ai cette erreur. Je comprends l'erreur, mais je ne sais pas comment la corriger.

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

Précisez-le où? J'ai essayé ceci:

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

Mais j'ai eu la même erreur.

Précisez-le avec quoi, exactement? Je suppose que l'URI de la vue vers laquelle je veux qu'elle revienne:

'/sessions/new'

C'est ce qu'ils veulent dire?


OK, donc il s'avère qu'ils veulent dire faire ceci:

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

Quelqu'un peut-il me dire où cela est documenté? J'aimerais lire le contexte de cette information.

Que faire si le domaine n'est pas "localhost: 3000"? Et si c'est "localhost: 3001" ou quelque chose? Un moyen d'anticiper cela?

Pourquoi cela ne fonctionne pas:

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

La documentation Rails indique spécifiquement que c'est ainsi que vous définissez les en-têtes.

Ethan
la source

Réponses:

90

Leur recommandation se traduit par ce qui suit:

setup do
  @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }
end
James A. Rosen
la source
1
vous pouvez vous en tirer simplement en spécifiant le chemin relatif, comme dans '/ sessions / new'.
Martin Faartoft du
Cela ne fonctionne pas pour moi car j'utilise https => 'on'. Que faire maintenant?
Robert Reiz
47

La réponse acceptée ne fonctionne pas pour les tests d'intégration car la @requestvariable n'existe pas.

Selon RailsGuides , vous pouvez passer des en-têtes aux assistants.

Rails <= 4:

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

Rails> = 5:

test "blah" do
  get root_path, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://foo.com" }
  ...
end
Fotios
la source
2
Merci beaucoup. J'ai cherché 1 heure pour une solution. Votre message fonctionne pour moi!
Robert Reiz
9
Sur Rails 5, les en-têtes sont spécifiés comme get :show, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://example.com/home" }
suit
9

En réponse à la question:

Pourquoi cela ne fonctionne pas:

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

Cela ne fonctionne pas car le document Rails que vous avez lié à une classe différente de celle que vous utilisez probablement.

Vous êtes lié à ActionController::Integration:Session. Je suppose que vous écrivez un test fonctionnel (si vous utilisez Test :: Unit) ou un test de contrôleur (si vous utilisez Rspec). Quoi qu'il en soit, vous utilisez probablement ActionController::TestCaseou une sous-classe de celui-ci. Qui, à son tour, comprend le module ActionController::TestProcess.

ActionController::TestProcessfournit une getméthode avec des paramètres différents de la getméthode fournie par ActionController::Integration:Session. (Ennuyeux, hein?) La signature de la méthode est la suivante:

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

Malheureusement, il n'y a pas de paramètre d'en-tête. Mais au moins, le réglage @request.env['HTTP_REFERER']fonctionne.

rlkw1024
la source
1

Dans Rails3, j'ai eu la même erreur:
pour se débarrasser de cela, le contrôleur correspondant a fourni un sauvetage pour "redirect_to: back"

Exemple:redirect_to :back rescue redirect_to required_path

rupsray
la source
0
setup do
  @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }
end

Dans Rails 2.2.2, le bloc ci-dessus n'a jamais exécuté de test réel. Dire que

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

ligne n'a pas fonctionné. Vous pouvez simplement vous débarrasser du bloc de configuration et utiliser

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

au lieu. Et cela devrait définir le référent


la source
0

La solution la plus simple au problème ci-dessus consiste à faire la demande avec les en-têtes associés. Rails lira automatiquement cet en-tête.

post '/your-custom-route', {}, {'HTTP_REFERER': 'http://www.your-allowed-domain.com'}
Nerf
la source
0

Actuellement, j'ai utilisé Rails 5.2.1, mon approche du référent de demande de stub à l'intérieur du contrôleur est comme ci-dessous:

let(:stub_referer) { some_path(some_param) }
before do
  request.headers.merge! referer: stub_referer
  get :some_action, format: :html
end
Agung Prasetyo
la source