2010-11-17 9 views
5

ich ein Projekt am Start und ich möchte in der Lage sein, alles zu testen :)Rspec, Cancan und Entwickeln

und ich habe einige Probleme mit Cancan und ersinnen.

Zum Beispiel habe ich eine Controller-Kontakte. Jeder kann sehen und jeder (mit Ausnahme von verbotenen Personen) kann Kontakt schaffen.

#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 

Der Code funktioniert, aber ich nicht, wie der Controller zu testen. Ich habe das versucht. Das funktioniert, wenn ich die Zeile load_and_authorize_resource kommentiere.

#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 

Aber diese Tests völlig versagt .... Ich sah nichts im Web ... :( Also, wenn Sie mich auf dem Weg raten kann ich folgen muss, ich zu Ohr freuen würde Sie :)

Antwort

6

CanCan ruft nicht Contact.new(params[:contact]). Stattdessen ruft es contact.attributes = params[:contact] später auf, nachdem es einige anfängliche Attribute basierend auf den aktuellen Fähigkeitsberechtigungen angewandt hat.

Weitere Informationen zu dieser und einer alternativen Lösung finden Sie unter Issue #176. Ich habe vor, dies in CanCan Version 1.5 zu beheben, wenn nicht früher.

+0

Danke Ryan! Ich werde das überprüfen! – Arkan

+0

Hallo Ryan, ich habe mir deinen Link angeguckt und danke an Voxik, ich habe seinen Patch angelegt und jetzt kann ich alle meine Tests bestehen. Ich hoffe, Sie werden den Patch bald auf einer neuen Version von Cancan veröffentlichen. Danke noch einmal ! – Arkan