Commit 588faac9c8f84b6b874cd4b004dbe5712563eff6

Authored by Dan Croak
1 parent 384ed39e

adding a cucumber db to database.yml. unpacking clearance as a plugin. convertin…

…g webrat steps to use test::unit assertions instead of rspec matchers.
Showing 48 changed files with 1817 additions and 25 deletions   Show diff stats
config/database.yml
1 1 # SQLite version 3.x
2 2 # gem install sqlite3-ruby (not necessary on OS X Leopard)
3   -development:
  3 +development: &default
4 4 adapter: sqlite3
5 5 database: db/development.sqlite3
6 6 pool: 5
7 7 timeout: 5000
8 8  
9   -# Warning: The database defined as "test" will be erased and
10   -# re-generated from your development database when you run "rake".
11   -# Do not set this db to the same as development or production.
12 9 test:
13   - adapter: sqlite3
  10 + <<: *default
14 11 database: db/test.sqlite3
15   - pool: 5
16   - timeout: 5000
17 12  
18   -production:
19   - adapter: sqlite3
20   - database: db/production.sqlite3
21   - pool: 5
22   - timeout: 5000
  13 +cucumber:
  14 + <<: *default
  15 + database: db/cucumber.sqlite3
23 16  
... ...
config/environments/cucumber.rb
... ... @@ -15,7 +15,13 @@ config.action_controller.allow_forgery_protection = false
15 15 # ActionMailer::Base.deliveries array.
16 16 config.action_mailer.delivery_method = :test
17 17  
18   -config.gem "cucumber", :lib => false, :version => ">=0.3.11" unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber'))
19   -config.gem "webrat", :lib => false, :version => ">=0.4.4" unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
20   -config.gem "rspec", :lib => false, :version => ">=1.2.6" unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
21   -config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6" unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
  18 +config.gem "cucumber", :lib => false, :version => ">=0.3.11"
  19 +config.gem "webrat", :lib => false, :version => ">=0.4.4"
  20 +
  21 +# config.gem "rspec", :lib => false, :version => ">=1.2.6"
  22 +# config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6"
  23 +
  24 +require 'rubygems'
  25 +require 'factory_girl'
  26 +require 'shoulda'
  27 +
... ...
features/step_definitions/webrat_steps.rb
... ... @@ -91,29 +91,37 @@ When /^I attach the file at &quot;([^\&quot;]*)&quot; to &quot;([^\&quot;]*)&quot;$/ do |path, field|
91 91 end
92 92  
93 93 Then /^I should see "([^\"]*)"$/ do |text|
94   - response.should contain(text)
  94 + # response.should contain(text)
  95 + assert_match /#{text}/m, @response.body
95 96 end
96 97  
97 98 Then /^I should not see "([^\"]*)"$/ do |text|
98   - response.should_not contain(text)
  99 + # response.should_not contain(text)
  100 + assert_no_match /#{text}/m, @response.body
99 101 end
100 102  
101 103 Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
102   - field_labeled(field).value.should =~ /#{value}/
  104 + # field_labeled(field).value.should =~ /#{value}/
  105 + assert_match /#{value}/, field_labeled(field).value
103 106 end
104 107  
105 108 Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
106   - field_labeled(field).value.should_not =~ /#{value}/
  109 + # field_labeled(field).value.should_not =~ /#{value}/
  110 + assert_no_match /#{value}/, field_labeled(field).value
107 111 end
108   -
  112 +
109 113 Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
110   - field_labeled(label).should be_checked
  114 + # field_labeled(label).should be_checked
  115 + assert field_labeled(label).checked?
111 116 end
112 117  
113 118 Then /^the "([^\"]*)" checkbox should not be checked$/ do |label|
114   - field_labeled(label).should_not be_checked
  119 + # field_labeled(label).should_not be_checked
  120 + assert !field_labeled(label).checked?
115 121 end
116 122  
117 123 Then /^I should be on (.+)$/ do |page_name|
118   - URI.parse(current_url).path.should == path_to(page_name)
  124 + # URI.parse(current_url).path.should == path_to(page_name)
  125 + assert_equal path_to(page_name), URI.parse(current_url).path
119 126 end
  127 +
... ...
features/support/env.rb
... ... @@ -20,5 +20,5 @@ Webrat.configure do |config|
20 20 config.mode = :rails
21 21 end
22 22  
23   -require 'cucumber/rails/rspec'
  23 +# require 'cucumber/rails/rspec'
