2010-11-17 8 views
5

Sto iniziando un progetto e vorrei essere in grado di testare tutto :)Rspec, CanCan e mettere a punto

e ho alcuni problemi con CanCan e mettere a punto.

Ad esempio, ho un controller Contatti. Tutti possono vedere e tutti (tranne le persone vietate) possono creare contatti.

#app/controllers/contacts_controller.rb 
class ContactsController < ApplicationController 
    load_and_authorize_resource 

    def index 
    @contact = Contact.new 
    end 

    def create 
    @contact = Contact.new(params[:contact]) 
    if @contact.save 
     respond_to do |f| 
     f.html { redirect_to root_path, :notice => 'Thanks'} 
     end 
    else 
     respond_to do |f| 
     f.html { render :action => :index } 
     end 
    end 
    end 
end 

Il codice funziona, ma non è come testare il controller. Ho provato questo. Funziona se commento la linea load_and_authorize_resource.

#spec/controllers/contacts_controller_spec.rb 
require 'spec_helper' 

describe ContactsController do 

    def mock_contact(stubs={}) 
    (@mock_ak_config ||= mock_model(Contact).as_null_object).tap do |contact| 
     contact.stub(stubs) unless stubs.empty? 
    end 
    end 

    before (:each) do 
    # @user = Factory.create(:user) 
    # sign_in @user 
    # @ability = Ability.new(@user) 
    @ability = Object.new 
    @ability.extend(CanCan::Ability) 
    @controller.stubs(:current_ability).returns(@ability) 
    end 

    describe "GET index" do 
    it "assigns a new contact as @contact" do 
     @ability.can :read, Contact 
     Contact.stub(:new) { mock_contact } 
     get :index 
     assigns(:contact).should be(mock_contact) 
    end 
    end 

    describe "POST create" do 

    describe "with valid params" do 
     it "assigns a newly created contact as @contact" do 
     @ability.can :create, Contact 
     Contact.stub(:new).with({'these' => 'params'}) { mock_contact(:save => true) } 
     post :create, :contact => {'these' => 'params'} 
     assigns(:contact).should be(mock_contact) 
     end 

     it "redirects to the index of contacts" do 
     @ability.can :create, Contact 
     Contact.stub(:new) { mock_contact(:save => true) } 
     post :create, :contact => {} 
     response.should redirect_to(root_url) 
     end 
    end 

    describe "with invalid params" do 
     it "assigns a newly created but unsaved contact as @contact" do 
     @ability.can :create, Contact 
     Contact.stub(:new).with({'these' => 'params'}) { mock_contact(:save => false) } 
     post :create, :contact => {'these' => 'params'} 
     assigns(:contact).should be(mock_contact) 
     end 

     it "re-renders the 'new' template" do 
     @ability.can :create, Contact 
     Contact.stub(:new) { mock_contact(:save => false) } 
     post :create, :contact => {} 
     response.should render_template("index") 
     end 
    end 

    end 
end 

Ma questi test totalmente fallito .... ho visto nulla sul web ... :( Quindi, se mi si può consigliare il modo devo seguire, sarei felice di orecchio you :)

risposta

6

CanCan non chiama Contact.new(params[:contact]). Chiama invece contact.attributes = params[:contact] in seguito dopo aver applicato alcuni attributi iniziali in base alle autorizzazioni dell'abilità corrente.

Vedere Issue #176 per dettagli su questo e una soluzione alternativa. Ho intenzione di farlo correggere in CanCan versione 1.5 se non prima.

+0

Grazie ryan! Lo controllerò! – Arkan

+0

Ciao Ryan, ho dato un'occhiata al tuo link e grazie a voxik, ho applicato la sua patch e ora sono in grado di superare tutti i miei test. Spero che pubblicherai presto la patch su una nuova versione di Cancan. Grazie ancora ! – Arkan