Forum: RSpec step definitons to check login

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
James B. (Guest)
on 2008-12-16 21:34
I am working with the authlogic gem and trying to create a simple login
test from cucumber features. The feature statement is:

Given the user is not logged in

The step definition for this is confounding me.  In the
application_controller the authlogic tutorial recommends the following:

private
    def require_user
      unless current_user
        store_location
        flash[:notice] = "You must sign in to access this page"
        redirect_to new_user_session_url
        return false
      end
    end

    def require_no_user
      if current_user
        store_location
        flash[:notice] = "You must be logged out to access this page"
        redirect_to account_url
        return false
      end

As these are private methods they are not directly accessible from the
step definitions and I am at a loss as to how to proceed.  I could
augment the application controller with a public user_authenticated
method:

  def user_authenticated
     return true if current_user
     false
  end

But it seems wrong to alter the application code for no other purpose
than to ease testing.  Is there another approach that I should be using?
David C. (Guest)
on 2008-12-16 21:58
(Received via mailing list)
On Tue, Dec 16, 2008 at 1:34 PM, James B. <removed_email_address@domain.invalid>
wrote:
>      unless current_user
>        flash[:notice] = "You must be logged out to access this page"
>     return true if current_user
>     false
>  end
>
> But it seems wrong to alter the application code for no other purpose
> than to ease testing.  Is there another approach that I should be using?

For things like session state, general consensus seems to be to go
through the app, not directly after its internals. So to log in I'd do
something like this:

Given /a user logged in as "(.*)"/ do |role|
  user = create_user(role, 'supersecret') #helper method
  visit login_path
  fill_in :username, :with => user.username
  fill_in :password, :with => 'supersecret'
  click_button "Login"
end

For an anonymous user, I usually just have an empty step:

Given /an anonymous user/ do; end

This assumes that you have to explicitly log in to be logged in, but
that seems like a safe assumption to me.

As for your point about changing code to make it testable, while I can
appreciate the desire to avoid modifying code for tests, if that's
what it takes to test it, I do it. In this case I wouldn't bother, but
as a general principle tests are part of the code base, just important
(if not more so) than the application code.

FWIW,
David
Andrew P. (Guest)
on 2008-12-17 01:49
(Received via mailing list)
Doing this for Restful-Authentication I add the following in
features/support/env.rb

# Make visible for testing
ApplicationController.send(:public, :logged_in?, :current_user,
:authorized?)

Hopefully something similar will work with Authlogic

Andrew

2008/12/16 James B. <removed_email_address@domain.invalid>
Zach D. (Guest)
on 2008-12-17 02:09
(Received via mailing list)
On Tue, Dec 16, 2008 at 6:47 PM, Andrew P. 
<removed_email_address@domain.invalid>
wrote:
> Doing this for Restful-Authentication I add the following in
> features/support/env.rb
>
> # Make visible for testing
> ApplicationController.send(:public, :logged_in?, :current_user,
> :authorized?)

Why do you need these available for cucumber scenarios?


>> Given the user is not logged in
>>        return false
>>
>> But it seems wrong to alter the application code for no other purpose
> rspec-users mailing list
> removed_email_address@domain.invalid
> http://rubyforge.org/mailman/listinfo/rspec-users
>



--
Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com
Andrew P. (Guest)
on 2008-12-17 03:03
(Received via mailing list)
So I can confirm that I'm logged in, that the user is who I say he is,
etc.

e.g

Then /^I should be logged in$/ do
  controller.logged_in?.should be_true
end

makes sense?

2008/12/16 Zach D. <removed_email_address@domain.invalid>
Zach D. (Guest)
on 2008-12-17 03:32
(Received via mailing list)
On Tue, Dec 16, 2008 at 7:48 PM, Andrew P. 
<removed_email_address@domain.invalid>
wrote:
> So I can confirm that I'm logged in, that the user is who I say he is, etc.
>
> e.g
>
> Then /^I should be logged in$/ do
>   controller.logged_in?.should be_true
> end
>
> makes sense?

I know why you're doing it, but I just want to know *why* you're doing
it? Can you not tell through the application itself that someone is
logged in, logged out, and verify their identity without having to
expose the internals?


>> > :authorized?)
>> >>
>> >>      unless current_user
>> >>        flash[:notice] = "You must be logged out to access this page"
>> >>     return true if current_user
>> >> removed_email_address@domain.invalid
>>
>> --
>> Zach D.
>> http://www.continuousthinking.com
>> http://www.mutuallyhuman.com
>> _______________________________________________
>> rspec-users mailing list
>> removed_email_address@domain.invalid
>> http://rubyforge.org/mailman/listinfo/rspec-users
>
>



--
Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com
Aslak H. (Guest)
on 2008-12-17 03:41
(Received via mailing list)
On Wed, Dec 17, 2008 at 1:48 AM, Andrew P. 
<removed_email_address@domain.invalid>
wrote:

