janus 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +3 -0
  4. data/.gitignore +4 -0
  5. data/.travis.yml +18 -0
  6. data/LICENSE +20 -0
  7. data/README.rdoc +4 -5
  8. data/Rakefile +22 -0
  9. data/VERSION +1 -0
  10. data/certs/ysbaddaden.pem +21 -0
  11. data/janus.gemspec +28 -0
  12. data/lib/generators/janus/resource_generator.rb +17 -1
  13. data/lib/generators/templates/janus.rb +9 -5
  14. data/lib/generators/templates/mailer.rb +3 -0
  15. data/lib/generators/templates/mailer/confirmation_instructions.html.erb +7 -0
  16. data/lib/generators/templates/mailer/confirmation_instructions.text.erb +7 -0
  17. data/lib/generators/templates/mailer/reset_password_instructions.html.erb +9 -0
  18. data/lib/generators/templates/mailer/reset_password_instructions.text.erb +7 -0
  19. data/lib/janus.rb +3 -0
  20. data/lib/janus/config.rb +9 -3
  21. data/lib/janus/controllers/confirmations_controller.rb +1 -1
  22. data/lib/janus/controllers/internal_helpers.rb +8 -1
  23. data/lib/janus/controllers/passwords_controller.rb +1 -1
  24. data/lib/janus/controllers/registrations_controller.rb +1 -1
  25. data/lib/janus/controllers/sessions_controller.rb +6 -5
  26. data/lib/janus/models/confirmable.rb +2 -0
  27. data/lib/janus/models/database_authenticatable.rb +4 -2
  28. data/lib/janus/models/rememberable.rb +2 -0
  29. data/lib/janus/models/remote_authenticatable.rb +2 -0
  30. data/lib/janus/models/remote_token.rb +6 -5
  31. data/lib/janus/models/token_authenticatable.rb +79 -0
  32. data/lib/janus/models/trackable.rb +2 -0
  33. data/lib/janus/strategies.rb +1 -1
  34. data/lib/janus/strategies/token_authenticatable.rb +22 -0
  35. data/lib/janus/version.rb +10 -0
  36. data/test/fixtures/admins.yml +5 -0
  37. data/test/fixtures/users.yml +10 -0
  38. data/test/functional/admins/sessions_controller_test.rb +13 -0
  39. data/test/functional/home_controller_test.rb +8 -0
  40. data/test/functional/janus/mailer_test.rb +14 -0
  41. data/test/functional/janus/manager_test.rb +94 -0
  42. data/test/functional/users/confirmations_controller_test.rb +68 -0
  43. data/test/functional/users/passwords_controller_test.rb +131 -0
  44. data/test/functional/users/registrations_controller_test.rb +112 -0
  45. data/test/functional/users/sessions_controller_test.rb +100 -0
  46. data/test/functional/users_controller_test.rb +29 -0
  47. data/test/generators/install_generator_test.rb +16 -0
  48. data/test/generators/resource_generator_test.rb +80 -0
  49. data/test/integration/users/rememberable_test.rb +32 -0
  50. data/test/integration/users/remote_test.rb +72 -0
  51. data/test/integration/users/sessions_test.rb +18 -0
  52. data/test/integration/users/token_authenticatable_test.rb +42 -0
  53. data/test/integration/users/trackable_test.rb +22 -0
  54. data/test/rails_app/.gitignore +4 -0
  55. data/test/rails_app/Rakefile +7 -0
  56. data/test/rails_app/app/controllers/admins/sessions_controller.rb +11 -0
  57. data/test/rails_app/app/controllers/application_controller.rb +9 -0
  58. data/test/rails_app/app/controllers/blogs_controller.rb +6 -0
  59. data/test/rails_app/app/controllers/home_controller.rb +4 -0
  60. data/test/rails_app/app/controllers/users/confirmations_controller.rb +3 -0
  61. data/test/rails_app/app/controllers/users/passwords_controller.rb +3 -0
  62. data/test/rails_app/app/controllers/users/registrations_controller.rb +17 -0
  63. data/test/rails_app/app/controllers/users/sessions_controller.rb +11 -0
  64. data/test/rails_app/app/controllers/users_controller.rb +9 -0
  65. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  66. data/test/rails_app/app/mailers/user_mailer.rb +3 -0
  67. data/test/rails_app/app/models/admin.rb +3 -0
  68. data/test/rails_app/app/models/remote_token.rb +6 -0
  69. data/test/rails_app/app/models/user.rb +8 -0
  70. data/test/rails_app/app/views/admins/sessions/new.html.erb +30 -0
  71. data/test/rails_app/app/views/blogs/show.html.erb +2 -0
  72. data/test/rails_app/app/views/home/index.html.erb +2 -0
  73. data/test/rails_app/app/views/layouts/application.html.erb +28 -0
  74. data/test/rails_app/app/views/user_mailer/confirmation_instructions.html.erb +7 -0
  75. data/test/rails_app/app/views/user_mailer/confirmation_instructions.text.erb +7 -0
  76. data/test/rails_app/app/views/user_mailer/reset_password_instructions.html.erb +9 -0
  77. data/test/rails_app/app/views/user_mailer/reset_password_instructions.text.erb +7 -0
  78. data/test/rails_app/app/views/users/confirmations/new.html.erb +16 -0
  79. data/test/rails_app/app/views/users/passwords/edit.html.erb +21 -0
  80. data/test/rails_app/app/views/users/passwords/new.html.erb +16 -0
  81. data/test/rails_app/app/views/users/registrations/edit.html.erb +31 -0
  82. data/test/rails_app/app/views/users/registrations/new.html.erb +26 -0
  83. data/test/rails_app/app/views/users/sessions/new.html.erb +30 -0
  84. data/test/rails_app/app/views/users/show.html.erb +2 -0
  85. data/test/rails_app/config.ru +4 -0
  86. data/test/rails_app/config/application.rb +43 -0
  87. data/test/rails_app/config/boot.rb +6 -0
  88. data/test/rails_app/config/database.yml +22 -0
  89. data/test/rails_app/config/environment.rb +5 -0
  90. data/test/rails_app/config/environments/development.rb +23 -0
  91. data/test/rails_app/config/environments/production.rb +50 -0
  92. data/test/rails_app/config/environments/test.rb +34 -0
  93. data/test/rails_app/config/initializers/janus.rb +25 -0
  94. data/test/rails_app/config/initializers/secret_token.rb +8 -0
  95. data/test/rails_app/config/initializers/session_store.rb +8 -0
  96. data/test/rails_app/config/locales/janus.en.yml +65 -0
  97. data/test/rails_app/config/routes.rb +13 -0
  98. data/test/rails_app/db/migrate/20110323153820_create_users.rb +40 -0
  99. data/test/rails_app/db/migrate/20110331153546_create_remote_tokens.rb +15 -0
  100. data/test/rails_app/db/migrate/20130412104138_create_admins.rb +10 -0
  101. data/test/rails_app/db/schema.rb +58 -0
  102. data/test/rails_app/db/seeds.rb +7 -0
  103. data/test/rails_app/lib/tasks/.gitkeep +0 -0
  104. data/test/rails_app/public/404.html +26 -0
  105. data/test/rails_app/public/422.html +26 -0
  106. data/test/rails_app/public/500.html +26 -0
  107. data/test/rails_app/script/rails +6 -0
  108. data/test/test_helper.rb +121 -0
  109. data/test/unit/confirmable_test.rb +36 -0
  110. data/test/unit/janus_test.rb +27 -0
  111. data/test/unit/rememberable_test.rb +47 -0
  112. data/test/unit/remote_authenticatable_test.rb +37 -0
  113. data/test/unit/remote_token_test.rb +9 -0
  114. data/test/unit/reset_password_test.rb +45 -0
  115. data/test/unit/token_authenticatable_test.rb +41 -0
  116. data/test/unit/trackable_test.rb +21 -0
  117. data/test/unit/user_test.rb +68 -0
  118. metadata +303 -21
  119. metadata.gz.sig +0 -0
