blue_light_special 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +67 -0
- data/Rakefile +95 -0
- data/VERSION +1 -0
- data/app/controllers/blue_light_special/impersonations_controller.rb +44 -0
- data/app/controllers/blue_light_special/passwords_controller.rb +84 -0
- data/app/controllers/blue_light_special/sessions_controller.rb +70 -0
- data/app/controllers/blue_light_special/users_controller.rb +48 -0
- data/app/models/blue_light_special_mailer.rb +22 -0
- data/app/models/deliver_change_password_job.rb +19 -0
- data/app/models/deliver_welcome_job.rb +17 -0
- data/app/models/impersonation.rb +26 -0
- data/app/views/blue_light_special_mailer/change_password.html.erb +9 -0
- data/app/views/impersonations/index.html.erb +5 -0
- data/app/views/passwords/edit.html.erb +23 -0
- data/app/views/passwords/new.html.erb +15 -0
- data/app/views/sessions/new.html.erb +48 -0
- data/app/views/users/_form.html.erb +21 -0
- data/app/views/users/edit.html.erb +6 -0
- data/app/views/users/new.html.erb +6 -0
- data/app/views/users/show.html.erb +8 -0
- data/generators/blue_light_special/USAGE +1 -0
- data/generators/blue_light_special/blue_light_special_generator.rb +78 -0
- data/generators/blue_light_special/lib/insert_commands.rb +33 -0
- data/generators/blue_light_special/lib/rake_commands.rb +22 -0
- data/generators/blue_light_special/templates/README +20 -0
- data/generators/blue_light_special/templates/application.html.erb +50 -0
- data/generators/blue_light_special/templates/blue_light_special.rb +21 -0
- data/generators/blue_light_special/templates/blue_light_special.yml +42 -0
- data/generators/blue_light_special/templates/factories.rb +23 -0
- data/generators/blue_light_special/templates/migrations/create_users.rb +24 -0
- data/generators/blue_light_special/templates/migrations/update_users.rb +44 -0
- data/generators/blue_light_special/templates/style.css +31 -0
- data/generators/blue_light_special/templates/user.rb +3 -0
- data/generators/blue_light_special/templates/xd_receiver.html +10 -0
- data/generators/blue_light_special/templates/xd_receiver_ssl.html +10 -0
- data/generators/blue_light_special_admin/USAGE +1 -0
- data/generators/blue_light_special_admin/blue_light_special_admin_generator.rb +30 -0
- data/generators/blue_light_special_admin/lib/insert_commands.rb +33 -0
- data/generators/blue_light_special_admin/templates/README +16 -0
- data/generators/blue_light_special_admin/templates/app/controllers/admin/admin_controller.rb +14 -0
- data/generators/blue_light_special_admin/templates/app/controllers/admin/users_controller.rb +52 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/_form.html.erb +25 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/edit.html.erb +6 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/index.html.erb +7 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/new.html.erb +6 -0
- data/generators/blue_light_special_admin/templates/app/views/admin/users/show.html.erb +10 -0
- data/generators/blue_light_special_admin/templates/test/integration/admin/users_test.rb +201 -0
- data/generators/blue_light_special_tests/USAGE +1 -0
- data/generators/blue_light_special_tests/blue_light_special_tests_generator.rb +21 -0
- data/generators/blue_light_special_tests/templates/README +58 -0
- data/generators/blue_light_special_tests/templates/test/integration/edit_profile_test.rb +35 -0
- data/generators/blue_light_special_tests/templates/test/integration/facebook_test.rb +61 -0
- data/generators/blue_light_special_tests/templates/test/integration/impersonation_test.rb +39 -0
- data/generators/blue_light_special_tests/templates/test/integration/password_reset_test.rb +128 -0
- data/generators/blue_light_special_tests/templates/test/integration/sign_in_test.rb +66 -0
- data/generators/blue_light_special_tests/templates/test/integration/sign_out_test.rb +28 -0
- data/generators/blue_light_special_tests/templates/test/integration/sign_up_test.rb +47 -0
- data/lib/blue_light_special.rb +7 -0
- data/lib/blue_light_special/authentication.rb +138 -0
- data/lib/blue_light_special/configuration.rb +32 -0
- data/lib/blue_light_special/extensions/errors.rb +6 -0
- data/lib/blue_light_special/extensions/rescue.rb +5 -0
- data/lib/blue_light_special/routes.rb +55 -0
- data/lib/blue_light_special/user.rb +241 -0
- data/rails/init.rb +4 -0
- data/shoulda_macros/blue_light_special.rb +244 -0
- data/test/controllers/passwords_controller_test.rb +184 -0
- data/test/controllers/sessions_controller_test.rb +129 -0
- data/test/controllers/users_controller_test.rb +57 -0
- data/test/models/blue_light_special_mailer_test.rb +52 -0
- data/test/models/impersonation_test.rb +25 -0
- data/test/models/user_test.rb +213 -0
- data/test/rails_root/app/controllers/accounts_controller.rb +10 -0
- data/test/rails_root/app/controllers/application_controller.rb +6 -0
- data/test/rails_root/app/helpers/application_helper.rb +5 -0
- data/test/rails_root/app/helpers/confirmations_helper.rb +2 -0
- data/test/rails_root/app/helpers/passwords_helper.rb +2 -0
- data/test/rails_root/app/models/user.rb +3 -0
- data/test/rails_root/config/boot.rb +110 -0
- data/test/rails_root/config/environment.rb +22 -0
- data/test/rails_root/config/environments/development.rb +19 -0
- data/test/rails_root/config/environments/production.rb +1 -0
- data/test/rails_root/config/environments/test.rb +37 -0
- data/test/rails_root/config/initializers/blue_light_special.rb +4 -0
- data/test/rails_root/config/initializers/inflections.rb +10 -0
- data/test/rails_root/config/initializers/mime_types.rb +5 -0
- data/test/rails_root/config/initializers/requires.rb +13 -0
- data/test/rails_root/config/initializers/time_formats.rb +4 -0
- data/test/rails_root/config/routes.rb +9 -0
- data/test/rails_root/db/migrate/20100305173127_blue_light_special_create_users.rb +21 -0
- data/test/rails_root/db/migrate/20100305173129_create_delayed_jobs.rb +20 -0
- data/test/rails_root/public/dispatch.rb +10 -0
- data/test/rails_root/script/create_project.rb +52 -0
- data/test/rails_root/test/factories/user.rb +13 -0
- data/test/rails_root/test/functional/accounts_controller_test.rb +23 -0
- data/test/rails_root/test/integration/facebook_test.rb +49 -0
- data/test/rails_root/test/integration/impersonation_test.rb +38 -0
- data/test/rails_root/test/integration/password_reset_test.rb +127 -0
- data/test/rails_root/test/integration/sign_in_test.rb +72 -0
- data/test/rails_root/test/integration/sign_out_test.rb +28 -0
- data/test/rails_root/test/integration/sign_up_test.rb +84 -0
- data/test/test_helper.rb +21 -0
- metadata +219 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'boot')
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
Rails::Initializer.run do |config|
|
5
|
+
config.load_paths += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'gems', '*', 'lib'))
|
6
|
+
config.action_controller.session = {
|
7
|
+
:session_key => "_blue_light_special_session",
|
8
|
+
:secret => ['blue_light_special', 'random', 'words', 'here'].map {|k| Digest::MD5.hexdigest(k) }.join
|
9
|
+
}
|
10
|
+
|
11
|
+
config.gem "justinfrench-formtastic",
|
12
|
+
:lib => 'formtastic',
|
13
|
+
:source => 'http://gems.github.com'
|
14
|
+
|
15
|
+
config.gem "mini_fb",
|
16
|
+
:version => '=0.2.2'
|
17
|
+
|
18
|
+
config.gem "delayed_job",
|
19
|
+
:version => '=1.8.4'
|
20
|
+
|
21
|
+
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
2
|
+
|
3
|
+
# In the development environment your application's code is reloaded on
|
4
|
+
# every request. This slows down response time but is perfect for development
|
5
|
+
# since you don't have to restart the webserver when you make code changes.
|
6
|
+
config.cache_classes = false
|
7
|
+
|
8
|
+
# Log error messages when you accidentally call methods on nil.
|
9
|
+
config.whiny_nils = true
|
10
|
+
|
11
|
+
# Show full error reports and disable caching
|
12
|
+
config.action_controller.consider_all_requests_local = true
|
13
|
+
config.action_controller.perform_caching = false
|
14
|
+
config.action_view.debug_rjs = true
|
15
|
+
|
16
|
+
# Don't care if the mailer can't send
|
17
|
+
config.action_mailer.raise_delivery_errors = false
|
18
|
+
|
19
|
+
HOST = "localhost"
|
@@ -0,0 +1 @@
|
|
1
|
+
HOST = "http://example.com"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
2
|
+
|
3
|
+
# The test environment is used exclusively to run your application's
|
4
|
+
# test suite. You never need to work with it otherwise. Remember that
|
5
|
+
# your test database is "scratch space" for the test suite and is wiped
|
6
|
+
# and recreated between test runs. Don't rely on the data there!
|
7
|
+
config.cache_classes = true
|
8
|
+
|
9
|
+
# Log error messages when you accidentally call methods on nil.
|
10
|
+
config.whiny_nils = true
|
11
|
+
|
12
|
+
# Show full error reports and disable caching
|
13
|
+
config.action_controller.consider_all_requests_local = true
|
14
|
+
config.action_controller.perform_caching = false
|
15
|
+
|
16
|
+
# Disable request forgery protection in test environment
|
17
|
+
config.action_controller.allow_forgery_protection = false
|
18
|
+
|
19
|
+
# Tell ActionMailer not to deliver emails to the real world.
|
20
|
+
# The :test delivery method accumulates sent emails in the
|
21
|
+
# ActionMailer::Base.deliveries array.
|
22
|
+
config.action_mailer.delivery_method = :test
|
23
|
+
|
24
|
+
config.gem 'shoulda',
|
25
|
+
:source => "http://gemcutter.org",
|
26
|
+
:version => '>= 2.9.1'
|
27
|
+
config.gem 'factory_girl',
|
28
|
+
:source => "http://gemcutter.org",
|
29
|
+
:version => '>= 1.2.3'
|
30
|
+
|
31
|
+
config.gem 'webrat',
|
32
|
+
:lib => false,
|
33
|
+
:version => '>= 0.6.0'
|
34
|
+
|
35
|
+
config.gem 'fakeweb',
|
36
|
+
:source => "http://gemcutter.org",
|
37
|
+
:version => '>= 1.2.8'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Add new inflection rules using the following format
|
4
|
+
# (all these examples are active by default):
|
5
|
+
# Inflector.inflections do |inflect|
|
6
|
+
# inflect.plural /^(ox)$/i, '\1en'
|
7
|
+
# inflect.singular /^(ox)en/i, '\1'
|
8
|
+
# inflect.irregular 'person', 'people'
|
9
|
+
# inflect.uncountable %w( fish sheep )
|
10
|
+
# end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Dir[File.join(RAILS_ROOT, 'lib', 'extensions', '*.rb')].each do |f|
|
2
|
+
require f
|
3
|
+
end
|
4
|
+
|
5
|
+
Dir[File.join(RAILS_ROOT, 'lib', '*.rb')].each do |f|
|
6
|
+
require f
|
7
|
+
end
|
8
|
+
|
9
|
+
# Rails 2 doesn't like mocks
|
10
|
+
|
11
|
+
Dir[File.join(RAILS_ROOT, 'test', 'mocks', RAILS_ENV, '*.rb')].each do |f|
|
12
|
+
require f
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class BlueLightSpecialCreateUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:users) do |t|
|
4
|
+
t.string :email
|
5
|
+
t.string :role, :limit => 50
|
6
|
+
t.string :encrypted_password, :limit => 128
|
7
|
+
t.string :salt, :limit => 128
|
8
|
+
t.string :remember_token, :limit => 128
|
9
|
+
t.string :facebook_uid, :limit => 50
|
10
|
+
t.string :password_reset_token, :limit => 128
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :users, :email
|
15
|
+
add_index :users, :remember_token
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :users
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CreateDelayedJobs < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :delayed_jobs, :force => true do |table|
|
4
|
+
table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
|
5
|
+
table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
|
6
|
+
table.text :handler # YAML-encoded string of the object that will do work
|
7
|
+
table.text :last_error # reason for last failure (See Note below)
|
8
|
+
table.datetime :run_at # When to run. Could be Time.now for immediately, or sometime in the future.
|
9
|
+
table.datetime :locked_at # Set when a client is working on this object
|
10
|
+
table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
|
11
|
+
table.string :locked_by # Who is working on this object (if locked)
|
12
|
+
table.timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
drop_table :delayed_jobs
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/opt/local/bin/ruby
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
|
4
|
+
|
5
|
+
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
|
6
|
+
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
|
7
|
+
require "dispatcher"
|
8
|
+
|
9
|
+
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
|
10
|
+
Dispatcher.dispatch
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'activesupport'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
project_name = ARGV[0]
|
7
|
+
fail("Usage: #{File.basename(__FILE__)} new_project_name") unless project_name
|
8
|
+
fail("Project name must only contain [a-z0-9_]") unless project_name =~ /^[a-z0-9_]+$/
|
9
|
+
|
10
|
+
base_directory = Pathname.new(File.join(File.dirname(__FILE__), '..', '..')).realpath
|
11
|
+
project_directory = base_directory + project_name
|
12
|
+
fail("Project directory (#{project_directory}) already exists") if project_directory.exist?
|
13
|
+
|
14
|
+
template_url = "git@github.com:thoughtbot/rails-template.git"
|
15
|
+
changeme = "CHANGEME"
|
16
|
+
|
17
|
+
def run(cmd)
|
18
|
+
puts "Running '#{cmd}'"
|
19
|
+
out = `#{cmd}`
|
20
|
+
if $? != 0
|
21
|
+
fail "Command #{cmd} failed: #$?\n#{out}"
|
22
|
+
end
|
23
|
+
out
|
24
|
+
end
|
25
|
+
|
26
|
+
def search_and_replace(file, search, replace)
|
27
|
+
if File.file?(file)
|
28
|
+
contents = File.read(file)
|
29
|
+
if contents[search]
|
30
|
+
puts "Replacing #{search} with #{replace} in #{file}"
|
31
|
+
contents.gsub!(search, replace)
|
32
|
+
File.open(file, "w") { |f| f << contents }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
run("mkdir #{project_directory}")
|
38
|
+
Dir.chdir(project_directory) or fail("Couldn't change to #{project_directory}")
|
39
|
+
run("git init")
|
40
|
+
run("git remote add template #{template_url}")
|
41
|
+
run("git pull template master")
|
42
|
+
|
43
|
+
Dir.glob("#{project_directory}/**/*").each do |file|
|
44
|
+
search_and_replace(file, changeme, project_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
run("git commit -a -m 'Initial commit'")
|
48
|
+
|
49
|
+
puts
|
50
|
+
puts "Now login to github and add a new project named '#{project_name.humanize.titleize}'"
|
51
|
+
|
52
|
+
|
@@ -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 :admin_user, :parent => :user do |admin|
|
12
|
+
admin.role 'admin'
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AccountsControllerTest < ActionController::TestCase
|
4
|
+
|
5
|
+
context "when signed out" do
|
6
|
+
setup { sign_out }
|
7
|
+
should_deny_access_on :get, :edit
|
8
|
+
should_deny_access_on :put, :update
|
9
|
+
end
|
10
|
+
|
11
|
+
context "on POST to create" do
|
12
|
+
setup do
|
13
|
+
post :create
|
14
|
+
end
|
15
|
+
|
16
|
+
should_deny_access
|
17
|
+
|
18
|
+
should "not store location" do
|
19
|
+
assert session[:return_to].nil?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'facebooker/mock/service'
|
3
|
+
require 'facebooker/mock/session'
|
4
|
+
|
5
|
+
class FacebookTest < ActionController::IntegrationTest
|
6
|
+
|
7
|
+
context 'Signing in with Facebook' do
|
8
|
+
|
9
|
+
setup do
|
10
|
+
Facebooker::MockService.fixture_path = File.dirname(__FILE__) + '/../facebooker_fixtures'
|
11
|
+
fb_session = Facebooker::MockSession.create
|
12
|
+
fb_session.secure!
|
13
|
+
CitiesController.any_instance.stubs(:facebook_session).returns(fb_session)
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'find an existing user with the facebook uid' do
|
17
|
+
user = Factory( :facebook_user,
|
18
|
+
:facebook_uid => 8055,
|
19
|
+
:email => 'bob@facebook.com',
|
20
|
+
:first_name => 'Bob',
|
21
|
+
:last_name => 'Jones',
|
22
|
+
:display_name => 'Bob Jones',
|
23
|
+
:zip_code => '11111')
|
24
|
+
|
25
|
+
visit city_url(City.default)
|
26
|
+
assert controller.signed_in?
|
27
|
+
assert_equal controller.current_user, user
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'create a new user when the facebook uid is not found' do
|
31
|
+
assert_nil User.find_by_facebook_uid(8055)
|
32
|
+
|
33
|
+
visit city_url(City.default)
|
34
|
+
assert controller.signed_in?
|
35
|
+
assert_equal controller.current_user.facebook_uid, 8055
|
36
|
+
end
|
37
|
+
|
38
|
+
should 'copy the facebook user details' do
|
39
|
+
visit city_url(City.default)
|
40
|
+
assert controller.signed_in?
|
41
|
+
assert_equal controller.current_user.first_name, 'Dave'
|
42
|
+
assert_equal controller.current_user.last_name, 'Fetterman'
|
43
|
+
assert_equal controller.current_user.display_name, 'Dave Fetterman'
|
44
|
+
assert_equal controller.current_user.email, 'bob@facebook.com'
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ImpersonationTest < ActionController::IntegrationTest
|
4
|
+
|
5
|
+
context 'When impersonating another user' do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@bob = Factory(:user, :email => 'bob@bob.bob', :display_name => 'Bobby')
|
9
|
+
@admin_user = Factory(:admin_user, :email => 'admin@twongo.com')
|
10
|
+
sign_in_as @admin_user.email, @admin_user.password
|
11
|
+
impersonate(@bob)
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'be signed in' do
|
15
|
+
assert controller.signed_in?
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'be logged in as bob' do
|
19
|
+
assert_equal controller.current_user, @bob
|
20
|
+
end
|
21
|
+
|
22
|
+
should 'be able to go back to the original admin user' do
|
23
|
+
delete impersonate_url
|
24
|
+
assert controller.signed_in?
|
25
|
+
assert_equal controller.current_user, @admin_user
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
|
34
|
+
def impersonate(user)
|
35
|
+
post impersonate_url(user)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PasswordResetTest < ActionController::IntegrationTest
|
4
|
+
|
5
|
+
context 'When requesting a password reset' do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
ActionMailer::Base.deliveries.clear
|
9
|
+
end
|
10
|
+
|
11
|
+
teardown do
|
12
|
+
ActionMailer::Base.deliveries.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when not signed up' do
|
16
|
+
|
17
|
+
should 'see "Unknown email"' do
|
18
|
+
request_password_reset('unknown@bob.bob')
|
19
|
+
assert_match(/Unknown email/, response.body)
|
20
|
+
end
|
21
|
+
|
22
|
+
should 'not send an email' do
|
23
|
+
request_password_reset('unknown@bob.bob')
|
24
|
+
assert ActionMailer::Base.deliveries.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when signed up' do
|
30
|
+
|
31
|
+
setup do
|
32
|
+
@user = Factory(:user, :email => 'bob@bob.bob')
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'see "instructions for changing your password"' do
|
36
|
+
request_password_reset(@user.email)
|
37
|
+
assert_match(/instructions for changing your password/, response.body)
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'send a password reset email to the user' do
|
41
|
+
request_password_reset(@user.email)
|
42
|
+
@user.reload # catch updated confirmation token
|
43
|
+
Delayed::Job.work_off
|
44
|
+
sent = ActionMailer::Base.deliveries.last
|
45
|
+
assert_equal @user.email, sent.recipients
|
46
|
+
assert_match /password/i, sent.subject
|
47
|
+
assert !@user.password_reset_token.blank?
|
48
|
+
assert_match /#{@user.password_reset_token}/, sent.body[:url]
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'After requesting a password reset' do
|
56
|
+
|
57
|
+
setup do
|
58
|
+
ActionMailer::Base.deliveries.clear
|
59
|
+
@user = Factory(:user, :email => 'bob@bob.bob')
|
60
|
+
end
|
61
|
+
|
62
|
+
teardown do
|
63
|
+
ActionMailer::Base.deliveries.clear
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'with failed password confirmation' do
|
67
|
+
|
68
|
+
should 'see error messages' do
|
69
|
+
request_password_reset('bob@bob.bob')
|
70
|
+
@user.reload
|
71
|
+
change_password(@user, :password => 'goodpassword', :confirm => 'badpassword')
|
72
|
+
assert_match(/Password doesn't match confirmation/, response.body)
|
73
|
+
end
|
74
|
+
|
75
|
+
should 'not be signed in' do
|
76
|
+
request_password_reset('bob@bob.bob')
|
77
|
+
@user.reload
|
78
|
+
change_password(@user, :password => 'goodpassword', :confirm => 'badpassword')
|
79
|
+
assert !controller.signed_in?
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'with valid password and confirmation' do
|
85
|
+
|
86
|
+
should 'be signed in' do
|
87
|
+
request_password_reset('bob@bob.bob')
|
88
|
+
@user.reload
|
89
|
+
change_password(@user)
|
90
|
+
assert controller.signed_in?
|
91
|
+
end
|
92
|
+
|
93
|
+
should 'be able to sign in with new password' do
|
94
|
+
request_password_reset('bob@bob.bob')
|
95
|
+
@user.reload
|
96
|
+
change_password(@user)
|
97
|
+
sign_out
|
98
|
+
sign_in_as('bob@bob.bob', 'goodpassword')
|
99
|
+
assert controller.signed_in?
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
|
110
|
+
def request_password_reset(email)
|
111
|
+
visit new_password_url
|
112
|
+
fill_in "Email Address", :with => email
|
113
|
+
click_button "reset password"
|
114
|
+
end
|
115
|
+
|
116
|
+
def change_password(user, options = {})
|
117
|
+
options[:password] ||= 'goodpassword'
|
118
|
+
options[:confirm] ||= options[:password]
|
119
|
+
|
120
|
+
visit edit_user_password_path(:user_id => user,
|
121
|
+
:token => user.password_reset_token)
|
122
|
+
fill_in "Choose password", :with => options[:password]
|
123
|
+
fill_in "Confirm password", :with => options[:confirm]
|
124
|
+
click_button "save this password"
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|