Commit f30baf85a361a5bc424ce259784a9f5755364854

Authored by Dan Croak
1 parent 67628f5f

added clearance, including cucumber features. removed test/mocks.

app/controllers/application_controller.rb
1 class ApplicationController < ActionController::Base 1 class ApplicationController < ActionController::Base
  2 + include Clearance::Authentication
2 3
3 helper :all 4 helper :all
4 5
app/models/user.rb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +class User < ActiveRecord::Base
  2 + include Clearance::User
  3 +end
config/initializers/action_mailer_configs.rb
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
1 -ActionMailer::Base.smtp_settings = {  
2 - :address => "smtp.thoughtbot.com",  
3 - :port => 25,  
4 - :domain => "thoughtbot.com"  
5 -}  
6 -  
config/initializers/mail.rb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +ActionMailer::Base.smtp_settings = {
  2 + :address => "smtp.thoughtbot.com",
  3 + :port => 25,
  4 + :domain => "thoughtbot.com"
  5 +}
  6 +
  7 +DO_NOT_REPLY = "donotreply@example.com"
  8 +
config/initializers/mocks.rb
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -# Rails 2 doesn't like mocks  
2 -  
3 -# This callback will run before every request to a mock in development mode,  
4 -# or before the first server request in production.  
5 -  
6 -Rails.configuration.to_prepare do  
7 - Dir[File.join(RAILS_ROOT, 'test', 'mocks', RAILS_ENV, '*.rb')].each do |f|  
8 - load f  
9 - end  
10 -end  
config/routes.rb
1 ActionController::Routing::Routes.draw do |map| 1 ActionController::Routing::Routes.draw do |map|
2 2
3 - # Sample resource route (maps HTTP verbs to controller actions automatically):  
4 - # map.resources :products  
5 -  
6 - # Sample resource route with options:  
7 - # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }  
8 -  
9 - # Sample resource route with sub-resources:  
10 - # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller  
11 -  
12 - # Sample resource route within a namespace:  
13 - # map.namespace :admin do |admin|  
14 - # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)  
15 - # admin.resources :products  
16 - # end  
17 -  
18 - # You can have the root of your site routed with map.root -- just remember to delete public/index.html.  
19 - # map.root :controller => "welcome" 3 + map.root :controller => "clearance/users", :action => "new"
20 4
21 # See how all your routes lay out with "rake routes" 5 # See how all your routes lay out with "rake routes"
22 6
23 - # map.home '', :controller => 'home', :action => 'dashboard'  
24 - # map.with_options :controller => 'sessions' do |m|  
25 - # m.login '/login', :action => 'new'  
26 - # m.logout '/logout', :action => 'destroy'  
27 - # end 7 + # For more information on routes, read:
  8 + # http://guides.rubyonrails.org/routing.html
28 9
29 end 10 end
db/migrate/20090701195337_clearance_create_users.rb 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +class ClearanceCreateUsers < ActiveRecord::Migration
  2 + def self.up
  3 + create_table(:users) do |t|
  4 + t.string :email
  5 + t.string :encrypted_password, :limit => 128
  6 + t.string :salt, :limit => 128
  7 + t.string :token, :limit => 128
  8 + t.datetime :token_expires_at
  9 + t.boolean :email_confirmed, :default => false, :null => false
  10 + end
  11 +
  12 + add_index :users, [:id, :token]
  13 + add_index :users, :email
  14 + add_index :users, :token
  15 + end
  16 +
  17 + def self.down
  18 + drop_table :users
  19 + end
  20 +end
features/password_reset.feature 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +Feature: Password reset
  2 + In order to sign in even if user forgot their password
  3 + A user
  4 + Should be able to reset it
  5 +
  6 + Scenario: User is not signed up
  7 + Given no user exists with an email of "email@person.com"
  8 + When I request password reset link to be sent to "email@person.com"
  9 + Then I should see "Unknown email"
  10 +
  11 + Scenario: User is signed up and requests password reset
  12 + Given I signed up with "email@person.com/password"
  13 + When I request password reset link to be sent to "email@person.com"
  14 + Then I should see "instructions for changing your password"
  15 + And a password reset message should be sent to "email@person.com"
  16 +
  17 + Scenario: User is signed up updated his password and types wrong confirmation
  18 + Given I signed up with "email@person.com/password"
  19 + When I follow the password reset link sent to "email@person.com"
  20 + And I update my password with "newpassword/wrongconfirmation"
  21 + Then I should see error messages
  22 + And I should be signed out
  23 +
  24 + Scenario: User is signed up and updates his password
  25 + Given I signed up with "email@person.com/password"
  26 + When I follow the password reset link sent to "email@person.com"
  27 + And I update my password with "newpassword/newpassword"
  28 + Then I should be signed in
  29 + When I sign out
  30 + Then I should be signed out
  31 + And I sign in as "email@person.com/newpassword"
  32 + Then I should be signed in
  33 +
