ruby-on-rails - example - rails selenium
Pruebas RSpec redireccionan a URL con parĂ¡metros GET (3)
¿Puedes usar tus ayudantes de ruta en lugar de una cadena simple? Si es así, simplemente puede pasar parámetros de hash a un ayudante de ruta y se convertirán a parámetros de cadena de consulta:
root_url foo: ''bar'', baz: ''quux''
=> "http://www.your-root.com/?baz=quux&foo=bar"
expect(response).to redirect_to(root_url(foo: ''bar'', baz: ''quux''))
¿Ayuda eso, o está restringido a usar cadenas en lugar de ayudantes de ruta?
Otra idea es que simplemente puede hacer valer directamente los valores en el hash de params en lugar de la cadena url + query, ya que los params de cadena de consulta se serializarán en el hash de params ...
Digamos que tengo un FoosController
con un método redirect_to_baz
.
class FoosController < ApplicationController
def redirect_to_baz
redirect_to ''http://example.com/?foo=1&bar=2&baz=3''
end
end
Estoy probando esto con spec/controllers/foos_controller_spec.rb
:
require ''spec_helper''
describe FoosController, :type => :controller do
describe "GET redirect_to_baz" do
it "redirects to example.com with params" do
get :redirect_to_baz
expect(response).to redirect_to "http://example.com/?foo=1&bar=2&baz=3"
end
end
end
Funciona. Sin embargo, si alguien intercambia los parámetros de la cadena de consulta (por ejemplo, http://example.com/?bar=2&baz=3&foo=1
), la prueba falla.
¿Cuál es la forma correcta de probar esto?
Me gustaría hacer algo como:
expect(response).to redirect_to("http://example.com/", params: { foo: 1, bar: 2, baz: 3 })
Miré la documentation e intenté buscar parámetros de response.parameters
, pero no encontré nada de eso. Incluso Hash#to_query
no parece resolver este problema.
Cualquier ayuda sería muy apreciada.
De la documentation , la ruta de redirección esperada puede coincidir con una expresión regular:
expect(response).to redirect_to %r(/Ahttp://example.com)
Para verificar la cadena de consulta de la ubicación de redireccionamiento parece un poco más complicado. Tienes acceso a la ubicación de la respuesta, por lo que deberías poder hacer esto:
response.location
# => http://example.com?foo=1&bar=2&baz=3
Deberías poder extraer los parámetros de la cadena de consulta de esta manera:
redirect_params = Rack::Utils.parse_query(URI.parse(response.location).query)
# => {"foo"=>"1", "bar"=>"2", "baz"=>"3"}
Y a partir de eso, debería ser sencillo verificar que los parámetros de redireccionamiento son correctos:
expect(redirect_params).to eq("foo" => "1", "baz" => "3", "bar" => "2")
# => true
Sin embargo, si tiene que hacer este tipo de lógica más de una vez, definitivamente sería conveniente envolverlo todo en un emparejador de rspec personalizado.
Necesitaba algo similar y terminé con esto:
Pudo escribir pruebas y no preocuparse por el orden de los parámetros de consulta.
expect(response.location).to be_a_similar_url_to("http://example.com/?beta=gamma&alpha=delta")
Coloque lo siguiente en ./spec/support/matchers/be_a_similar_url_to.rb
RSpec::Matchers.define :be_a_similar_url_to do |expected|
match do |actual|
expected_uri = URI.parse(expected)
actual_uri = URI.parse(actual)
expect(actual_uri.host).to eql(expected_uri.host)
expect(actual_uri.port).to eql(expected_uri.port)
expect(actual_uri.scheme).to eql(expected_uri.scheme)
expect(Rack::Utils.parse_nested_query(actual_uri.query)).to eql(Rack::Utils.parse_nested_query(expected_uri.query))
expect(actual_uri.fragment).to eql(expected_uri.fragment)
end
# optional
failure_message do |actual|
"expected that #{actual} would be a similar URL to #{expected}"
end
# optional
failure_message_when_negated do |actual|
"expected that #{actual} would not be a similar URL to #{expected}"
end
end