This gist is dedicated to all of my fellow clueless n00bs who are frightened by the combination of RSpec, Capybara and Authlogic.
This gist will not tell you how to install Ruby, Rails, RSpec, Capybara or Authlogic. For the most part, you can install any of these by running either:
brew install <packagename>
bundle install <packagename>
At the point in time that you reach this gist, you should have all of them installed.
These steps are derived from a RubyDoc Article. AuthLogic requires a controller to be called against.
require 'spec_helper'
require 'rspec/rails'
require 'factory_girl'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# Load Capybara
require 'capybara/rspec'
# Load AuthLogic
require 'authlogic/test_case'
config.include Authlogic::TestCase
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
end
The spec tests require several modules (like factory_girl and of course AuthLogic). The important lines here are the two which load AuthLogic. There are other places where you can load the library, but this worked for me.
Add these includes to the top of the tile:
require 'spec_helper'
require 'rails_helper'
rails_helper
includes AuthLogic, which becomes available here. Next, before your block of tests you must activate AuthLogic:
it 'While authenticated do' do
setup :activate_authlogic
# Tests with authentication go here.
end
AuthLogic should work at this point. It won't do anything, but it should work.
This took me too long to figure out because
- most AuthLogic test documentation was written with
Test::Unit
in mind; - test specs used Cucumber instead of RSpec;
- peak use of AuthLogic was about five years ago-tutorials lag a few versions behind the latest Rails;
- and some tutorials are plain bad.
"WTF?!" you wonder. I mean, all the tutorials tell you to do it like that. This is a good enough method for a controller or model tels, but for a feature test, for an AuthLogic session to work, there must exist:
- A user record in the database. Not in memory, or anywhere else.
User.create(foobar)
will add a user to the database.FactoryGirl.create(:user)
will add a user to the database.FactoryGirl.build(:user)
will not add a user to the database.
- A session cookie in the browser.
UserSession.create(user)
creates a session on the server. It does not add a cookie to the browser.- When Capybara loads the page, AuthLogic checks the browser for a cookie.
- Since this cookie is not present, authentication fails and the fallback action is executed.
- There are two ways to create a cookie:
- Fill out the login form.
- Hand-generate a cookie after
UserSession.create(user)
.
Because RSpec tests are feature tests of the entire site, it is considered a Bad Idea to skip the login form. You can create cookies, but shouldn't. Instead you should write a method which fills out the login form for you, and then call your test as a yielded block:
def as_user(user)
log_in_as user
yield
log_out
end
...
it 'should have a pony banner' do
as_user(pony_lover) do
visit '/ponies'
expect(page).to have_content 'WE ALL LOVE MAGIC PONIES'
end
end