features/sign_in.feature 0 → 100644
@@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
  1 +Feature: Sign in
  2 + In order to get access to protected sections of the site
  3 + A user
  4 + Should be able to sign in
  5 +
  6 + Scenario: User is not signed up
  7 + Given no user exists with an email of "email@person.com"
  8 + When I go to the sign in page
  9 + And I sign in as "email@person.com/password"
  10 + Then I should see "Bad email or password"
  11 + And I should be signed out
  12 +
  13 + Scenario: User is not confirmed
  14 + Given I signed up with "email@person.com/password"
  15 + When I go to the sign in page
  16 + And I sign in as "email@person.com/password"
  17 + Then I should see "User has not confirmed email"
  18 + And I should be signed out
  19 +
  20 + Scenario: User enters wrong password
  21 + Given I am signed up and confirmed as "email@person.com/password"
  22 + When I go to the sign in page
  23 + And I sign in as "email@person.com/wrongpassword"
  24 + Then I should see "Bad email or password"
  25 + And I should be signed out
  26 +
  27 + Scenario: User signs in successfully
  28 + Given I am signed up and confirmed as "email@person.com/password"
  29 + When I go to the sign in page
  30 + And I sign in as "email@person.com/password"
  31 + Then I should see "Signed in"
  32 + And I should be signed in
  33 +
  34 + Scenario: User signs in and checks "remember me"
  35 + Given I am signed up and confirmed as "email@person.com/password"
  36 + When I go to the sign in page
  37 + And I sign in with "remember me" as "email@person.com/password"
  38 + Then I should see "Signed in"
  39 + And I should be signed in
  40 + When I return next time
  41 + Then I should be signed in
  42 +
features/sign_out.feature 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +Feature: Sign out
  2 + To protect my account from unauthorized access
  3 + A signed in user
  4 + Should be able to sign out
  5 +
  6 + Scenario: User signs out
  7 + Given I am signed up and confirmed as "email@person.com/password"
  8 + When I sign in as "email@person.com/password"
  9 + Then I should be signed in
  10 + And I sign out
  11 + Then I should see "Signed out"
  12 + And I should be signed out
  13 +
  14 + Scenario: User who was remembered signs out
  15 + Given I am signed up and confirmed as "email@person.com/password"
  16 + When I sign in with "remember me" as "email@person.com/password"
  17 + Then I should be signed in
  18 + And I sign out
  19 + Then I should see "Signed out"
  20 + And I should be signed out
  21 + When I return next time
  22 + Then I should be signed out
  23 +
features/sign_up.feature 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +Feature: Sign up
  2 + In order to get access to protected sections of the site
  3 + A user
  4 + Should be able to sign up
  5 +
  6 + Scenario: User signs up with invalid data
  7 + When I go to the sign up page
  8 + And I fill in "Email" with "invalidemail"
  9 + And I fill in "Password" with "password"
  10 + And I fill in "Confirm password" with ""
  11 + And I press "Sign Up"
  12 + Then I should see error messages
  13 +
  14 + Scenario: User signs up with valid data
  15 + When I go to the sign up page
  16 + And I fill in "Email" with "email@person.com"
  17 + And I fill in "Password" with "password"
  18 + And I fill in "Confirm password" with "password"
  19 + And I press "Sign Up"
  20 + Then I should see "instructions for confirming"
  21 + And a confirmation message should be sent to "email@person.com"
  22 +
  23 + Scenario: User confirms his account
  24 + Given I signed up with "email@person.com/password"
  25 + When I follow the confirmation link sent to "email@person.com"
  26 + Then I should see "Confirmed email and signed in"
  27 + And I should be signed in
  28 +
