Help on skipping a before_filter for a story

Hi folks,

I’m hoping for a bit of help on best-practices for skipping a
before_filter when running a particular step. Specifically the
authentication filter. What happens is that the post (see code below)
returns a redirect response to the login page triggered by the of my
authentication filter, rather than the contents of what I’d like to be
testing.

How do people handle temporarily turning of this kind of thing that’s
not relevant to the test? Temporarily I’ve just put an unless RAILS_ENV
== ‘test’ after it, but obviouly that won’t work for the specs that
actually test that before filter!

Thanks for any help!

-Eric

Given “$field in new entry is $field_value” do |field,field_value|
@params ||= {}
@params[field.intern] = field_value
end

When “submitting the new entry” do
post “/entry”, :record => @params
end

Then “should include confirmation: $message” do |message|
response.should have_text(/#{message}/)
end

On Sep 8, 2008, at 8:49 PM, Eric Harris-Braun wrote:

not relevant to the test? Temporarily I’ve just put an unless
@params[field.intern] = field_value
end

When “submitting the new entry” do
post “/entry”, :record => @params
end

Then “should include confirmation: $message” do |message|
response.should have_text(/#{message}/)
end

If your controller has this

:before_filter :login_required

and say, login_required is defined in application.rb, then your
controller spec can stub it out

controller.stub!(:login_required).and_return(true)

On Mon, Sep 8, 2008 at 9:47 PM, Jonathan L.
[email protected] wrote:

testing.
Given “$field in new entry is $field_value” do |field,field_value|
end

If your controller has this

   :before_filter :login_required

and say, login_required is defined in application.rb, then your controller
spec can stub it out

   controller.stub!(:login_required).and_return(true)

This is true in a controller spec, but Eric was asking about story
steps where this won’t work.

Cheers,
David

never mind, i misread your question, thought you were talking about a
controller spec
rather than a story

stories are intended to exercise the full stack, so I actually log
in, with a step like this:

Given "I am logged in " do
user = create_registered_user( :login => ‘user’, :password =>
‘secret’)
post_via_redirect “/sessions”, :login => ‘user’, :password =>
“secret”,
response.should be_success
session[:user].should == user.id
end

Eric Harris-Braun wrote:

not relevant to the test? Temporarily I’ve just put an unless RAILS_ENV
end

When “submitting the new entry” do
post “/entry”, :record => @params
end

Then “should include confirmation: $message” do |message|
response.should have_text(/#{message}/)
end

Hi Eric,
The point of stories is to have them act as integration tests going
through the entire stack just like a typical user would. So, you should
really be logging in to your app before you start submitting forms. So
doing something like:

When “submitting the new entry” do
User.create!(:login => ‘james’, :password => ‘password’)
post “/sessions”, :login => ‘james’, :passsword => ‘password’
post “/entry”, :record => @params

end

I typically extract this out into a helper called ‘login’ where I can
simply pass a user object.

BTW, have you checked out webrat yet? It makes submitting forms very
easy.

HTH,
Ben

Thanks David for the very detailed response.

I see what you mean about why this should be hard to do. In fact
perhaps what I should do instead is simply specify the user-login part
in my story instead of skipping it. I didn’t at first because its a
pain, i.e. sending the sessions/create post and then saving the sessions
cookie and then sending it along with the post I really want to test.

Are there any best-practices or examples of how folks accomplish this
task?

Thanks,

-Eric

On Mon, Sep 8, 2008 at 10:49 PM, Eric Harris-Braun [email protected]
wrote:

Thanks David for the very detailed response.

I see what you mean about why this should be hard to do. In fact
perhaps what I should do instead is simply specify the user-login part
in my story instead of skipping it. I didn’t at first because its a
pain, i.e. sending the sessions/create post and then saving the sessions
cookie and then sending it along with the post I really want to test.

Are there any best-practices or examples of how folks accomplish this
task?

You should not need to save any cookies. You should be able to simply
log in and then go to the secure page. Have you tried just doing that?

On Mon, Sep 8, 2008 at 7:49 PM, Eric Harris-Braun [email protected] wrote:

not relevant to the test? Temporarily I’ve just put an unless RAILS_ENV
== ‘test’ after it, but obviouly that won’t work for the specs that
actually test that before filter!

Hi Eric,

Story Runner and Cucumber both hook into rails through
ActionController::Integration::Session which, as far as I know, offers
no hooks the likes of which you are looking for.

The get, post, put and delete methods are not the same as those in
rails functional tests or rspec controller specs because they do not
target a specific controller - they actually go through routing - so
there is no way to get a handle on the controller on which you want to
bypass the filter.

For me, this is as it should be. The idea behind automating scenarios
is to run through the stack, including routing. Even when we bypass
routing and controllers and go directly to models, we’re still going
from the outside of the model layer - not to its internals.

That said, if you still want to do this and control when it happens, I
think you could do something like this:

class ApplicationController
def self.skipping_authentication
alias_method :orig_authenticate, :authenticate
def authenticate; true; end
yield
alias_method :authenticate, :orig_authenticate
end
end

ApplicationController.skipping_authentication do
post “/entry”, :record => @params
end

I have not tested it in a story. It might not work. But it might :slight_smile:

I did try the concept out outside of rails/stories/etc:

That’ll output this:

BAR
bar

HTH,
David

On Tue, Sep 9, 2008 at 2:33 AM, Eric Harris-Braun
[email protected] wrote:

Hi folks,

I’m hoping for a bit of help on best-practices for skipping a

There are no practices for this (or anything else) that are better
than any other practice.

before_filter when running a particular step. Specifically the
authentication filter. What happens is that the post (see code below)
returns a redirect response to the login page triggered by the of my
authentication filter, rather than the contents of what I’d like to be
testing.

My general advice is to not futz around with your application’s
behaviour when you’re running stories (or cucumber features).
Why? Because stories/features are intended to be end-to-end tests of
the unaltered app. This was recently discussed in a thread about
mocking/stubbing from steps.

If the application wants you to log in, then log in from one of your
steps.

If for whatever reason this is impractical I would recommend doing
something like:

unless ENV[‘SKIP_LOGIN_IN_STORIES’]

-and set that env var from one of the ruby files that get loaded
before your story/feature runs.
(but I would consider this a test smell)

Cheers,
Aslak