2008-09-15 13 views
17

He creado una aplicación de aprendizaje utilizando Bort, que es una aplicación base que incluye Restful Authentication y RSpec. Lo tengo en funcionamiento y agregué un nuevo objeto que requiere que los usuarios inicien sesión antes de que puedan hacer algo (before_filter :login_required en el controlador). [edit: También debo mencionar que el usuario has_many de la nueva clase y solo el usuario debería poder verlo.]Rails, Restful Authentication & RSpec - Cómo probar modelos nuevos que requieren autenticación

He creado el nuevo modelo/controlador utilizando los generadores de Rspec que han creado una serie de valores predeterminados pruebas. Todos pasan si no hay before_filter pero varios fallan, como debería esperarse, una vez que el before_filter está en su lugar.

¿Cómo hago para que las pruebas generadas se ejecuten como si hubiera/no un usuario conectado? ¿Necesito un lote completo de coincidencias que no haya iniciado sesión - redireccionar las pruebas? Supongo que es una especie de técnica burlona o accesorio, pero soy nuevo en RSpec y un poco a la deriva. También se apreciarán buenos enlaces tutoriales de RSpec.

Respuesta

7

Tengo una configuración muy similar, y debajo está el código que estoy usando para probar esto. En cada uno de los describe s pongo en:

it_should_behave_like "login-required object" 
def attempt_access; do_post; end 

Si todo lo que necesita es un inicio de sesión, o

it_should_behave_like "ownership-required object" 
def login_as_object_owner; login_as @product.user; end 
def attempt_access; do_put; end 
def successful_ownership_access 
    response.should redirect_to(product_url(@product)) 
end 

Si necesita la propiedad. Obviamente, los métodos de ayuda cambian (muy poco) con cada giro, pero esto hace la mayor parte del trabajo por usted. Esto está en mi spec_helper.rb

shared_examples_for "login-required object" do 
    it "should not be able to access this without logging in" do 
    attempt_access 

    response.should_not be_success 
    respond_to do |format| 
     format.html { redirect_to(login_url) } 
     format.xml { response.status_code.should == 401 } 
    end 
    end 
end 

shared_examples_for "ownership-required object" do 
    it_should_behave_like "login-required object" 

    it "should not be able to access this without owning it" do 
    attempt_access 

    response.should_not be_success 
    respond_to do |format| 
     format.html { response.should be_redirect } 
     format.xml { response.status_code.should == 401 } 
    end 
    end 

    it "should be able to access this if you own it" do 
    login_as_object_owner 
    attempt_access 

    if respond_to?(:successful_ownership_access) 
     successful_ownership_access 
    else 
     response.should be_success 
    end 
    end 
end 
4

Encontré algunas respuestas a mi propia pregunta. Básicamente, necesitaba entender cómo simular el usuario desde restful_authentication para que las pruebas de controlador rspec autogeneradas pudieran pasar incluso si había agregado before_filter: login_required.

Aquí están algunos de mis recursos solo se encuentran:

RSpec: It Should Behave Like

rspec, restful_authentication, and login_required

using restful_authentication current_user inside controller specs

DRYing up your CRUD controller RSpecs

1

para burlarse de un usuario está conectado, que cortar en el controlador para configurar manualmente @current_user:

module AuthHelper 
    protected 

    def login_as(model, id_or_attributes = {}) 
    attributes = id_or_attributes.is_a?(Fixnum) ? {:id => id} : id_or_attributes 
    @current_user = stub_model(model, attributes) 
    target = controller rescue template 
    target.instance_variable_set '@current_user', @current_user 

    if block_given? 
     yield 
     target.instance_variable_set '@current_user', nil 
    end 
    return @current_user 
    end 

    def login_as_user(id_or_attributes = {}, &block) 
    login_as(User, id_or_attributes, &block) 
    end 
end 
7

Cuando no probar la autenticación, pero las pruebas de los controladores que necesita el usuario sea autenticado por lo general golpeo el método de filtro:

before(:each) do 
    controller.stub!(:authenticate).and_return(true) 
end 

El ejemplo anterior funciona donde mi before_filter se establece en el método de autenticar :

before_filter :authenticate 

y la autenticación en mi aplicación utiliza Autenticación básica HTTP, pero realmente puede ser cualquier otro mecanismo de autenticación.

private 
def authenticate 
    authenticate_or_request_with_http_basic do |user,password| 
    user == USER_NAME && password == PASSWORD 
    end 
end 

Creo que es una forma bastante sencilla de probar.

+0

¡El más dulce! – AnkitG

Cuestiones relacionadas