features/step_definitions/clearance_steps.rb 0 → 100644
@@ -0,0 +1,110 @@ @@ -0,0 +1,110 @@
  1 +# General
  2 +
  3 +Then /^I should see error messages$/ do
  4 + assert_match /error(s)? prohibited/m, response.body
  5 +end
  6 +
  7 +# Database
  8 +
  9 +Given /^no user exists with an email of "(.*)"$/ do |email|
  10 + assert_nil User.find_by_email(email)
  11 +end
  12 +
  13 +Given /^I signed up with "(.*)\/(.*)"$/ do |email, password|
  14 + user = Factory :user,
  15 + :email => email,
  16 + :password => password,
  17 + :password_confirmation => password
  18 +end
  19 +
  20 +Given /^I am signed up and confirmed as "(.*)\/(.*)"$/ do |email, password|
  21 + user = Factory :email_confirmed_user,
  22 + :email => email,
  23 + :password => password,
  24 + :password_confirmation => password
  25 +end
  26 +
  27 +# Session
  28 +
  29 +Then /^I should be signed in$/ do
  30 + assert controller.signed_in?
  31 +end
  32 +
  33 +Then /^I should be signed out$/ do
  34 + assert ! controller.signed_in?
  35 +end
  36 +
  37 +When /^session is cleared$/ do
  38 + request.reset_session
  39 + controller.instance_variable_set(:@_current_user, nil)
  40 +end
  41 +
  42 +# Emails
  43 +
  44 +Then /^a confirmation message should be sent to "(.*)"$/ do |email|
  45 + user = User.find_by_email(email)
  46 + sent = ActionMailer::Base.deliveries.first
  47 + assert_equal [user.email], sent.to
  48 + assert_match /confirm/i, sent.subject
  49 + assert !user.token.blank?
  50 + assert_match /#{user.token}/, sent.body
  51 +end
  52 +
  53 +When /^I follow the confirmation link sent to "(.*)"$/ do |email|
  54 + user = User.find_by_email(email)
  55 + visit new_user_confirmation_path(:user_id => user, :token => user.token)
  56 +end
  57 +
  58 +Then /^a password reset message should be sent to "(.*)"$/ do |email|
  59 + user = User.find_by_email(email)
  60 + sent = ActionMailer::Base.deliveries.first
  61 + assert_equal [user.email], sent.to
  62 + assert_match /password/i, sent.subject
  63 + assert !user.token.blank?
  64 + assert_match /#{user.token}/, sent.body
  65 +end
  66 +
  67 +When /^I follow the password reset link sent to "(.*)"$/ do |email|
  68 + user = User.find_by_email(email)
  69 + visit edit_user_password_path(:user_id => user, :token => user.token)
  70 +end
  71 +
  72 +When /^I try to change the password of "(.*)" without token$/ do |email|
  73 + user = User.find_by_email(email)
  74 + visit edit_user_password_path(:user_id => user)
  75 +end
  76 +
  77 +Then /^I should be forbidden$/ do
  78 + assert_response :forbidden
  79 +end
  80 +
  81 +# Actions
  82 +
  83 +When /^I sign in( with "remember me")? as "(.*)\/(.*)"$/ do |remember, email, password|
  84 + When %{I go to the sign in page}
  85 + And %{I fill in "Email" with "#{email}"}
  86 + And %{I fill in "Password" with "#{password}"}
  87 + And %{I check "Remember me"} if remember
  88 + And %{I press "Sign In"}
  89 +end
  90 +
  91 +When /^I sign out$/ do
  92 + visit '/session', :delete
  93 +end
  94 +
  95 +When /^I request password reset link to be sent to "(.*)"$/ do |email|
  96 + When %{I go to the password reset request page}
  97 + And %{I fill in "Email address" with "#{email}"}
  98 + And %{I press "Reset password"}
  99 +end
  100 +
  101 +When /^I update my password with "(.*)\/(.*)"$/ do |password, confirmation|
  102 + And %{I fill in "Choose password" with "#{password}"}
  103 + And %{I fill in "Confirm password" with "#{confirmation}"}
  104 + And %{I press "Save this password"}
  105 +end
  106 +
  107 +When /^I return next time$/ do
  108 + When %{session is cleared}
  109 + And %{I go to the homepage}
  110 +end
features/step_definitions/factory_girl_steps.rb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +Factory.factories.each do |name, factory|
  2 + Given /^an? #{name} exists with an? (.*) of "([^"]*)"$/ do |attr, value|
  3 + Factory(name, attr.gsub(' ', '_') => value)
  4 + end
  5 +end
features/support/paths.rb
1 module NavigationHelpers 1 module NavigationHelpers
2 - # Maps a name to a path. Used by the  
3 - #  
4 - # When /^I go to (.+)$/ do |page_name|  
5 - #  
6 - # step definition in webrat_steps.rb  
7 - #  
8 def path_to(page_name) 2 def path_to(page_name)
9 case page_name 3 case page_name
10 -  
11 - when /the homepage/  
12 - '/'  
13 -  
14 - # Add more mappings here.  
15 - # Here is a more fancy example:  
16 - #  
17 - # when /^(.*)'s profile page$/i  
18 - # user_profile_path(User.find_by_login($1)) 4 +
  5 + when /the homepage/i
  6 + root_path
  7 + when /the sign up page/i
  8 + new_user_path
  9 + when /the sign in page/i
  10 + new_session_path
  11 + when /the password reset request page/i
  12 + new_password_path
  13 +
  14 + # Add more page name => path mappings here
19 15
20 else 16 else
21 - raise "Can't find mapping from \"#{page_name}\" to a path.\n" +  
22 - "Now, go and add a mapping in #{__FILE__}" 17 + raise "Can't find mapping from \"#{page_name}\" to a path."
23 end 18 end
24 end 19 end
25 end 20 end
test/factories/clearance.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +Factory.sequence :email do |n|
  2 + "user#{n}@example.com"
  3 +end
  4 +
  5 +Factory.define :user do |user|
  6 + user.email { Factory.next :email }
  7 + user.password { "password" }
  8 + user.password_confirmation { "password" }
  9 +end
  10 +
  11 +Factory.define :email_confirmed_user, :parent => :user do |user|
  12 + user.email_confirmed { true }
  13 +end
test/mocks/development/.keep
test/mocks/test/.keep