2010-10-04 11 views
5

Dado un par de ciudades en el PP:¿Cómo se prueba limitaciones ruta utilizando RSpec

City.first.attributes => {:id => 1, :name => 'nyc'} 
City.last.attributes => {:id => 2, :name => 'boston'} 

Y una ruta como:

match '/:city/*dest' => 'cities#do_something', :constraints => {:city => /#{City.all.map{|c| c.name}.join('|'}/} 

(por lo que las restricciones deberían evaluar a:/NYC | Boston /)

Y una especificación:

it "recognizes and generates a route for city specific paths" do 
    { :put => '/bad-city/some/path' }.should route_to({:controller => "cities", :action => "do_something", :dest => 'some/path', :city => 'bad-city'}) 
end 

Esperaría una falla. Pero pasa.

mismo modo:

it "doesn't route bad city names" do 
    { :put => '/some-bad-city/some/path' }.should_not be_routable 
end 

Aquí espero que pase, pero falla.

Parece que la restricción se ignora en las especificaciones, ya que las ciudades coincidentes tienen el mismo comportamiento que las malas.

¿Es esto un problema conocido, o me estoy perdiendo algo que tengo que hacer?

+0

Porque esto funciona en dev, pero no en prueba, estoy pensando que el problema es que la restricción se evalúa al inicio, y en el DB de prueba no hay ciudades en ese punto. Entonces, la expresión regular se ve como // y coincide con todo. Pero cuando trato de convertirlo en un Proc, o en una clase que implementa #matches? (Request), parece que nunca se llama. –

Respuesta

11

Este enfoque funciona: En routes.rb

match '/:city/*destination' => 'cities#myaction', :constraints => {:city => /#{City.all.map{|c|c.slug}.join('|')}/} 

En la especificación:

describe "routing" do 
    before(:each) do 
    @mock_city = mock_model(City, :id => 42, :slug => 'some-city') 
    City.stub!(:find_by_slug => @mock_city, :all => [@mock_city]) 
    MyApp::Application.reload_routes! 
    end 

    it "recognizes and generates a route for city specific paths" do 
    { :get => '/some-city/some/path' }.should route_to({:controller => "cities", :action => "myaction", :destination => 'some/path', :city => 'some-city'}) 
    end 

    it "rejects city paths for cities that don't exist in the DB" do 
    { :get => '/some-bad-city/some/path' }.should_not be_routable 
    end 
end 

Por último, agregué un observador para volver a cargar rutas cada vez que cambia la tabla de ciudades.

+5

Es horrible usar un db encontrar todo en las rutas. Rb así. En este caso, el controlador o un before_filter deben validar la ciudad. – oma

0

Al especificar limitaciones, debe incluir el parámetro para limitar:

match '/:city/*dest' => 'cities#do_something', :constraints => { :city => /nyc|boston|philly/ } 
+0

Usted sabe - en mi intento de simplificar el problema, introduje un error tipográfico. Gracias por la captura. –