2011-10-06 22 views
9

Estoy trabajando en un proyecto de rieles en el que utilizo CanCan para autorizar mis recursos. Cuando un usuario no inicia sesión e intenta enviar una "conversación" (a través de un envío de formulario ajax), CanCan correctamente plantea un 401 con {"status":"error","message":"You must be logged in to do that!"} como respuesta (he verificado esto en el navegador usando Firebug). Sin embargo, en mis pruebas obtener un código de respuesta 302 en lugar de un 401: talks_controller_spec.rb¿Cómo puedo usar RSpec para probar el código de respuesta en una autorización fallida de CanCan?

class TalksController < ApplicationController 
    authorize_resource 

    def create 
    @talk = current_user.talks.build(params[:talk]) 

    respond_to do |format| 
     if @talk.save 
     response = { :redirect => talk_path(@talk) } 
     format.html { redirect_to @talk, notice: 'Talk was successfully created.' } 
     format.json { render json: response, status: :created, } 
     else 
     format.html { render action: "new" } 
     format.json { render json: @talk.errors, status: :unprocessable_entity } 
     end 
    end 
    end 
end 

:

describe TalksController do 
    describe "POST create" do 
    context "when not signed in" do 
     it "should not assign talk" do 
     post :create 
     assigns[:talk].should be_nil 
     end 
     it "should respond with a 401" do 
     post :create 
     response.response_code.should == 401 
     end 
    end 
    end 
end 

El primer ejemplo se incluye aquí tiene éxito (cesionarios: [TALK] no se asignan), pero el segundo no es:

1) TalksController POST create when not signed in should respond with a 401 
    Failure/Error: response.response_code.should == 401 
     expected: 401 
      got: 302 (using ==) 
    # ./spec/controllers/talks_controller_spec.rb:53:in `block (4 levels) in <top (required)>' 

No estoy seguro exactamente de lo que está pasando. ¿Hay alguna manera de probar el código de respuesta real devuelto al navegador? ¿O una forma mejor de probar la autorización?

+0

Puede intentar cambiar las especificaciones para leer 'post: create,: format =>: json' y ver si eso ayuda. – zetetic

+0

¡Gracias por la sugerencia! Desafortunadamente, todavía obtengo el mismo código 302 después de agregar el: format =>: json. –

+1

¿Has mirado el registro de prueba? – zetetic

Respuesta

8

Al final resultó que, mi proyecto rescató las excepciones de autorización de CanCan con la siguiente función. Debido a que la función solo aumenta un 401 cuando la solicitud es ajax (y redirecciona de otra manera), obtuve un 401 en el navegador, pero no en mis pruebas.

# Handle authorization exceptions 
rescue_from CanCan::AccessDenied do |exception| 
    if request.xhr? 
    if signed_in? 
     render json: {:status => :error, :message => "You don't have permission to #{exception.action} #{exception.subject.class.to_s.pluralize}"}, :status => 403 
    else 
     render json: {:status => :error, :message => "You must be logged in to do that!"}, :status => 401 
    end 
    else 
    render :file => "public/401.html", :status => :unauthorized 
    end 
end 

Gracias a zetetic por sugerir puedo comprobar mis registros de prueba, ya que esto revela la diferencia de solicitudes.

Cuestiones relacionadas