Commit f30baf85a361a5bc424ce259784a9f5755364854

Authored by Dan Croak
1 parent 67628f5f

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

app/controllers/application_controller.rb
1 1 class ApplicationController < ActionController::Base
  2 + include Clearance::Authentication
2 3  
3 4 helper :all
4 5  
... ...
app/models/user.rb 0 → 100644
... ... @@ -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   -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 @@
  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   -# 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 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 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 10 end
... ...
db/migrate/20090701195337_clearance_create_users.rb 0 → 100644
... ... @@ -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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 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 2 def path_to(page_name)
9 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 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 18 end
24 19 end
25 20 end
... ...
test/factories/clearance.rb 0 → 100644
... ... @@ -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