@@ -20,6 +20,8 @@ module Janus
20
20
  extend ActiveSupport::Concern
21
21
 
22
22
  included do
23
+ include Janus::Models::Base unless include?(Janus::Models::Base)
24
+
23
25
  begin
24
26
  attr_protected :remember_token, :remember_created_at
25
27
  rescue
@@ -57,6 +57,8 @@ module Janus
57
57
  extend ActiveSupport::Concern
58
58
 
59
59
  included do |klass|
60
+ include Janus::Models::Base unless include?(Janus::Models::Base)
61
+
60
62
  begin
61
63
  attr_protected :session_token
62
64
  rescue
@@ -1,11 +1,12 @@
1
1
  module Janus
2
2
  module Models
3
3
  module RemoteToken
4
- def self.included(klass)
5
- klass.class_eval do
6
- include Janus::Models::Base
7
- before_save :reset_token
8
- end
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include Janus::Models::Base
8
+
9
+ before_save :reset_token
9
10
  end
10
11
 
11
12
  # Generates an unique token.
@@ -0,0 +1,79 @@
1
+ module Janus
2
+ module Models
3
+ # = TokenAuthenticatable
4
+ #
5
+ # Allows to connect through an unique identifier.
6
+ #
7
+ # The strategy to generate the authentication token is up to you. You may
8
+ # either generate a token when a user is created:
9
+ #
10
+ # before_create :reset_authentication_token
11
+ #
12
+ # or you may change the token whenever a user is saved:
13
+ #
14
+ # before_save :reset_authentification_token
15
+ #
16
+ # or whenever its password is changed:
17
+ #
18
+ # before_save :reset_authentication_token, :if => :encrypted_password_changed?
19
+ #
20
+ # The strategy to invalidate the authentication token is also up to you. You
21
+ # may use a callback or one of the configuration options:
22
+ #
23
+ # - +token_authentication_valid_for+ - number of seconds a token will be
24
+ # valid once created (defaults to nil);
25
+ # - +reusable_authentication_token+ - false to destroy the token once it's
26
+ # consumed (defaults to true).
27
+ #
28
+ module TokenAuthenticatable
29
+ extend ActiveSupport::Concern
30
+
31
+ included do
32
+ include Janus::Models::Base unless include?(Janus::Models::Base)
33
+
34
+ begin
35
+ attr_protected :authentication_token, :token_authentication_valid_for, :reusable_authentication_token
36
+ rescue
37
+ end
38
+
39
+ janus_config :token_authentication_key, :token_authentication_valid_for, :reusable_authentication_token
40
+ end
41
+
42
+ # Generates an unique authentication token and saves the model.
43
+ # Any existing token will be overwritten.
44
+ def reset_authentication_token!
45
+ reset_authentication_token
46
+ save
47
+ end
48
+
49
+ # Generates an unique authentification token.
50
+ def reset_authentication_token
51
+ self.authentication_token = self.class.generate_token(:authentication_token)
52
+ self.authentication_token_created_at = Time.now
53
+ end
54
+
55
+ # Destroys the auth token.
56
+ def destroy_authentication_token!
57
+ update_attribute(:authentication_token, nil)
58
+ end
59
+
60
+ module ClassMethods
61
+ def find_for_token_authentication(token)
62
+ if record = where(:authentication_token => token).first
63
+ if expired_authentication_token?(record)
64
+ record.destroy_authentication_token!
65
+ return
66
+ end
67
+ record.destroy_authentication_token! unless reusable_authentication_token
68
+ record
69
+ end
70
+ end
71
+
72
+ def expired_authentication_token?(record)
73
+ token_authentication_valid_for && record.authentication_token_created_at &&
74
+ record.authentication_token_created_at < Time.now - token_authentication_valid_for
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -18,6 +18,8 @@ module Janus
18
18
  extend ActiveSupport::Concern