> So I can confirm that I'm logged in, that the user is who I say he is, etc.
>
> e.g
>
> Then /^I should be logged in$/ do
>   controller.logged_in?.should be_true


Or:
controller.should be_logged_in

Aslak
Zach D. (Guest)
on 2008-12-17 03:50
(Received via mailing list)
On Tue, Dec 16, 2008 at 8:30 PM, Zach D. <removed_email_address@domain.invalid>
wrote:
>
> I know why you're doing it, but I just want to know *why* you're doing
> it? Can you not tell through the application itself that someone is
> logged in, logged out, and verify their identity without having to
> expose the internals?

I'm not trying to be pedantic or facetious. I'm really trying to
explore the use case,


>>> > # Make visible for testing
>>> >
>>> >> private
>>> >>      if current_user
>>> >>
>>> >> _______________________________________________
>>>
>>
>>
>
>
>
> --
> Zach D.
> http://www.continuousthinking.com
> http://www.mutuallyhuman.com
>



--
Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com
James B. (Guest)
on 2008-12-17 16:44
Zach D. wrote:
> On Tue, Dec 16, 2008 at 8:30 PM, Zach D. <removed_email_address@domain.invalid>
> wrote:
>>
>> I know why you're doing it, but I just want to know *why* you're doing
>> it? Can you not tell through the application itself that someone is
>> logged in, logged out, and verify their identity without having to
>> expose the internals?
>

In my case I am exploring the whole nature of BDD. Since experience,
much of it bad, is the best teacher I am trying to cram as much of it as
possible into the front end; before it gets expensive.

Testing whether or not the application can detect and distinguish
between authenticated and non-authenticate requests where it matters is
important in my opinion.  The situation being that some parts are
accessible anonymously and some are not.  It might be considered
desirable to limit access to things like the log in form only to
non-authenticated requests.  It such a feature is required then the
means to test for it must be provided as well.


Regards,
James B. (Guest)
on 2008-12-17 16:45
Andrew P. wrote:
> Doing this for Restful-Authentication I add the following in
> features/support/env.rb
>
> # Make visible for testing
> ApplicationController.send(:public, :logged_in?, :current_user,
> :authorized?)
>

Forgive my ignorance but would you do me the favour of explaining
exactly what this does?  I can guess but I would rather have a clear
understanding of how this construct works so that I can generalize its
application.

Regards,
James B. (Guest)
on 2008-12-17 16:56
Re: authlogin

Can someone familiar with this gem explain where and how the
user_sessions are maintained?   I have pawed through the code but it has
left me rather more confused than not.  The best inkling I can arrive at
is that the authlogic persistence token is stored in the session data
and that the UserSession model serially searches sessions for that token
string in whatever store medium that the Rails application is using.
However, I cannot seem to identify exactly where and how this is done in
the code.  Advice would be welcome.
Pat M. (Guest)
on 2008-12-17 17:10
(Received via mailing list)
James B. <removed_email_address@domain.invalid> writes:

> In my case I am exploring the whole nature of BDD. Since experience,
>
>
> Regards,

I think Zach's point was that you can tell that someone is logged in if
you see a "edit your profile" link somewhere, and they're not logged in
if you see a "log in" link on the page.  Yes, of course it's useful to
know whether someone is authenticated or not...but you can test that
through properties of your own app, rather than digging under the hood
and calling the auth system directly.

Pat
Nicolás Sanguinetti (Guest)
on 2008-12-17 17:19
(Received via mailing list)
Module#public (a private method) works in one of two ways: 1) it
receives a list of symbols with method names, those methods are
decorated as public. 2) it receives no arguments, in which case all
methods defined from that point forward (until another visibility
declaration is encountered in the class definition or the class
closed) are public.

Same with Module#protected and Module#private.

So what he's doing is turning logged_in?, current_user and authorized
into public methods.

Of course, a 30 second trip in google land would have led you to the
ruby documentation, where you'd have found a good explanation with
examples. Or, running `ri public` would've steered you in the right
direction.

-foca

/me wishes people used ri more.
James B. (Guest)
on 2008-12-17 17:23
Pat M. wrote:
> James B. <removed_email_address@domain.invalid> writes:

>
> I think Zach's point was that you can tell that someone is logged in if
> you see a "edit your profile" link somewhere, and they're not logged in
> if you see a "log in" link on the page.  Yes, of course it's useful to
> know whether someone is authenticated or not...but you can test that
> through properties of your own app, rather than digging under the hood
> and calling the auth system directly.
>

That is what I gathered from the "visits login_path" statement in
David's example.  Still, I am interested in finding out what other ways
are possible to test for session authentication status and how implement
them, if only to assure myself that they are not the way I want to do
this.  I have yet to unload a lot of baggage retained from previous
experience.

I am also trying to gain a comfort level with the authlogic gem.  That
desire is in part driving this quest.
James B. (Guest)
on 2008-12-17 17:33
Nicolás Sanguinetti wrote:
>
> Of course, a 30 second trip in google land would have led you to the
> ruby documentation, where you'd have found a good explanation with
> examples. Or, running `ri public` would've steered you in the right
> direction.
>
> -foca
>
> /me wishes people used ri more.

