Comment définir HTTP_REFERER lors du test dans Rails?

J’essaie de tester un contrôleur et j’ai cette erreur. Je comprends l’erreur, mais je ne sais pas comment y remédier.

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

Spécifiez-le où? J’ai essayé ceci:

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

Mais eu la même erreur.

Spécifiez-le avec quoi, exactement? Je suppose que l’URI de la vue, je veux qu’il revienne à:

 '/sessions/new' 

Est-ce ce qu’ils veulent dire?


OK, il se trouve que ça veut dire:

 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.

Et 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 marche pas:

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

Les documents Rails indiquent spécifiquement que vous définissez les en-têtes.

Leur recommandation se traduit comme suit:

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

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

Selon RailsGuides , vous pouvez transmettre 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 

En réponse à la question:

Pourquoi cela ne marche pas:

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

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

Vous avez 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). De toute façon, vous utilisez probablement ActionController::TestCase ou une sous-classe de celle-ci. Ce qui inclut à son tour le module ActionController::TestProcess .

ActionController::TestProcess fournit une méthode get avec différents parameters que la méthode get 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, mettre @request.env['HTTP_REFERER'] fonctionne.

Dans Rails3, j’ai eu la même erreur:
Pour se débarrasser de cela dans le contrôleur correspondant fourni de secours pour “redirect_to: back”

Exemple: redirect_to :back rescue redirect_to required_path

 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 effectué de test réel. Dire que

post: create, {: user => {: email => ‘invalide @ abc’}}

ligne n’a pas fonctionné. Vous pouvez simplement vous débarrasser du bloc d’installation et utiliser

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

au lieu. Et il devrait définir le référant

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