24 24 require 'webrat/core/matchers'
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/CHANGELOG.textile 0 → 100644
... ... @@ -0,0 +1,162 @@
  1 +h2. 0.6.8 (06/24/2009)
  2 +
  3 +* Added defined? checks for various Rails constants such as ActionController
  4 +for easier unit testing of Clearance extensions... particularly ActiveRecord
  5 +extensions... particularly strong_password. (Dan Croak)
  6 +
  7 +h2. 0.6.7 (06/13/2009)
  8 +
  9 +* [#30] Added sign_up, sign_in, sign_out named routes. (Dan Croak)
  10 +* [#22] Minimizing Reek smell: Duplication in redirect_back_or. (Dan Croak)
  11 +* Deprecated sign_user_in. Told developers to use sign_in instead. (Dan
  12 +Croak)
  13 +* [#16] flash_success_after_create, flash_notice_after_create, flash_failure_after_create, flash_sucess_after_update, flash_success_after_destroy, etc. (Dan Croak)
  14 +* [#17] bug. added #create to forbidden before_filters on confirmations controller. (Dan Croak)
  15 +* [#24] should_be_signed_in_as shouldn't look in the session. (Dan Croak)
  16 +* README improvements. (Dan Croak)
  17 +* Move routes loading to separate file. (Joshua Clayton)
  18 +
  19 +h2. 0.6.6 (05/18/2009)
  20 +
  21 +* [#14] replaced class_eval in Clearance::User with modules. This was needed
  22 +in a thoughtbot client app so we could write our own validations. (Dan Croak)
  23 +
  24 +h2. 0.6.5 (05/17/2009)
  25 +
  26 +* [#6] Make Clearance i18n aware. (Timur Vafin, Marcel Goerner, Eugene Bolshakov, Dan Croak)
  27 +
  28 +h2. 0.6.4 (05/12/2009)
  29 +
  30 +* Moved issue tracking to Github from Lighthouse. (Dan Croak)
  31 +* [#7] asking higher-level questions of controllers in webrat steps, such as signed_in? instead of what's in the session. same for accessors. (Dan Croak)
  32 +* [#11] replacing sign_in_as & sign_out shoulda macros with a stubbing (requires no dependency) approach. this will avoid dealing with the internals of current_user, such as session & cookies. added sign_in macro which signs in an email confirmed user from clearance's factories. (Dan Croak)
  33 +* [#13] move private methods on sessions controller into Clearance::Authentication module (Dan Croak)
  34 +* [#9] audited flash keys. (Dan Croak)
  35 +
  36 +h2. 0.6.3 (04/23/2009)
  37 +
  38 +* Scoping ClearanceMailer properly within controllers so it works in production environments. (Nick Quaranto)
  39 +
  40 +h2. 0.6.2 (04/22/2009)
  41 +
  42 +* Insert Clearance::User into User model if it exists. (Nick Quaranto)
  43 +* World(NavigationHelpers) Cucumber 3.0 style. (Shay Arnett & Mark Cornick)
  44 +
  45 +h2. 0.6.1 (04/21/2009)
  46 +* Scope operators are necessary to keep Rails happy. Reverting the original
  47 +revert so they're back in the library now for constants referenced inside of
  48 +the gem. (Nick Quaranto)
  49 +
  50 +h2. 0.6.0 (04/21/2009)
  51 +
  52 +* Converted Clearance to a Rails engine. (Dan Croak & Joe Ferris)
  53 +* Include Clearance::User in User model in app. (Dan Croak & Joe Ferris)
  54 +* Include Clearance::Authentication in ApplicationController. (Dan Croak & Joe Ferris)
  55 +* Namespace controllers under Clearance. (Dan Croak & Joe Ferris)
  56 +* Routes move to engine, use namespaced controllers but publicly the same. (Dan Croak & Joe Ferris)
  57 +* If you want to override a controller, subclass it like SessionsController <
  58 +Clearance::SessionsController. This gives you access to usual hooks such as
  59 +url_after_create. (Dan Croak & Joe Ferris)
  60 +* Controllers, mailer, model, routes all unit tested inside engine. Use
  61 +script/generate clearance_features to test integration of Clearance with your
  62 +Rails app. No longer including modules in your app's test files. (Dan Croak & Joe Ferris)
  63 +* Moved views to engine. (Joe Ferris)
  64 +* Converted generated test/factories/clearance.rb to use inheritence for
  65 +email_confirmed_user. (Dan Croak)
  66 +* Corrected some spelling errors with methods (Nick Quaranto)
  67 +* Converted "I should see error messages" to use a regex in the features (Nick
  68 +Quaranto)
  69 +* Loading clearance routes after rails routes via some monkeypatching (Nick
  70 +Quaranto)
  71 +* Made the clearance controllers unloadable to stop constant loading errors in
  72 +development mode (Nick Quaranto)
  73 +
  74 +h2. 0.5.6 (4/11/2009)
  75 +
  76 +* [#57] Step definition changed for "User should see error messages" so
  77 +features won't fail for certain validations. (Nick Quaranto)
  78 +
  79 +h2. 0.5.5 (3/23/2009)
  80 +
  81 +* Removing duplicate test to get rid of warning. (Nick Quaranto)
  82 +
  83 +h2. 0.5.4 (3/21/2009)
  84 +
  85 +* When users fail logging in, redirect them instead of rendering. (Matt
  86 +Jankowski)
  87 +
  88 +h2. 0.5.3 (3/5/2009)
  89 +
  90 +* Clearance now works with (and requires) Shoulda 2.10.0. (Mark Cornick, Joe
  91 +Ferris, Dan Croak)
  92 +* Prefer flat over nested contexts in sessions_controller_test. (Joe Ferris,
  93 +Dan Croak)
  94 +
  95 +h2. 0.5.2 (3/2/2009)
  96 +
  97 +* Fixed last remaining errors in Rails 2.3 tests. Now fully compatible. (Joe
  98 +Ferris, Dan Croak)
  99 +
  100 +h2. 0.5.1 (2/27/2009)
  101 +
  102 +* [#46] A user with unconfirmed email who resets password now confirms email.
  103 +(Marcel Görner)
  104 +* Refactored user_from_cookie, user_from_session, User#authenticate to use
  105 +more direct return code instead of ugly, harder to read ternary. (Dan Croak)
  106 +* Switch order of cookies and sessions to take advantage of Rails 2.3's "Rack-based lazy-loaded sessions":http://is.gd/i23E. (Dan Croak)
  107 +* Altered generator to interact with application_controller.rb instead of
  108 +application.rb in Rails 2.3 apps. (Dan Croak)
  109 +* [#42] Bug fix. Rack-based session change altered how to test remember me
  110 +cookie. (Mihai Anca)
  111 +
  112 +h2. 0.5.0 (2/27/2009)
  113 +
  114 +* Fixed problem with Cucumber features. (Dan Croak)
  115 +* Fixed mising HTTP fluency use case. (Dan Croak)
  116 +* Refactored User#update_password to take just parameters it needs. (Dan
  117 +Croak)
  118 +* Refactored User unit tests to be more readable. (Dan Croak)
  119 +
  120 +h2. 0.4.9 (2/20/2009)
  121 +
  122 +* Protect passwords & confirmations actions with forbidden filters. (Dan Croak)
  123 +* Return 403 Forbidden status code in those cases. (Tim Pope)
  124 +* Test 403 Forbidden status code in Cucumber feature. (Dan Croak, Joe Ferris)
  125 +* Raise custom ActionController::Forbidden error internally. (Joe Ferris, Mike Burns, Jason Morrison)
  126 +* Test ActionController::Forbidden error is raised in functional test. (Joe Ferris, Mike Burns, Dan Croak)
  127 +* [#45] Fixed bug that allowed anyone to edit another user's password (Marcel Görner)
  128 +* Required Factory Girl >= 1.2.0. (Dan Croak)
  129 +
  130 +h2. 0.4.8 (2/16/2009)
  131 +
  132 +* Added support paths for Cucumber. (Ben Mabey)
  133 +* Added documentation for the flash. (Ben Mabey)
  134 +* Generators require "test_helper" instead of File.join. for rr compatibility. (Joe Ferris)
  135 +* Removed interpolated email address from flash message to make i18n easier. (Bence Nagy)
  136 +* Standardized flash messages that refer to email delivery. (Dan Croak)
  137 +
  138 +h2. 0.4.7 (2/12/2009)
  139 +
  140 +* Removed Clearance::Test::TestHelper so there is one less setup step. (Dan Croak)
  141 +* All test helpers now in shoulda_macros. (Dan Croak)
  142 +
  143 +h2. 0.4.6 (2/11/2009)
  144 +
  145 +* Made the modules behave like mixins again. (hat-tip Eloy Duran)
  146 +* Created Actions and PrivateMethods modules on controllers for future RDoc reasons. (Dan Croak, Joe Ferris)
  147 +
  148 +h2. 0.4.5 (2/9/2009)
  149 +
  150 +* [#43] Removed email downcasing because local-part is case sensitive per RFC5321. (Dan Croak)
  151 +* [#42] Removed dependency on Mocha. (Dan Croak)
  152 +* Required Shoulda >= 2.9.1. (Dan Croak)
  153 +* Added password reset feature to clearance_features generator. (Eugene Bolshakov, Dan Croak)
  154 +* Removed unnecessary session[:salt]. (Dan Croak)
  155 +* [#41] Only store location for session[:return_to] for GET requests. (Dan Croak)
  156 +* Audited "sign up" naming convention. "Register" had slipped in a few places. (Dan Croak)
  157 +* Switched to SHA1 encryption. Cypher doesn't matter much for email confirmation, password reset. Better to have shorter hashes in the emails for clients who line break on 72 chars. (Dan Croak)
  158 +
  159 +h2. 0.4.4 (2/2/2009)
  160 +
  161 +* Added a generator for Cucumber features. (Joe Ferris, Dan Croak)
  162 +* Standarized naming for "Sign up," "Sign in," and "Sign out". (Dan Croak)
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/LICENSE 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +The MIT License
  2 +
  3 +Copyright (c) 2008 thoughtbot, inc.
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in
  13 +all copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21 +THE SOFTWARE.
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/README.textile 0 → 100644
... ... @@ -0,0 +1,123 @@
  1 +h1. Clearance
  2 +
  3 +Rails authentication with email & password.
  4 +
  5 +"We have clearance, Clarence.":http://www.youtube.com/v/mNRXJEE3Nz8
  6 +
  7 +h2. Wiki
  8 +
  9 +Most information regarding Clearance is on the "Github Wiki":http://wiki.github.com/thoughtbot/clearance.
  10 +
  11 +h2. Installation
  12 +
  13 +Clearance is a Rails engine. It works with versions of Rails greater than 2.3.
  14 +
  15 +In config/environment.rb:
  16 +
  17 +<pre>
  18 +config.gem "thoughtbot-clearance",
  19 + :lib => 'clearance',
  20 + :source => 'http://gems.github.com',
  21 + :version => '0.6.6'
  22 +</pre>
  23 +
  24 +Vendor the gem:
  25 +
  26 +<pre>
  27 +rake gems:install
  28 +rake gems:unpack
  29 +</pre>
  30 +
  31 +Make sure the development database exists and run the generator:
  32 +
  33 +@script/generate clearance@
  34 +
  35 +A number of files will be created and instructions will be printed.
  36 +
  37 +You may already have some of these files. Don't worry. You'll be asked if you want to overwrite them.
  38 +
  39 +Run the migration:
  40 +
  41 +@rake db:migrate@
  42 +
  43 +Define a HOST constant in your environment files.
  44 +In config/environments/test.rb and config/environments/development.rb it can be:
  45 +
  46 +@HOST = "localhost"@
  47 +
  48 +In production.rb it must be the actual host your application is deployed to.
  49 +The constant is used by mailers to generate URLs in emails.
  50 +
  51 +In config/environment.rb:
  52 +
  53 +@DO_NOT_REPLY = "donotreply@example.com"@
  54 +
  55 +Define root_url to *something* in your config/routes.rb:
  56 +
  57 +@map.root :controller => 'home'@
  58 +
  59 +h2. Cucumber Features
  60 +
  61 +As your app evolves, you want to know that authentication still works. Clearance's opinion is that you should test its integration with your app using "Cucumber":http://cukes.info/.
  62 +
  63 +In config/environments/test.rb:
  64 +
  65 +<pre>
  66 +config.gem 'webrat',
  67 + :version => '= 0.4.4'
  68 +config.gem 'cucumber',
  69 + :version => '= 0.3.0'
  70 +config.gem 'thoughtbot-factory_girl',
  71 + :lib => 'factory_girl',
  72 + :source => "http://gems.github.com",
  73 + :version => '1.2.1'
  74 +</pre>
  75 +
  76 +Vendor the gems:
  77 +
  78 +<pre>
  79 +rake gems:install RAILS_ENV=test
  80 +rake gems:unpack RAILS_ENV=test
  81 +</pre>
  82 +
  83 +We don't vendor nokogiri due to its native extensions, so install it normally on your machine:
  84 +
  85 +@sudo gem install nokogiri@
  86 +
  87 +Run the Cucumber generator (if you haven't already) and Clearance's feature generator:
  88 +
  89 +<pre>
  90 +script/generate cucumber
  91 +script/generate clearance_features
  92 +</pre>
  93 +
  94 +All of the files generated should be new with the exception of the features/support/paths.rb file. If you have not modified your paths.rb then you will be okay to replace it with this one. If you need to keep your paths.rb file then add these locations in your paths.rb manually:
  95 +
  96 +<pre>
  97 +def path_to(page_name)
  98 + case page_name
  99 + ...
  100 + when /the sign up page/i
  101 + new_user_path
  102 + when /the sign in page/i
  103 + new_session_path
  104 + when /the password reset request page/i
  105 + new_password_path
  106 + ...
  107 +end
  108 +</pre>
  109 +
  110 +h2. Authors
  111 +
  112 +Clearance was extracted out of "Hoptoad":http://hoptoadapp.com. We merged the authentication code from two of thoughtbot's clients' Rails apps and have since used it each time we need authentication. The following people have improved the library. Thank you!
  113 +
  114 +Dan Croak, Mike Burns, Jason Morrison, Joe Ferris, Eugene Bolshakov, Nick Quaranto, Josh Nichols, Mike Breen, Marcel Görner, Bence Nagy, Ben Mabey, Eloy Duran, Tim Pope, Mihai Anca, Mark Cornick, Shay Arnett, Joshua Clayton & Mustafa Ekim.
  115 +
  116 +h2. Questions?
  117 +
  118 +Ask the "mailing list":http://groups.google.com/group/thoughtbot-clearance
  119 +
  120 +h2. Suggestions, Bugs, Refactoring?
  121 +
  122 +Fork away and create a "Github Issue":http://github.com/thoughtbot/clearance/issues. Please don't send pull requests.
  123 +
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/Rakefile 0 → 100644
... ... @@ -0,0 +1,76 @@
  1 +# encoding: utf-8
  2 +
  3 +require 'rake'
  4 +require 'rake/testtask'
  5 +require 'cucumber/rake/task'
  6 +
  7 +namespace :test do
  8 + Rake::TestTask.new(:all => ["generator:cleanup",
  9 + "generator:generate"]) do |task|
  10 + task.libs << "lib"
  11 + task.libs << "test"
  12 + task.pattern = "test/**/*_test.rb"
  13 + task.verbose = false
  14 + end
  15 +
  16 + Cucumber::Rake::Task.new(:features) do |t|
  17 + t.cucumber_opts = "--format progress"
  18 + t.feature_pattern = "test/rails_root/features/*.feature"
  19 + end
  20 +end
  21 +
  22 +generators = %w(clearance clearance_features)
  23 +
  24 +namespace :generator do
  25 + desc "Cleans up the test app before running the generator"
  26 + task :cleanup do
  27 + generators.each do |generator|
  28 + FileList["generators/#{generator}/templates/**/*.*"].each do |each|
  29 + file = "test/rails_root/#{each.gsub("generators/#{generator}/templates/",'')}"
  30 + File.delete(file) if File.exists?(file)
  31 + end
  32 + end
  33 +
  34 + FileList["test/rails_root/db/**/*"].each do |each|
  35 + FileUtils.rm_rf(each)
  36 + end
  37 + FileUtils.rm_rf("test/rails_root/vendor/plugins/clearance")
  38 + FileUtils.mkdir_p("test/rails_root/vendor/plugins")
  39 + clearance_root = File.expand_path(File.dirname(__FILE__))
  40 + system("ln -s #{clearance_root} test/rails_root/vendor/plugins/clearance")
  41 + end
  42 +
  43 + desc "Run the generator on the tests"
  44 + task :generate do
  45 + generators.each do |generator|
  46 + system "cd test/rails_root && ./script/generate #{generator} && rake db:migrate db:test:prepare"
  47 + end
  48 + end
  49 +end
  50 +
  51 +desc "Run the test suite"
  52 +task :default => ['test:all', 'test:features']
  53 +
  54 +gem_spec = Gem::Specification.new do |gem_spec|
  55 + gem_spec.name = "clearance"
  56 + gem_spec.version = "0.6.8"
  57 + gem_spec.summary = "Rails authentication with email & password."
  58 + gem_spec.email = "support@thoughtbot.com"
  59 + gem_spec.homepage = "http://github.com/thoughtbot/clearance"
  60 + gem_spec.description = "Rails authentication with email & password."
  61 + gem_spec.authors = ["Dan Croak", "Mike Burns", "Jason Morrison",
  62 + "Joe Ferris", "Eugene Bolshakov", "Nick Quaranto",
  63 + "Josh Nichols", "Mike Breen", "Marcel Görner",
  64 + "Bence Nagy", "Ben Mabey", "Eloy Duran",
  65 + "Tim Pope", "Mihai Anca", "Mark Cornick",
  66 + "Shay Arnett"]
  67 + gem_spec.files = FileList["[A-Z]*", "{app,config,generators,lib,shoulda_macros,rails}/**/*"]
  68 +end
  69 +
  70 +desc "Generate a gemspec file"
  71 +task :gemspec do
  72 + File.open("#{gem_spec.name}.gemspec", 'w') do |f|
  73 + f.write gem_spec.to_yaml
  74 + end
  75 +end
  76 +
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/TODO.textile 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +h1. To-do
  2 +
  3 +* Make insertion of Clearance::User into User model automatic from the generator.
  4 +* Change generated README to include instruction about running the migration.
  5 +* DO_NOT_REPLY, HOST refactoring.
  6 +
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/controllers/clearance/confirmations_controller.rb 0 → 100644
... ... @@ -0,0 +1,52 @@
  1 +class Clearance::ConfirmationsController < ApplicationController
  2 + unloadable
  3 +
  4 + before_filter :forbid_confirmed_user, :only => [:new, :create]
  5 + before_filter :forbid_missing_token, :only => [:new, :create]
  6 + before_filter :forbid_non_existent_user, :only => [:new, :create]
  7 + filter_parameter_logging :token
  8 +
  9 + def new
  10 + create
  11 + end
  12 +
  13 + def create
  14 + @user = ::User.find_by_id_and_token(params[:user_id], params[:token])
  15 + @user.confirm_email!
  16 +
  17 + sign_in(@user)
  18 + flash_success_after_create
  19 + redirect_to(url_after_create)
  20 + end
  21 +
  22 + private
  23 +
  24 + def forbid_confirmed_user
  25 + user = ::User.find_by_id(params[:user_id])
  26 + if user && user.email_confirmed?
  27 + raise ActionController::Forbidden, "confirmed user"
  28 + end
  29 + end
  30 +
  31 + def forbid_missing_token
  32 + if params[:token].blank?
  33 + raise ActionController::Forbidden, "missing token"
  34 + end
  35 + end
  36 +
  37 + def forbid_non_existent_user
  38 + unless ::User.find_by_id_and_token(params[:user_id], params[:token])
  39 + raise ActionController::Forbidden, "non-existent user"
  40 + end
  41 + end
  42 +
  43 + def flash_success_after_create
  44 + flash[:success] = translate(:confirmed_email,
  45 + :scope => [:clearance, :controllers, :confirmations],
  46 + :default => "Confirmed email and signed in.")
  47 + end
  48 +
  49 + def url_after_create
  50 + root_url
  51 + end
  52 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/controllers/clearance/passwords_controller.rb 0 → 100644
... ... @@ -0,0 +1,81 @@
  1 +class Clearance::PasswordsController < ApplicationController
  2 + unloadable
  3 +
  4 + before_filter :forbid_missing_token, :only => [:edit, :update]
  5 + before_filter :forbid_non_existent_user, :only => [:edit, :update]
  6 + filter_parameter_logging :password, :password_confirmation
  7 +
  8 + def new
  9 + render :template => 'passwords/new'
  10 + end
  11 +
  12 + def create
  13 + if user = ::User.find_by_email(params[:password][:email])
  14 + user.forgot_password!
  15 + ::ClearanceMailer.deliver_change_password user
  16 + flash_notice_after_create
  17 + redirect_to(url_after_create)
  18 + else
  19 + flash_failure_after_create
  20 + render :template => 'passwords/new'
  21 + end
  22 + end
  23 +
  24 + def edit
  25 + @user = ::User.find_by_id_and_token(params[:user_id], params[:token])
  26 + render :template => 'passwords/edit'
  27 + end
  28 +
  29 + def update
  30 + @user = ::User.find_by_id_and_token(params[:user_id], params[:token])
  31 +
  32 + if @user.update_password(params[:user][:password],
  33 + params[:user][:password_confirmation])
  34 + @user.confirm_email!
  35 + sign_in(@user)
  36 + flash_success_after_update
  37 + redirect_to(url_after_update)
  38 + else
  39 + render :template => 'passwords/edit'
  40 + end
  41 + end
  42 +
  43 + private
  44 +
  45 + def forbid_missing_token
  46 + if params[:token].blank?
  47 + raise ActionController::Forbidden, "missing token"
  48 + end
  49 + end
  50 +
  51 + def forbid_non_existent_user
  52 + unless ::User.find_by_id_and_token(params[:user_id], params[:token])
  53 + raise ActionController::Forbidden, "non-existent user"
  54 + end
  55 + end
  56 +
  57 + def flash_notice_after_create
  58 + flash[:notice] = translate(:deliver_change_password,
  59 + :scope => [:clearance, :controllers, :passwords],
  60 + :default => "You will receive an email within the next few minutes. " <<
  61 + "It contains instructions for changing your password.")
  62 + end
  63 +
  64 + def flash_failure_after_create
  65 + flash.now[:failure] = translate(:unknown_email,
  66 + :scope => [:clearance, :controllers, :passwords],
  67 + :default => "Unknown email.")
  68 + end
  69 +
  70 + def url_after_create
  71 + new_session_url
  72 + end
  73 +
  74 + def flash_success_after_update
  75 + flash[:success] = translate(:signed_in, :default => "Signed in.")
  76 + end
  77 +
  78 + def url_after_update
  79 + root_url
  80 + end
  81 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/controllers/clearance/sessions_controller.rb 0 → 100644
... ... @@ -0,0 +1,67 @@
  1 +class Clearance::SessionsController < ApplicationController
  2 + unloadable
  3 +
  4 + protect_from_forgery :except => :create
  5 + filter_parameter_logging :password
  6 +
  7 + def new
  8 + render :template => 'sessions/new'
  9 + end
  10 +
  11 + def create
  12 + @user = ::User.authenticate(params[:session][:email],
  13 + params[:session][:password])
  14 + if @user.nil?
  15 + flash_failure_after_create
  16 + render :template => 'sessions/new', :status => :unauthorized
  17 + else
  18 + if @user.email_confirmed?
  19 + sign_in(@user)
  20 + remember(@user) if remember?
  21 + flash_success_after_create
  22 + redirect_back_or(url_after_create)
  23 + else
  24 + ::ClearanceMailer.deliver_confirmation(@user)
  25 + flash_notice_after_create
  26 + redirect_to(new_session_url)
  27 + end
  28 + end
  29 + end
  30 +
  31 + def destroy
  32 + forget(current_user)
  33 + flash_success_after_destroy
  34 + redirect_to(url_after_destroy)
  35 + end
  36 +
  37 + private
  38 +
  39 + def flash_failure_after_create
  40 + flash.now[:failure] = translate(:bad_email_or_password,
  41 + :scope => [:clearance, :controllers, :sessions],
  42 + :default => "Bad email or password.")
  43 + end
  44 +
  45 + def flash_success_after_create
  46 + flash[:success] = translate(:signed_in, :default => "Signed in.")
  47 + end
  48 +
  49 + def flash_notice_after_create
  50 + flash[:notice] = translate(:unconfirmed_email,
  51 + :scope => [:clearance, :controllers, :sessions],
  52 + :default => "User has not confirmed email. " <<
  53 + "Confirmation email will be resent.")
  54 + end
  55 +
  56 + def url_after_create
  57 + root_url
  58 + end
  59 +
  60 + def flash_success_after_destroy
  61 + flash[:success] = translate(:signed_out, :default => "Signed out.")
  62 + end
  63 +
  64 + def url_after_destroy
  65 + new_session_url
  66 + end
  67 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/controllers/clearance/users_controller.rb 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +class Clearance::UsersController < ApplicationController
  2 + unloadable
  3 +
  4 + before_filter :redirect_to_root, :only => [:new, :create], :if => :signed_in?
  5 + filter_parameter_logging :password
  6 +
  7 + def new
  8 + @user = ::User.new(params[:user])
  9 + render :template => 'users/new'
  10 + end
  11 +
  12 + def create
  13 + @user = ::User.new params[:user]
  14 + if @user.save
  15 + ::ClearanceMailer.deliver_confirmation @user
  16 + flash_notice_after_create
  17 + redirect_to(url_after_create)
  18 + else
  19 + render :template => 'users/new'
  20 + end
  21 + end
  22 +
  23 + private
  24 +
  25 + def flash_notice_after_create
  26 + flash[:notice] = translate(:deliver_confirmation,
  27 + :scope => [:clearance, :controllers, :users],
  28 + :default => "You will receive an email within the next few minutes. " <<
  29 + "It contains instructions for confirming your account.")
  30 + end
  31 +
  32 + def url_after_create
  33 + new_session_url
  34 + end
  35 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/models/clearance_mailer.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +class ClearanceMailer < ActionMailer::Base
  2 +
  3 + default_url_options[:host] = HOST
  4 +
  5 + def change_password(user)
  6 + from DO_NOT_REPLY
  7 + recipients user.email
  8 + subject I18n.t(:change_password,
  9 + :scope => [:clearance, :models, :clearance_mailer],
  10 + :default => "Change your password")
  11 + body :user => user
  12 + end
  13 +
  14 + def confirmation(user)
  15 + from DO_NOT_REPLY
  16 + recipients user.email
  17 + subject I18n.t(:confirmation,
  18 + :scope => [:clearance, :models, :clearance_mailer],
  19 + :default => "Account confirmation")
  20 + body :user => user
  21 + end
  22 +
  23 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/clearance_mailer/change_password.html.erb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +Someone, hopefully you, has requested that we send you a link to change your password.
  2 +
  3 +Here's the link:
  4 +
  5 +<%= edit_user_password_url(@user, :token => @user.token, :escape => false) %>
  6 +
  7 +If you didn't request this, ignore this email. Don't worry. Your password hasn't been changed.
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/clearance_mailer/confirmation.html.erb 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +
  2 +<%= new_user_confirmation_url :user_id => @user, :token => @user.token, :encode => false %>
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/passwords/edit.html.erb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +<h2>Change your password</h2>
  2 +
  3 +<p>
  4 + Your password has been reset. Choose a new password below.
  5 +</p>
  6 +
  7 +<%= error_messages_for :user %>
  8 +
  9 +<% form_for(:user,
  10 + :url => user_password_path(@user, :token => @user.token),
  11 + :html => { :method => :put }) do |form| %>
  12 + <div class="password_field">
  13 + <%= form.label :password, "Choose password" %>
  14 + <%= form.password_field :password %>
  15 + </div>
  16 + <div class="password_field">
  17 + <%= form.label :password_confirmation, "Confirm password" %>
  18 + <%= form.password_field :password_confirmation %>
  19 + </div>
  20 + <div class="submit_field">
  21 + <%= form.submit "Save this password", :disable_with => "Please wait..." %>
  22 + </div>
  23 +<% end %>
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/passwords/new.html.erb 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +<h2>Change your password</h2>
  2 +
  3 +<p>
  4 + We will email you a link to change your password.
  5 +</p>
  6 +
  7 +<% form_for :password, :url => passwords_path do |form| %>
  8 + <div class="text_field">
  9 + <%= form.label :email, "Email address" %>
  10 + <%= form.text_field :email %>
  11 + </div>
  12 + <div class="submit_field">
  13 + <%= form.submit "Reset password", :disable_with => "Please wait..." %>
  14 + </div>
  15 +<% end %>
0 16 \ No newline at end of file
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/sessions/new.html.erb 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +<h2>Sign in</h2>
  2 +
  3 +<% form_for :session, :url => session_path do |form| %>
  4 + <div class="text_field">
  5 + <%= form.label :email %>
  6 + <%= form.text_field :email %>
  7 + </div>
  8 + <div class="text_field">
  9 + <%= form.label :password %>
  10 + <%= form.password_field :password %>
  11 + </div>
  12 + <div class="text_field">
  13 + <%= form.check_box :remember_me %>
  14 + <%= form.label :remember_me %>
  15 + </div>
  16 + <div class="submit_field">
  17 + <%= form.submit "Sign in", :disable_with => "Please wait..." %>
  18 + </div>
  19 +<% end %>
  20 +
  21 +<ul>
  22 + <li>
  23 + <%= link_to "Sign up", new_user_path %>
  24 + </li>
  25 + <li>
  26 + <%= link_to "Forgot password?", new_password_path %>
  27 + </li>
  28 +</ul>
0 29 \ No newline at end of file
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/users/_form.html.erb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<%= form.error_messages %>
  2 +<div class="text_field">
  3 + <%= form.label :email %>
  4 + <%= form.text_field :email %>
  5 +</div>
  6 +<div class="password_field">
  7 + <%= form.label :password %>
  8 + <%= form.password_field :password %>
  9 +</div>
  10 +<div class="password_field">
  11 + <%= form.label :password_confirmation, "Confirm password" %>
  12 + <%= form.password_field :password_confirmation %>
  13 +</div>
0 14 \ No newline at end of file
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/users/new.html.erb 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +<h2>Sign up</h2>
  2 +
  3 +<% form_for @user do |form| %>
  4 + <%= render :partial => '/users/form', :object => form %>
  5 + <%= form.submit 'Sign up', :disable_with => 'Please wait...' %>
  6 +<% end %>
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/config/clearance_routes.rb 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +ActionController::Routing::Routes.draw do |map|
  2 + map.resources :passwords,
  3 + :controller => 'clearance/passwords',
  4 + :only => [:new, :create]
  5 +
  6 + map.resource :session,
  7 + :controller => 'clearance/sessions',
  8 + :only => [:new, :create, :destroy]
  9 +
  10 + map.resources :users, :controller => 'clearance/users' do |users|
  11 + users.resource :password,
  12 + :controller => 'clearance/passwords',
  13 + :only => [:create, :edit, :update]
  14 +
  15 + users.resource :confirmation,
  16 + :controller => 'clearance/confirmations',
  17 + :only => [:new, :create]
  18 + end
  19 +
  20 + map.sign_up 'sign_up',
  21 + :controller => 'clearance/users',
  22 + :action => 'new'
  23 + map.sign_in 'sign_in',
  24 + :controller => 'clearance/sessions',
  25 + :action => 'new'
  26 + map.sign_out 'sign_out',
  27 + :controller => 'clearance/sessions',
  28 + :action => 'destroy',
  29 + :method => :delete
  30 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/USAGE 0 → 100644
... ... @@ -0,0 +1 @@
  1 +script/generate clearance
0 2 \ No newline at end of file
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/clearance_generator.rb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
  2 +require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
  3 +require 'factory_girl'
  4 +
  5 +class ClearanceGenerator < Rails::Generator::Base
  6 +
  7 + def manifest
  8 + record do |m|
  9 + m.insert_into "app/controllers/application_controller.rb",
  10 + "include Clearance::Authentication"
  11 +
  12 + user_model = "app/models/user.rb"
  13 + if File.exists?(user_model)
  14 + m.insert_into user_model, "include Clearance::User"
  15 + else
  16 + m.directory File.join("app", "models")
  17 + m.file "user.rb", user_model
  18 + end
  19 +
  20 + m.directory File.join("test", "factories")
  21 + m.file "factories.rb", "test/factories/clearance.rb"
  22 +
  23 + m.migration_template "migrations/#{migration_name}.rb",
  24 + 'db/migrate',
  25 + :migration_file_name => "clearance_#{migration_name}"
  26 +
  27 + m.readme "README"
  28 + end
  29 + end
  30 +
  31 + private
  32 +
  33 + def migration_name
  34 + if ActiveRecord::Base.connection.table_exists?(:users)
  35 + 'update_users'
  36 + else
  37 + 'create_users'
  38 + end
  39 + end
  40 +
  41 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/lib/insert_commands.rb 0 → 100644
... ... @@ -0,0 +1,33 @@
  1 +# Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
  2 +
  3 +Rails::Generator::Commands::Base.class_eval do
  4 + def file_contains?(relative_destination, line)
  5 + File.read(destination_path(relative_destination)).include?(line)
  6 + end
  7 +end
  8 +
  9 +Rails::Generator::Commands::Create.class_eval do
  10 + def insert_into(file, line)
  11 + logger.insert "#{line} into #{file}"
  12 + unless options[:pretend] || file_contains?(file, line)
  13 + gsub_file file, /^(class|module) .+$/ do |match|
  14 + "#{match}\n #{line}"
  15 + end
  16 + end
  17 + end
  18 +end
  19 +
  20 +Rails::Generator::Commands::Destroy.class_eval do
  21 + def insert_into(file, line)
  22 + logger.remove "#{line} from #{file}"
  23 + unless options[:pretend]
  24 + gsub_file file, "\n #{line}", ''
  25 + end
  26 + end
  27 +end
  28 +
  29 +Rails::Generator::Commands::List.class_eval do
  30 + def insert_into(file, line)
  31 + logger.insert "#{line} into #{file}"
  32 + end
  33 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/lib/rake_commands.rb 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +Rails::Generator::Commands::Create.class_eval do
  2 + def rake_db_migrate
  3 + logger.rake "db:migrate"
  4 + unless system("rake db:migrate")
  5 + logger.rake "db:migrate failed. Rolling back"
  6 + command(:destroy).invoke!
  7 + end
  8 + end
  9 +end
  10 +
  11 +Rails::Generator::Commands::Destroy.class_eval do
  12 + def rake_db_migrate
  13 + logger.rake "db:rollback"
  14 + system "rake db:rollback"
  15 + end
  16 +end
  17 +
  18 +Rails::Generator::Commands::List.class_eval do
  19 + def rake_db_migrate
  20 + logger.rake "db:migrate"
  21 + end
  22 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/README 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +
  2 +*******************************************************************************
  3 +
  4 +Ok, enough fancy automatic stuff. Time for some old school monkey copy-pasting.
  5 +
  6 +1. Define a HOST constant in your environments files.
  7 +In config/environments/test.rb and config/environments/development.rb it can be:
  8 +
  9 + HOST = "localhost"
  10 +
  11 +In production.rb it must be the actual host your application is deployed to.
  12 +The constant is used by mailers to generate URLs in emails.
  13 +
  14 +2. In config/environment.rb:
  15 +
  16 + DO_NOT_REPLY = "donotreply@example.com"
  17 +
  18 +3. Define root_url to *something* in your config/routes.rb:
  19 +
  20 + map.root :controller => 'home'
  21 +
  22 +*******************************************************************************
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/factories.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
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/migrations/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
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/migrations/update_users.rb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +class ClearanceUpdateUsers < ActiveRecord::Migration
  2 + def self.up
  3 +<%
  4 + existing_columns = ActiveRecord::Base.connection.columns(:users).collect { |each| each.name }
  5 + columns = [
  6 + [:email, 't.string :email'],
  7 + [:encrypted_password, 't.string :encrypted_password, :limit => 128'],
  8 + [:salt, 't.string :salt, :limit => 128'],
  9 + [:token, 't.string :token, :limit => 128'],
  10 + [:token_expires_at, 't.datetime :token_expires_at'],
  11 + [:email_confirmed, 't.boolean :email_confirmed, :default => false, :null => false']
  12 + ].delete_if {|c| existing_columns.include?(c.first.to_s)}
  13 +-%>
  14 + change_table(:users) do |t|
  15 +<% columns.each do |c| -%>
  16 + <%= c.last %>
  17 +<% end -%>
  18 + end
  19 +
  20 +<%
  21 + existing_indexes = ActiveRecord::Base.connection.indexes(:users)
  22 + index_names = existing_indexes.collect { |each| each.name }
  23 + new_indexes = [
  24 + [:index_users_on_id_and_token, 'add_index :users, [:id, :token]'],
  25 + [:index_users_on_email, 'add_index :users, :email'],
  26 + [:index_users_on_token, 'add_index :users, :token']
  27 + ].delete_if { |each| index_names.include?(each.first.to_s) }
  28 +-%>
  29 +<% new_indexes.each do |each| -%>
  30 + <%= each.last %>
  31 +<% end -%>
  32 + end
  33 +
  34 + def self.down
  35 + change_table(:users) do |t|
  36 +<% unless columns.empty? -%>
  37 + t.remove <%= columns.collect { |each| ":#{each.first}" }.join(',') %>
  38 +<% end -%>
  39 + end
  40 + end
  41 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/user.rb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +class User < ActiveRecord::Base
  2 + include Clearance::User
  3 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/USAGE 0 → 100644
... ... @@ -0,0 +1 @@
  1 +script/generate clearance_features
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/clearance_features_generator.rb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +class ClearanceFeaturesGenerator < Rails::Generator::Base
  2 +
  3 + def manifest
  4 + record do |m|
  5 + m.directory File.join("features", "step_definitions")
  6 + m.directory File.join("features", "support")
  7 +
  8 + ["features/step_definitions/clearance_steps.rb",
  9 + "features/step_definitions/factory_girl_steps.rb",
  10 + "features/support/paths.rb",
  11 + "features/sign_in.feature",
  12 + "features/sign_out.feature",
  13 + "features/sign_up.feature",
  14 + "features/password_reset.feature"].each do |file|
  15 + m.file file, file
  16 + end
  17 + end
  18 + end
  19 +
  20 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/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 +
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/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 +
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/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 +
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/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 +
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/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
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/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
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/features/support/paths.rb 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +module NavigationHelpers
  2 + def path_to(page_name)
  3 + case page_name
  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
  15 +
  16 + else
  17 + raise "Can't find mapping from \"#{page_name}\" to a path."
  18 + end
  19 + end
  20 +end
  21 +
  22 +World(NavigationHelpers)
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance.rb 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +require 'clearance/extensions/errors'
  2 +require 'clearance/extensions/rescue'
  3 +require 'clearance/extensions/routes'
  4 +
  5 +require 'clearance/authentication'
  6 +require 'clearance/user'
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/authentication.rb 0 → 100644
... ... @@ -0,0 +1,100 @@
  1 +module Clearance
  2 + module Authentication
  3 +
  4 + def self.included(controller)
  5 + controller.send(:include, InstanceMethods)
  6 +
  7 + controller.class_eval do
  8 + helper_method :current_user
  9 + helper_method :signed_in?
  10 +
  11 + hide_action :current_user, :signed_in?
  12 + end
  13 + end
  14 +
  15 + module InstanceMethods
  16 + def current_user
  17 + @_current_user ||= (user_from_cookie || user_from_session)
  18 + end
  19 +
  20 + def signed_in?
  21 + ! current_user.nil?
  22 + end
  23 +
  24 + protected
  25 +
  26 + def authenticate
  27 + deny_access unless signed_in?
  28 + end
  29 +
  30 + def user_from_session
  31 + if session[:user_id]
  32 + return nil unless user = ::User.find_by_id(session[:user_id])
  33 + return user if user.email_confirmed?
  34 + end
  35 + end
  36 +
  37 + def user_from_cookie
  38 + if token = cookies[:remember_token]
  39 + return nil unless user = ::User.find_by_token(token)
  40 + return user if user.remember?
  41 + end
  42 + end
  43 +
  44 + def sign_user_in(user)
  45 + warn "[DEPRECATION] sign_user_in: unnecessary. use sign_in(user) instead."
  46 + sign_in(user)
  47 + end
  48 +
  49 + def sign_in(user)
  50 + if user
  51 + session[:user_id] = user.id
  52 + end
  53 + end
  54 +
  55 + def remember?
  56 + params[:session] && params[:session][:remember_me] == "1"
  57 + end
  58 +
  59 + def remember(user)
  60 + user.remember_me!
  61 + cookies[:remember_token] = { :value => user.token,
  62 + :expires => user.token_expires_at }
  63 + end
  64 +
  65 + def forget(user)
  66 + user.forget_me! if user
  67 + cookies.delete(:remember_token)
  68 + reset_session
  69 + end
  70 +
  71 + def redirect_back_or(default)
  72 + redirect_to(return_to || default)
  73 + clear_return_to
  74 + end
  75 +
  76 + def return_to
  77 + session[:return_to] || params[:return_to]
  78 + end
  79 +
  80 + def clear_return_to
  81 + session[:return_to] = nil
  82 + end
  83 +
  84 + def redirect_to_root
  85 + redirect_to(root_url)
  86 + end
  87 +
  88 + def store_location
  89 + session[:return_to] = request.request_uri if request.get?
  90 + end
  91 +
  92 + def deny_access(flash_message = nil, opts = {})
  93 + store_location
  94 + flash[:failure] = flash_message if flash_message
  95 + redirect_to(new_session_url)
  96 + end
  97 + end
  98 +
  99 + end
  100 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/extensions/errors.rb 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +if defined?(ActionController)
  2 + module ActionController
  3 + class Forbidden < StandardError
  4 + end
  5 + end
  6 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/extensions/rescue.rb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +if defined?(ActionController::Base)
  2 + ActionController::Base.rescue_responses.update('ActionController::Forbidden' => :forbidden)
  3 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/extensions/routes.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +if defined?(ActionController::Routing::RouteSet)
  2 + class ActionController::Routing::RouteSet
  3 + def load_routes_with_clearance!
  4 + lib_path = File.dirname(__FILE__)
  5 + clearance_routes = File.join(lib_path, *%w[.. .. .. config clearance_routes.rb])
  6 + unless configuration_files.include?(clearance_routes)
  7 + add_configuration_file(clearance_routes)
  8 + end
  9 + load_routes_without_clearance!
  10 + end
  11 +
  12 + alias_method_chain :load_routes!, :clearance
  13 + end
  14 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/user.rb 0 → 100644
... ... @@ -0,0 +1,143 @@
  1 +require 'digest/sha1'
  2 +
  3 +module Clearance
  4 + module User
  5 +
  6 + def self.included(model)
  7 + model.extend(ClassMethods)
  8 +
  9 + model.send(:include, InstanceMethods)
  10 + model.send(:include, AttrAccessible)
  11 + model.send(:include, AttrAccessor)
  12 + model.send(:include, Validations)
  13 + model.send(:include, Callbacks)
  14 + end
  15 +
  16 + module AttrAccessible
  17 + def self.included(model)
  18 + model.class_eval do
  19 + attr_accessible :email, :password, :password_confirmation
  20 + end
  21 + end
  22 + end
  23 +
  24 + module AttrAccessor
  25 + def self.included(model)
  26 + model.class_eval do
  27 + attr_accessor :password, :password_confirmation
  28 + end
  29 + end
  30 + end
  31 +
  32 + module Validations
  33 + def self.included(model)
  34 + model.class_eval do
  35 + validates_presence_of :email
  36 + validates_uniqueness_of :email, :case_sensitive => false
  37 + validates_format_of :email, :with => %r{.+@.+\..+}
  38 +
  39 + validates_presence_of :password, :if => :password_required?
  40 + validates_confirmation_of :password, :if => :password_required?
  41 + end
  42 + end
  43 + end
  44 +
  45 + module Callbacks
  46 + def self.included(model)
  47 + model.class_eval do
  48 + before_save :initialize_salt, :encrypt_password, :initialize_token
  49 + end
  50 + end
  51 + end
  52 +
  53 + module InstanceMethods
  54 + def authenticated?(password)
  55 + encrypted_password == encrypt(password)
  56 + end
  57 +
  58 + def encrypt(string)
  59 + generate_hash("--#{salt}--#{string}--")
  60 + end
  61 +
  62 + def remember?
  63 + token_expires_at && Time.now.utc < token_expires_at
  64 + end
  65 +
  66 + def remember_me!
  67 + remember_me_until! 2.weeks.from_now.utc
  68 + end
  69 +
  70 + def forget_me!
  71 + clear_token
  72 + save(false)
  73 + end
  74 +
  75 + def confirm_email!
  76 + self.email_confirmed = true
  77 + self.token = nil
  78 + save(false)
  79 + end
  80 +
  81 + def forgot_password!
  82 + generate_token
  83 + save(false)
  84 + end
  85 +
  86 + def update_password(new_password, new_password_confirmation)
  87 + self.password = new_password
  88 + self.password_confirmation = new_password_confirmation
  89 + clear_token if valid?
  90 + save
  91 + end
  92 +
  93 + protected
  94 +
  95 + def generate_hash(string)
  96 + Digest::SHA1.hexdigest(string)
  97 + end
  98 +
  99 + def initialize_salt
  100 + if new_record?
  101 + self.salt = generate_hash("--#{Time.now.utc.to_s}--#{password}--")
  102 + end
  103 + end
  104 +
  105 + def encrypt_password
  106 + return if password.blank?
  107 + self.encrypted_password = encrypt(password)
  108 + end
  109 +
  110 + def generate_token
  111 + self.token = encrypt("--#{Time.now.utc.to_s}--#{password}--")
  112 + self.token_expires_at = nil
  113 + end
  114 +
  115 + def clear_token
  116 + self.token = nil
  117 + self.token_expires_at = nil
  118 + end
  119 +
  120 + def initialize_token
  121 + generate_token if new_record?
  122 + end
  123 +
  124 + def password_required?
  125 + encrypted_password.blank? || !password.blank?
  126 + end
  127 +
  128 + def remember_me_until!(time)
  129 + self.token_expires_at = time
  130 + self.token = encrypt("--#{token_expires_at}--#{password}--")
  131 + save(false)
  132 + end
  133 + end
  134 +
  135 + module ClassMethods
  136 + def authenticate(email, password)
  137 + return nil unless user = find_by_email(email)
  138 + return user if user.authenticated?(password)
  139 + end
  140 + end
  141 +
  142 + end
  143 +end
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/rails/init.rb 0 → 100644
... ... @@ -0,0 +1 @@
  1 +require 'clearance'
0 2 \ No newline at end of file
... ...
vendor/plugins/thoughtbot-clearance-0.6.8/shoulda_macros/clearance.rb 0 → 100644
... ... @@ -0,0 +1,262 @@
  1 +module Clearance
  2 + module Shoulda
  3 +
  4 + # STATE OF AUTHENTICATION
  5 +
  6 + def should_be_signed_in_as(&block)
  7 + should "be signed in as #{block.bind(self).call}" do
  8 + user = block.bind(self).call
  9 + assert_not_nil user,
  10 + "please pass a User. try: should_be_signed_in_as { @user }"
  11 + assert_equal user, @controller.send(:current_user),
  12 + "#{user.inspect} is not the current_user, " <<
  13 + "which is #{@controller.send(:current_user).inspect}"
  14 + end
  15 + end
  16 +
  17 + def should_be_signed_in_and_email_confirmed_as(&block)
  18 + warn "[DEPRECATION] should_be_signed_in_and_email_confirmed_as: questionable usefulness"
  19 + should_be_signed_in_as &block
  20 +
  21 + should "have confirmed email" do
  22 + user = block.bind(self).call
  23 +
  24 + assert_not_nil user
  25 + assert_equal user, assigns(:user)
  26 + assert assigns(:user).email_confirmed?
  27 + end
  28 + end
  29 +
  30 + def should_not_be_signed_in
  31 + should "not be signed in" do
  32 + assert_nil session[:user_id]
  33 + end
  34 + end
  35 +
  36 + def should_deny_access_on(http_method, action, opts = {})
  37 + warn "[DEPRECATION] should_deny_access_on: use a setup & should_deny_access(:flash => ?)"
  38 + flash_message = opts.delete(:flash)
  39 + context "on #{http_method} to #{action}" do
  40 + setup do
  41 + send(http_method, action, opts)
  42 + end
  43 +
  44 + should_deny_access(:flash => flash_message)
  45 + end
  46 + end
  47 +
  48 + def should_deny_access(opts = {})
  49 + if opts[:flash]
  50 + should_set_the_flash_to opts[:flash]
  51 + else
  52 + should_not_set_the_flash
  53 + end
  54 +
  55 + should_redirect_to('new_session_url') { new_session_url }
  56 + end
  57 +
  58 + # HTTP FLUENCY
  59 +
  60 + def should_forbid(description, &block)
  61 + should "forbid #{description}" do
  62 + assert_raises ActionController::Forbidden do
  63 + instance_eval(&block)
  64 + end
  65 + end
  66 + end
  67 +
  68 + # CONTEXTS
  69 +
  70 + def signed_in_user_context(&blk)
  71 + warn "[DEPRECATION] signed_in_user_context: creates a Mystery Guest, causes Obscure Test"
  72 + context "A signed in user" do
  73 + setup do
  74 + @user = Factory(:user)
  75 + @user.confirm_email!
  76 + sign_in_as @user
  77 + end
  78 + merge_block(&blk)
  79 + end
  80 + end
  81 +
  82 + def public_context(&blk)
  83 + warn "[DEPRECATION] public_context: common case is no-op. call sign_out otherwise"
  84 + context "The public" do
  85 + setup { sign_out }
  86 + merge_block(&blk)
  87 + end
  88 + end
  89 +
  90 + # CREATING USERS
  91 +
  92 + def should_create_user_successfully
  93 + warn "[DEPRECATION] should_create_user_successfully: not meant to be public, no longer used internally"
  94 + should_assign_to :user
  95 + should_change 'User.count', :by => 1
  96 +
  97 + should "send the confirmation email" do
  98 + assert_sent_email do |email|
  99 + email.subject =~ /account confirmation/i
  100 + end
  101 + end
  102 +
  103 + should_set_the_flash_to /confirm/i
  104 + should_redirect_to_url_after_create
  105 + end
  106 +
  107 + # RENDERING
  108 +
  109 + def should_render_nothing
  110 + should "render nothing" do
  111 + assert @response.body.blank?
  112 + end
  113 + end
  114 +
  115 + # REDIRECTS
  116 +
  117 + def should_redirect_to_url_after_create
  118 + should_redirect_to("the post-create url") do
  119 + @controller.send(:url_after_create)
  120 + end
  121 + end
  122 +
  123 + def should_redirect_to_url_after_update
  124 + should_redirect_to("the post-update url") do
  125 + @controller.send(:url_after_update)
  126 + end
  127 + end
  128 +
  129 + def should_redirect_to_url_after_destroy
  130 + should_redirect_to("the post-destroy url") do
  131 + @controller.send(:url_after_destroy)
  132 + end
  133 + end
  134 +
  135 + # VALIDATIONS
  136 +
  137 + def should_validate_confirmation_of(attribute, opts = {})
  138 + warn "[DEPRECATION] should_validate_confirmation_of: not meant to be public, no longer used internally"
  139 + raise ArgumentError if opts[:factory].nil?
  140 +
  141 + context "on save" do
  142 + should_validate_confirmation_is_not_blank opts[:factory], attribute
  143 + should_validate_confirmation_is_not_bad opts[:factory], attribute
  144 + end
  145 + end
  146 +
  147 + def should_validate_confirmation_is_not_blank(factory, attribute, opts = {})
  148 + warn "[DEPRECATION] should_validate_confirmation_is_not_blank: not meant to be public, no longer used internally"
  149 + should "validate #{attribute}_confirmation is not blank" do
  150 + model = Factory.build(factory, blank_confirmation_options(attribute))
  151 + model.save
  152 + assert_confirmation_error(model, attribute,
  153 + "#{attribute}_confirmation cannot be blank")
  154 + end
  155 + end
  156 +
  157 + def should_validate_confirmation_is_not_bad(factory, attribute, opts = {})
  158 + warn "[DEPRECATION] should_validate_confirmation_is_not_bad: not meant to be public, no longer used internally"
  159 + should "validate #{attribute}_confirmation is different than #{attribute}" do
  160 + model = Factory.build(factory, bad_confirmation_options(attribute))
  161 + model.save
  162 + assert_confirmation_error(model, attribute,
  163 + "#{attribute}_confirmation cannot be different than #{attribute}")
  164 + end
  165 + end
  166 +
  167 + # FORMS
  168 +
  169 + def should_display_a_password_update_form
  170 + warn "[DEPRECATION] should_display_a_password_update_form: not meant to be public, no longer used internally"
  171 + should "have a form for the user's token, password, and password confirm" do
  172 + update_path = ERB::Util.h(
  173 + user_password_path(@user, :token => @user.token)
  174 + )
  175 +
  176 + assert_select 'form[action=?]', update_path do
  177 + assert_select 'input[name=_method][value=?]', 'put'
  178 + assert_select 'input[name=?]', 'user[password]'
  179 + assert_select 'input[name=?]', 'user[password_confirmation]'
  180 + end
  181 + end
  182 + end
  183 +
  184 + def should_display_a_sign_up_form
  185 + warn "[DEPRECATION] should_display_a_sign_up_form: not meant to be public, no longer used internally"
  186 + should "display a form to sign up" do
  187 + assert_select "form[action=#{users_path}][method=post]",
  188 + true, "There must be a form to sign up" do
  189 + assert_select "input[type=text][name=?]",
  190 + "user[email]", true, "There must be an email field"
  191 + assert_select "input[type=password][name=?]",
  192 + "user[password]", true, "There must be a password field"
  193 + assert_select "input[type=password][name=?]",
  194 + "user[password_confirmation]", true, "There must be a password confirmation field"
  195 + assert_select "input[type=submit]", true,
  196 + "There must be a submit button"
  197 + end
  198 + end
  199 + end
  200 +
  201 + def should_display_a_sign_in_form
  202 + warn "[DEPRECATION] should_display_a_sign_in_form: not meant to be public, no longer used internally"
  203 + should 'display a "sign in" form' do
  204 + assert_select "form[action=#{session_path}][method=post]",
  205 + true, "There must be a form to sign in" do
  206 + assert_select "input[type=text][name=?]",
  207 + "session[email]", true, "There must be an email field"
  208 + assert_select "input[type=password][name=?]",
  209 + "session[password]", true, "There must be a password field"
  210 + assert_select "input[type=checkbox][name=?]",
  211 + "session[remember_me]", true, "There must be a 'remember me' check box"
  212 + assert_select "input[type=submit]", true,
  213 + "There must be a submit button"
  214 + end
  215 + end
  216 + end
  217 + end
  218 +end
  219 +
  220 +module Clearance
  221 + module Shoulda
  222 + module Helpers
  223 + def sign_in_as(user)
  224 + @controller.class_eval { attr_accessor :current_user }
  225 + @controller.current_user = user
  226 + return user
  227 + end
  228 +
  229 + def sign_in
  230 + sign_in_as Factory(:email_confirmed_user)
  231 + end
  232 +
  233 + def sign_out
  234 + @controller.class_eval { attr_accessor :current_user }
  235 + @controller.current_user = nil
  236 + end
  237 +
  238 + def blank_confirmation_options(attribute)
  239 + warn "[DEPRECATION] blank_confirmation_options: not meant to be public, no longer used internally"
  240 + opts = { attribute => attribute.to_s }
  241 + opts.merge("#{attribute}_confirmation".to_sym => "")
  242 + end
  243 +
  244 + def bad_confirmation_options(attribute)
  245 + warn "[DEPRECATION] bad_confirmation_options: not meant to be public, no longer used internally"
  246 + opts = { attribute => attribute.to_s }
  247 + opts.merge("#{attribute}_confirmation".to_sym => "not_#{attribute}")
  248 + end
  249 +
  250 + def assert_confirmation_error(model, attribute, message = "confirmation error")
  251 + warn "[DEPRECATION] assert_confirmation_error: not meant to be public, no longer used internally"
  252 + assert model.errors.on(attribute).include?("doesn't match confirmation"),
  253 + message
  254 + end
  255 + end
  256 + end
  257 +end
  258 +
  259 +class Test::Unit::TestCase
  260 + include Clearance::Shoulda::Helpers
  261 +end
  262 +Test::Unit::TestCase.extend(Clearance::Shoulda)
... ...