Thanks for the help.
I think I'm getting closer. I'm still not getting a redirect. I
still think it's the same reason though. I say this because when I
modify the last line of my spec to be render_template("index") instead
of redirect, it says that it renders the login template.
Am I putting the should_receive for has_role? in the wrong place?
My modified code is below.
def login
if request.post?
begin
session[:user] = User.authenticate(params[:login][:email],
params[:login][:password]).id
# Redirect the user as appropriate
if current_user.has_role?("tutor")
redirect_to toolkit_path
end
rescue
flash[:warning] = "Your e-mail address or password is invalid."
render :action => "login"
end
end
end
------
describe UsersController do
controller_name :users
before(:each) do
@current_user = mock_model(User,
:email => '[EMAIL PROTECTED]',
:password => 'teamup'
)
controller.stub!(:current_user).and_return(@current_user)
end
it "should login as a tutor" do
@role = mock_model(Role, :title => 'tutor')
@current_user.should_receive(:roles).once.and_return([EMAIL PROTECTED])
User.should_receive(:authenticate).with(@current_user.email,@current_user.password).and_return(@current_user)
@current_user.should_receive(:has_role?).with('tutor').and_return(true)
post :login, :login => {:email => @current_user.email, :password
=> @current_user.password}
request.session[:user].should == @current_user.id
should_be_logged_in
response.should be_redirect
response.should redirect_to(toolkit_path)
end
end
On 7/26/07, Courtenay <[EMAIL PROTECTED]> wrote:
> For starters, refactor your user<-->roles interaction.
>
> class User
>
> def has_role?(name)
> role = Role.find_by_name(name)
> roles.include?(role)
> end
>
> end
>
> Trust me, this will make things much easier to spec, and later, to
> scale. Also, it keeps the DB-specific stuff ("find") in the model,
> where it belongs.
>
> It is my belief that if you see a "find" call in the controller, you
> could probably refactor it and make it easier to maintain, and just
> plain better.
>
> For example, this will only make one DB call per role check for a
> total of ~5 db calls
>
> def has_role?(name)
> roles.count(:conditions => { :name => name }) > 0
> end
>
> This will make one db call to retrieve the list of role names for a
> total of 1 db call for the whole action.
>
> def has_role?(name)
> @role_names ||= roles.map(&:name)
> @role_names.include?(name)
> end
>
> So you can change the implementation without screwing round with a
> bunch of tests. In fact neither of these would require a change of
> controller specs.
>
> @user.should_receive(:has_role?).with('tutor').and_return(true)
>
> Hope this helps :)
>
> Courtenay
>
>
> On 7/26/07, Justin Williams <[EMAIL PROTECTED]> wrote:
> > I've done some more work on the specs, and it seems that my mocks
> > aren't pushing in the roles array associated with current_user.
> >
> >
> > describe UsersController do
> > before(:each) do
> > @user = mock_model(User,
> > :id => 1,
> > :email => '[EMAIL PROTECTED]',
> > :password => 'teamup'
> > )
> >
> > controller.stub!(:current_user).and_return(@user)
> > end
> >
> > it "should login as a tutor" do
> > @role = mock_model(Role)
> > @role.stub!(:title).and_return("tutor")
> > @user.should_receive(:roles).and_return([EMAIL PROTECTED])
> > @user.stub!(:type).and_return("Tutor")
> >
> > User.should_receive(:authenticate).with('[EMAIL
> > PROTECTED]','teamup').and_return(@user)
> > session[:user] = @user.id
> > post :login, :login => {:email => "[EMAIL PROTECTED]", :password
> > => "teamup"}
> > response.should be_success
> > response.should redirect_to(:controller => "toolkit/overview")
> > should_be_logged_in
> > end
> > end
> >
> >
> > The error i receive is 'UsersController should login as a tutor'
> > FAILED expected redirect to {:controller=>"toolkit/overview"}, got no
> > redirect". If I modify the test to be should render_template("index")
> > it will fail, saying that the template is reverting back to login.
> >
> > Any ideas on what I'm doing wrong?
> >
> > Thanks!
> >
> > - j
> >
> > On 7/24/07, Justin Williams <[EMAIL PROTECTED]> wrote:
> > > On 7/24/07, David Chelimsky <[EMAIL PROTECTED]> wrote:
> > >
> > > > Would you please post the code for the actions as well?
> > >
> > > def login
> > > if request.post?
> > > begin
> > > session[:user] = User.authenticate(params[:login][:email],
> > > params[:login][:password]).id
> > >
> > > if current_user.roles.include?(Role.find_by_title("employee")) or
> > > current_user.roles.include?(Role.find_by_title("administrator"))
> > > redirect_to staff_path
> > > elsif current_user.roles.include?(Role.find_by_title("tutor"))
> > > redirect_to toolkit_path
> > > elsif current_user.roles.include?(Role.find_by_title("client"))
> > > redirect_to client_path
> > > end
> > > rescue
> > > flash[:warning] = "Your e-mail address or password is invalid."
> > > render :action => "login"
> > > end
> > > end
> > > end
> > >
> > >
> > > It should also be noted, I realized the specs have two different sets
> > > of credentials. Modifying this to use a single one doesn't correct
> > > it. I was just a bit too liberal in my cut/pasting for email.
> > >
> > > Thanks!
> > >
> > > - j
> > >
> >
> >
> > --
> > -
> > Justin Williams
> > [EMAIL PROTECTED]
> > work: http://www.secondgearllc.com/
> > play: http://www.carpeaqua.com
> > _______________________________________________
> > rspec-users mailing list
> > [email protected]
> > http://rubyforge.org/mailman/listinfo/rspec-users
> >
> _______________________________________________
> rspec-users mailing list
> [email protected]
> http://rubyforge.org/mailman/listinfo/rspec-users
>
--
-
Justin Williams
[EMAIL PROTECTED]
work: http://www.secondgearllc.com/
play: http://www.carpeaqua.com
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users