[rspec-users] session data and user stories

David Chelimsky dchelimsky at gmail.com
Fri Jan 18 05:05:14 EST 2008


On Jan 16, 2008 4:59 PM, Evan Short <evan.short at gmail.com> wrote:
> hello there,
>
> i have been trying my hand at this rbehave material, specifically in terms
> of integration testing a rails application, and i am curious about the most
> friendly way to deal with session data.
>
> currently, the only way i have found to simulate a session is to open a
> session and refer to everything afterward via the @session variable stored
> after open_session. it seems to be workable, but is far from ideal:
>
> dir = File.dirname(__FILE__)
>  require 'rubygems'
>  require 'spec/story'
>  require "#{dir}/helper"
>
>  steps_for(:dealer_login) do
>      Given("I have opened a session") do
>        @session = open_session
>      end
>
>      Given("I am not logged in") do
>        @session.instance_variable_get("@session").should == nil
>      end
>
>      Given("I have a valid login/password combo") do
>        @login_with = valid_dealer_credentials
>      end
>
>      When("I submit my login/ password") do
>        @session.post("/gateway", :user=> @login_with)
>      end
>
> #there has to be a better way to address this
>      Then("I should be authenticated") do
>        @session.response.session.data.should == {:id => 1, "flash" => {}}
>      end
>
> #and this is just hideous.
>      Then("I should be sent to the dealer landing page") do
>        puts @session.response.instance_variable_get("@redirected_to").should
> == {:controller => "dealers"}
>      end
>  end
>
>  with_steps_for(:dealer_login) do
>      run_local_story "dealer_story", :type=>RailsStory
>  end
>
> there is a good chance someone has already covered this and i have just
> managed to miss it. documentation on rbehave is sparse (at best, as i have
> seen it. i have the peepcode, but if anyone has any other good resources i
> would be more than appreciative.)
>
> in the event that this has not been addressed, i see two possibilities:
>
> first, that i am somehow subverting the intention of rbehave. as i
> understand it, however, rbehave is at least partially intended for
> integration-level specification, so it seems to me that this session
> information would be valuable.
>
> on the other hand, perhaps this needs to be addressed in some way. i would
> be happy to help, but i am interested to see the community's opinion on the
> issue first.

RailsStory derives from ActionController::IntegrationTest, which
provides an implicit session. You also get rspec's matchers built
right in. Also, being logged in is not really behaviour - it's state.
All of that said (the following is not tested, but it's the right
idea):

Story: dealer visits landing page
  As a dealer
  I want the dealer landing page to be secure
  So that only dealers can see dealer stuff

  Scenario: anonymous user tries to visit landing page
    Given I am an anonymous user
    When I visit the dealer landing page
    Then I should see the login form

  Scenario: registered dealer logs in
    Given I am a registered dealer
    When I log in
    Then I should see the dealer landing page


steps_for(:dealer_login) do
  Given("I am an anonymous user") do
    # noop
  end

  Given("I am a registered dealer") do
    User.create!(registered_dealer_attributes)
    @credentials = registered_dealer_credentials
  end

  Given("I visit the $page") do |page|
    case page
    when "dealer landing page"
      get "/dealers"
    else
      raise "I don't know how to get to the #{page}"
    end
    follow_redirect if redirect?
  end

  When("I log in") do
    post "/gateway", :user => @credentials
  end

  Then("I should see the $page") do |page|
    case page
    when "dealer landing page"
      template = "/dealers/index"
    else
      raise "I don't know how what template to expect for #{page}"
    end
    follow_redirect if redirect?
  end
end

There are more things to generalize here as things build up. For
example, I've got one step definition that looks like this:

  Then("I should see the $page") do |page|
    page_map = {
      "user form" => "users/form",
      "login form" => "sessions/new",
      "thank you page" => "users/index",
      "user list" => "users/index",
      "group list" => "groups/index",
      "welcome page" => "welcome/index"
    }
    unless page_map[page].nil?
      response.should render_template(page_map[page])
    else
      raise "I don't know what template to look for for #{page.inspect}"
    end
  end

And a similar one for "When I visit the foo page".

You *can* use an explicit session, but this is mostly useful if you
have more than one session running simultaneously. Check out docs for
rails integration tests to get some more insight on this.

There's a lot more to talk about here, but that should get you going. HTH.

Cheers,
David


More information about the rspec-users mailing list