19
19
 
20
20
  included do
21
+ include Janus::Models::Base unless include?(Janus::Models::Base)
22
+
21
23
  begin
22
24
  attr_protected :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, :last_sign_in_ip
23
25
  rescue
@@ -26,7 +26,7 @@ module Janus
26
26
  module ClassMethods
27
27
  # Returns the list of strategies as underscore symbols.
28
28
  def strategies
29
- @strategies ||= [:rememberable, :remote_authenticatable]
29
+ @strategies ||= [:rememberable, :remote_authenticatable, :token_authenticatable]
30
30
  end
31
31
  end
32
32
  end
@@ -0,0 +1,22 @@
1
+ module Janus
2
+ module Strategies
3
+ class TokenAuthenticatable < Base
4
+ def valid?
5
+ resource.include?(Janus::Models::TokenAuthenticatable) and !auth_token.nil?
6
+ end
7
+
8
+ def authenticate!
9
+ user = resource.find_for_token_authentication(auth_token)
10
+ if user
11
+ success!(user)
12
+ else
13
+ pass
14
+ end
15
+ end
16
+
17
+ def auth_token
18
+ request.params[resource.token_authentication_key]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ module Janus
2
+ def self.version
3
+ Gem::Version.new File.read(File.expand_path('../../../VERSION', __FILE__))
4
+ end
5
+
6
+ module VERSION
7
+ MAJOR, MINOR, TINY, PRE = Janus.version.segments
8
+ STRING = Janus.version.to_s
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ bob:
2
+ email: "bob@example.com"
3
+ encrypted_password: "$2a$10$MFILoaQqegEY7swhM1KVeu7f1hls.3YhRRvrhWVX/NULJsqpyTLeO"
4
+ # password: "secret"
5
+
@@ -0,0 +1,10 @@
1
+ julien:
2
+ email: "julien@example.com"
3
+ encrypted_password: "$2a$10$MFILoaQqegEY7swhM1KVeu7f1hls.3YhRRvrhWVX/NULJsqpyTLeO"
4
+ # password: "secret"
5
+
6
+ martha:
7
+ email: "martha@fai.fr"
8
+ encrypted_password: "$2a$10$EBsYVyy9rvhC51.5HzQRDet4lh.0hAYwYbM0l6t3x0YfjKFKJNQm6"
9
+ # password: "vacances"
10
+
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ class Admins::SessionsControllerTest < ActionController::TestCase
4
+ setup do
5
+ @valid = { :email => admins(:bob).email, :password => 'secret' }
6
+ end
7
+
8
+ test "return_to when passwords_controller is missing" do
9
+ post :create, :admin => @valid
10
+ assert_redirected_to root_url
11
+ assert_authenticated(:admin)
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class HomeControllerTest < ActionController::TestCase
4
+ test "should get index" do
5
+ get :index
6
+ assert_response :ok
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class Janus::MailerTest < ActionMailer::TestCase
4
+ test "reset_password_instructions" do
5
+ users(:julien).generate_reset_password_token!
6
+
7
+ mail = UserMailer.reset_password_instructions(users(:julien)).deliver
8
+ assert_equal [users(:julien).email], mail.to
9
+ assert !mail.subject.blank?
10
+
11
+ url = edit_user_password_url(:token => users(:julien).reset_password_token)
12
+ assert_match Regexp.new(Regexp.escape(url)), mail.encoded
13
+ end
14
+ end
@@ -0,0 +1,94 @@
1
+ require 'test_helper'
2
+
3
+ class Janus::ManagerTest < ActionController::TestCase
4
+ test "should log user in and out" do
5
+ @janus.login(users(:julien))
6
+ assert @janus.authenticated?(:user), "Expected user to be authenticated."
7
+ assert_equal users(:julien), @janus.user(:user)
8
+
9
+ @janus.logout(:user)
10
+ assert !@janus.authenticated?(:user), "Expected user to not be authenticated."
11
+ assert_nil @janus.user(:user)
12
+ end
13
+
14
+ test "should log user in and out with custom scope" do
15
+ @janus.login(users(:julien), :scope => :custom)
16
+ assert @janus.authenticated?(:custom), "Expected user to be authenticated."
17
+ assert_equal users(:julien), @janus.user(:custom)
18
+
19
+ @janus.logout(:custom)
20
+ assert !@janus.authenticated?(:custom), "Expected user to not be authenticated."
21
+ assert_nil @janus.user(:custom)
22
+ end
23
+
24
+ test "should log users in different scopes" do
25
+ @janus.login(users(:julien), :scope => :user)
26
+ @janus.login(users(:martha), :scope => :admin)
27
+ assert @janus.authenticated?(:user), "Expected user to be authenticated."
28
+ assert @janus.authenticated?(:admin), "Expected admin to be authenticated."
29
+ assert_equal users(:julien), @janus.user(:user)
30
+ assert_equal users(:martha), @janus.user(:admin)
31
+
32
+ @janus.logout(:admin)
33
+ assert @janus.authenticated?(:user), "Expected user to still be authenticated."
34
+ assert !@janus.authenticated?(:admin), "Expected admin to no longer be authenticated."
35
+ assert_equal users(:julien), @janus.user(:user)
36
+ assert_nil @janus.user(:admin)
37
+ end
38
+
39
+ test "should logout all scopes at once" do
40
+ @janus.login(users(:julien), :scope => :user)
41
+ @janus.login(users(:martha), :scope => :admin)
42
+ assert @janus.authenticated?(:user), "Expected user to be authenticated."
43
+ assert @janus.authenticated?(:admin), "Expected admin to be authenticated."
44
+
45
+ @janus.logout
46
+ assert !@janus.authenticated?(:user), "Expected user to no longer be authenticated."
47
+ assert !@janus.authenticated?(:admin), "Expected admin to no longer be authenticated."
48
+ end
49
+
50
+ test "should reset session after logout from last scope" do
51
+ @janus.login(users(:julien), :scope => :user)
52
+ @janus.login(users(:martha), :scope => :admin)
53
+
54
+ @janus.logout(:admin)
55
+ assert_not_nil session['janus']
56
+
57
+ @janus.logout(:user)
58
+ assert_nil session['janus']
59
+ end
60
+
61
+ test "should set and unset the user manually" do
62
+ @janus.set_user(users(:martha))
63
+ assert @janus.authenticated?(:user), "Expected user to be authenticated."
64
+ assert_equal users(:martha), @janus.user(:user)
65
+
66
+ @janus.unset_user(:user)
67
+ assert !@janus.authenticated?(:user), "Expected user to not be authenticated."
68
+ assert_nil @janus.user(:user)
69
+ end
70
+
71
+ test "should set and unset the user manually in different scopes" do
72
+ @janus.set_user(users(:martha), :scope => :user)
73
+ @janus.set_user(users(:julien), :scope => :admin)
74
+ assert @janus.authenticated?(:user), "Expected user to be authenticated."
75
+ assert @janus.authenticated?(:admin), "Expected admin to be authenticated."
76
+ assert_equal users(:martha), @janus.user(:user)
77
+ assert_equal users(:julien), @janus.user(:admin)
78
+
79
+ @janus.unset_user(:user)
80
+ assert !@janus.authenticated?(:user), "Expected user to no longer be authenticated."
81
+ assert @janus.authenticated?(:admin), "Expected admin to still be authenticated."
82
+ assert_nil @janus.user(:user)
83
+ assert_equal users(:julien), @janus.user(:admin)
84
+
85
+ @janus.unset_user(:martha)
86
+ end
87
+
88
+ test "authenticate!" do
89
+ assert_raise(Janus::NotAuthenticated) { @janus.authenticate!(:user) }
90
+
91
+ @janus.set_user(users(:julien))
92
+ assert_nothing_raised { @janus.authenticate!(:user) }
93
+ end
94
+ end
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+
3
+ class Users::ConfirmationsControllerTest < ActionController::TestCase
4
+ test "should get show with token" do
5
+ users(:julien).generate_confirmation_token
6
+ users(:julien).save!
7
+
8
+ assert_difference('User.count(:confirmed_at)') do
9
+ get :show, :confirm_token => users(:julien).confirmation_token
10
+ assert_redirected_to root_url
11
+ assert flash[:notice]
12
+ end
13
+ end
14
+
15
+ test "should not get show without token" do
16
+ assert_no_difference('User.count(:confirmed_at)') do
17
+ get :show
18
+ assert_response :ok
19
+ assert_template 'new'
20
+ assert_select '#error_explanation'
21
+ end
22
+ end
23
+
24
+ test "should not get show with blank token" do
25
+ assert_no_difference('User.count(:confirmed_at)') do
26
+ get :show, :token => ""
27
+ assert_response :ok
28
+ assert_template 'new'
29
+ assert_select '#error_explanation'
30
+ end
31
+ end
32
+
33
+ test "should not get show with bad token" do
34
+ users(:julien).generate_reset_password_token!
35
+
36
+ assert_no_difference('User.count(:confirmed_at)') do
37
+ get :show, :token => "aiorujfqptezjsmdguspfofkn"
38
+ assert_response :ok
39
+ assert_template 'new'
40
+ assert_select '#error_explanation'
41
+ end
42
+ end
43
+
44
+ test "should get new" do
45
+ get :new
46
+ assert_response :ok
47
+ assert_select '#user_email', 1
48
+ end
49
+
50
+ test "should create" do
51
+ assert_email do
52
+ post :create, :user => { :email => users(:julien).email }
53
+ end
54
+
55
+ assert_redirected_to root_url
56
+ assert flash[:notice]
57
+ end
58
+
59
+ test "should not create" do
60
+ assert_no_email do
61
+ post :create, :user => { :email => 'nobody@example.com' }
62
+ end
63
+
64
+ assert_response :ok
65
+ assert_template 'new'
66
+ assert_select '#error_explanation'
67
+ end
68
+ end
@@ -0,0 +1,131 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ class Users::PasswordsControllerTest < ActionController::TestCase
5
+ setup do
6
+ @attributes = {
7
+ :password => "azerty",
8
+ :password_confirmation => "azerty"
9
+ }
10
+ end
11
+
12
+ test "should get new" do
13
+ get :new
14
+ assert_response :ok
15
+ assert_select '#user_email', 1
16
+ end
17
+
18
+ test "should get edit with token" do
19
+ users(:julien).generate_reset_password_token!
20
+
21
+ get :edit, :token => users(:julien).reset_password_token
22
+ assert_response :ok
23
+ assert_select '#user_reset_password_token', 1
24
+ assert_select '#user_password', 1
25
+ assert_select '#user_password_confirmation', 1
26
+ end
27
+
28
+ test "should not get edit without token" do
29
+ get :edit
30
+ assert_redirected_to root_url
31
+ assert flash[:alert]
32
+ end
33
+
34
+ test "should not get edit with blank token" do
35
+ get :edit, :token => ''
36
+ assert_redirected_to root_url
37
+ assert flash[:alert]
38
+ end
39
+
40
+ test "should not get edit with expired token" do
41
+ users(:julien).generate_reset_password_token!
42
+ users(:julien).update_attribute(:reset_password_sent_at, 1.month.ago)
43
+ get :edit, :token => "aiorujfqptezjsmdguspfofkn"
44
+ assert_redirected_to root_url
45
+ assert flash[:alert]
46
+ end
47
+
48
+ test "should not get edit with bad token" do
49
+ users(:julien).generate_reset_password_token!
50
+
51
+ get :edit, :token => "aiorujfqptezjsmdguspfofkn"
52
+ assert_redirected_to root_url
53
+ assert flash[:alert]
54
+ end
55
+
56
+ test "should create" do
57
+ assert_email do
58
+ post :create, :user => { :email => users(:julien).email }
59
+ end
60
+ assert_redirected_to root_url
61
+ assert flash[:notice]
62
+ end
63
+
64
+ test "should not create" do
65
+ assert_no_email do
66
+ post :create, :user => { :email => 'nobody@example.com' }
67
+ end
68
+ assert_response :ok
69
+ assert_template 'new'
70
+ assert_select '#error_explanation'
71
+ end
72
+
73
+ test "should update" do
74
+ users(:julien).generate_reset_password_token!
75
+
76
+ put :update, :user => @attributes.merge(:reset_password_token => users(:julien).reset_password_token)
77
+ assert_redirected_to root_url
78
+ assert flash[:notice]
79
+
80
+ users(:julien).reload
81
+
82
+ assert_nil users(:julien).reset_password_token
83
+ assert_nil users(:julien).reset_password_sent_at
84
+ assert users(:julien).valid_password?(@attributes[:password])
85
+ end
86
+
87
+ test "should not update" do
88
+ users(:julien).generate_reset_password_token!
89
+
90
+ put :update, :user => @attributes.merge(
91
+ :reset_password_token => users(:julien).reset_password_token,
92
+ :password_confirmation => "qwerty"
93
+ )
94
+ assert_response :ok
95
+ assert_template 'users/passwords/edit'
96
+ assert_select '#error_explanation'
97
+
98
+ users(:julien).reload
99
+
100
+ assert_not_nil users(:julien).reset_password_token
101
+ assert_not_nil users(:julien).reset_password_sent_at
102
+ assert !users(:julien).valid_password?(@attributes[:password])
103
+ end
104
+
105
+ test "should not update without token" do
106
+ put :update, :user => @attributes
107
+ assert_redirected_to root_url
108
+ assert flash[:alert]
109
+ end
110
+
111
+ test "should not update with blank token" do
112
+ put :update, :user => @attributes.merge(:reset_password_token => "")
113
+ assert_redirected_to root_url
114
+ assert flash[:alert]
115
+ end
116
+
117
+ test "should not update with bad token" do
118
+ put :update, :user => @attributes.merge(:reset_password_token => "zeouraprsoghpzçtusfgyzmpfojfjbsodifs")
119
+ assert_redirected_to root_url
120
+ assert flash[:alert]
121
+ end
122
+
123
+ test "should not update with expired token" do
124
+ users(:julien).generate_reset_password_token!
125
+ users(:julien).update_attribute(:reset_password_sent_at, 1.month.ago)
126
+
127
+ put :update, :user => @attributes.merge(:reset_password_token => users(:julien).reset_password_token)
128
+ assert_redirected_to root_url
129
+ assert flash[:alert]
130
+ end
131
+ end