I have open on my desktop at this moment the rdocs for:

Module
Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::LoggedIn

Class
ActionController::Base

I regret if my question upset you but it seemed to me a reasonable
request at the time.  Google is a wonderful tool.  I use it a very great
deal. But, it does require a certain facility with the topic to
formulate effective searches.  On this topic I fear that my capabilities
are somewhat deficient.

Your explanation was very helpful and informative.  Thank you very much.
Ingo W. (Guest)
on 2008-12-17 18:05
(Received via mailing list)
Hi all,

I am developing a rails plugin/gem with rspec. The plugin extends
ActiveRecord, so the specs basically needs a complete environment with
database access to run. What is a good way to set this up in a way
that can be bundled with the plugin, maybe in the form of a stripped-
down rails and a sqlite db?

Ingo
Scott T. (Guest)
on 2008-12-17 18:28
(Received via mailing list)
On Dec 17, 2008, at 10:26 AM, Ingo W. wrote:

> Hi all,
>
> I am developing a rails plugin/gem with rspec. The plugin extends
> ActiveRecord, so the specs basically needs a complete environment
> with database access to run. What is a good way to set this up in a
> way that can be bundled with the plugin, maybe in the form of a
> stripped-down rails and a sqlite db?

Here's what I've used for FixtureReplacement in the past (which linoj
generously contributed):

https://gist.github.com/3525b4cb43f0710a0ac0

Scott
David C. (Guest)
on 2008-12-17 19:02
(Received via mailing list)
On Wed, Dec 17, 2008 at 9:23 AM, James B. <removed_email_address@domain.invalid>
wrote:
>>
>
> That is what I gathered from the "visits login_path" statement in
> David's example.  Still, I am interested in finding out what other ways
> are possible to test for session authentication status and how implement
> them, if only to assure myself that they are not the way I want to do
> this.  I have yet to unload a lot of baggage retained from previous
> experience.

You're a bit restricted in cucumber out of the box, because for rails,
cucumber wraps ActionController::Integration::Session, which goes
through routing. You don't have controller objects readily available.

You have two options if you want to get at internals here (which
should really be your last resort):

1. write a new World for cucumber that wraps
ActionController::TestCase instead of
ActionController::Integration::Session. You'd have to figure out a way
to have that World loaded for some scenarios and the other loaded for
others.

2. use rspec-rails for more granular inspection. In an rspec
controller spec, you have access to the controller object.

HTH,
David
Pat M. (Guest)
on 2008-12-17 20:05
(Received via mailing list)
Ingo W. <removed_email_address@domain.invalid> writes:

> rspec-users mailing list
> removed_email_address@domain.invalid
> http://rubyforge.org/mailman/listinfo/rspec-users

Hey Ingo,

http://github.com/pat-maddox/rspec-plugin-generato... is a
generator that allows you to easily generate plugins that use rspec, and
will also set up a database if you pass it the --with-database option.
Should be pretty self-explanatory if you generate one and look at the
code.

http://github.com/pat-maddox/acts_as_value_object/... is a gem
that I'm working on, extends activerecord as you need to do.  Should be
helpful.

Pat
Hendrik V. (Guest)
on 2008-12-17 20:42
(Received via mailing list)
Hi Ingo,
we use our own dry_plugin_test_helper [1] for almost all our plugin
tests
and it works fine. It provides a stripped down Rails environment inside
the
gem so that you don't need it in your plugin just to test your plugin
code.
We mainly use it with Test::Unit but I don't see why rspec wouldn't
work.


Cheers,
Hendrik

[1] http://github.com/imedo/dry_plugin_test_helper/tree/master
Nick H. (Guest)
on 2009-02-09 17:05
(Received via mailing list)
On 17/12/2008, at 9:56 AM, James B. wrote:
> string in whatever store medium that the Rails application is using.
> However, I cannot seem to identify exactly where and how this is
> done in
> the code.  Advice would be welcome.

G'day James. I know this was like 2 months ago, but I finally got
around to reading the rest of this thread.

The last version of AuthLogic that I used was 1.0.1, so things might
have changed a bit since then. Nonetheless...

Authlogic uses a model called UserSession to deal with login sessions.
If you have a look at UserSessionsController, you'll see that there
are only three methods:
   * new
   * create
   * destroy

When a user wants to login, they call UserSessionsController#new,
which renders a login form. The login form submits to
UserSessionsController#create, which authenticates the user. If
successful, the session is saved, which causes the application to
consider the user "logged-in".

When a user wants to logout, they simply visit
UserSessionsController#destroy . This kills their UserSession object,
which results in the application considering them as "not logged-in".

I hope that helps. If you have other questions, feel free to post
here, or email me privately, or email Authlogic's author; he's quite
friendly.

Cheers,
Nick
This topic is locked and can not be replied to.