devise_invitable 1.1.8 → 1.2.1

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.

Potentially problematic release.


This version of devise_invitable might be problematic. Click here for more details.

Files changed (67) hide show
  1. data/README.rdoc +12 -2
  2. data/app/controllers/devise/invitations_controller.rb +13 -5
  3. data/app/controllers/devise_invitable/registrations_controller.rb +2 -2
  4. data/lib/devise_invitable.rb +1 -0
  5. data/lib/devise_invitable/model.rb +18 -22
  6. data/lib/devise_invitable/parameter_sanitizer.rb +11 -0
  7. data/lib/devise_invitable/rails.rb +1 -0
  8. data/lib/devise_invitable/version.rb +1 -1
  9. data/lib/generators/active_record/templates/migration.rb +2 -1
  10. data/test/functional/controller_helpers_test.rb +39 -0
  11. data/test/functional/registrations_controller_test.rb +59 -0
  12. data/test/generators/views_generator_test.rb +40 -0
  13. data/test/generators_test.rb +34 -0
  14. data/test/integration/invitation_remove_test.rb +29 -0
  15. data/test/integration/invitation_test.rb +223 -0
  16. data/test/integration_tests_helper.rb +48 -0
  17. data/test/mailers/invitation_mail_test.rb +59 -0
  18. data/test/model_tests_helper.rb +33 -0
  19. data/test/models/invitable_test.rb +533 -0
  20. data/test/models_test.rb +74 -0
  21. data/test/orm/active_record.rb +4 -0
  22. data/test/orm/mongoid.rb +20 -0
  23. data/test/rails_app/Rakefile +7 -0
  24. data/test/rails_app/app/controllers/admins_controller.rb +6 -0
  25. data/test/rails_app/app/controllers/application_controller.rb +10 -0
  26. data/test/rails_app/app/controllers/free_invitations_controller.rb +6 -0
  27. data/test/rails_app/app/controllers/home_controller.rb +4 -0
  28. data/test/rails_app/app/controllers/users_controller.rb +12 -0
  29. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  30. data/test/rails_app/app/models/admin.rb +23 -0
  31. data/test/rails_app/app/models/octopussy.rb +15 -0
  32. data/test/rails_app/app/models/user.rb +51 -0
  33. data/test/rails_app/app/views/admins/new.html.erb +12 -0
  34. data/test/rails_app/app/views/free_invitations/new.html.erb +12 -0
  35. data/test/rails_app/app/views/home/index.html.erb +0 -0
  36. data/test/rails_app/app/views/layouts/application.html.erb +16 -0
  37. data/test/rails_app/app/views/users/invitations/new.html.erb +15 -0
  38. data/test/rails_app/config.ru +4 -0
  39. data/test/rails_app/config/application.rb +24 -0
  40. data/test/rails_app/config/boot.rb +11 -0
  41. data/test/rails_app/config/database.yml +22 -0
  42. data/test/rails_app/config/environment.rb +5 -0
  43. data/test/rails_app/config/environments/development.rb +25 -0
  44. data/test/rails_app/config/environments/production.rb +49 -0
  45. data/test/rails_app/config/environments/test.rb +33 -0
  46. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  47. data/test/rails_app/config/initializers/devise.rb +207 -0
  48. data/test/rails_app/config/initializers/inflections.rb +10 -0
  49. data/test/rails_app/config/initializers/mime_types.rb +5 -0
  50. data/test/rails_app/config/initializers/secret_token.rb +7 -0
  51. data/test/rails_app/config/initializers/session_store.rb +8 -0
  52. data/test/rails_app/config/initializers/wrap_parameters.rb +14 -0
  53. data/test/rails_app/config/locales/devise.en.yml +57 -0
  54. data/test/rails_app/config/locales/en.yml +14 -0
  55. data/test/rails_app/config/routes.rb +9 -0
  56. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +39 -0
  57. data/test/rails_app/mongoid.yml +10 -0
  58. data/test/rails_app/script/rails +6 -0
  59. data/test/routes_test.rb +20 -0
  60. data/test/test_helper.rb +24 -0
  61. metadata +128 -40
  62. data/app/controllers/devise_invitable/registrations_controller.rb~ +0 -15
  63. data/lib/devise_invitable.rb~ +0 -65
  64. data/lib/devise_invitable/controllers/helpers.rb~ +0 -21
  65. data/lib/devise_invitable/controllers/registrations.rb~ +0 -21
  66. data/lib/devise_invitable/model.rb~ +0 -224
  67. data/lib/devise_invitable/rails.rb~ +0 -21
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+ require 'integration_tests_helper'
3
+
4
+ class InvitationTest < ActionDispatch::IntegrationTest
5
+
6
+ test 'invited user can choose to remove his account/invite' do
7
+ user = User.invite!(:email => "valid@email.com")
8
+
9
+ # remove!
10
+ visit remove_user_invitation_path(:invitation_token => user.invitation_token)
11
+ assert_equal root_path, current_path
12
+ assert page.has_css?('p#notice', :text => 'Your invitation was removed.')
13
+
14
+ # try to remove again!
15
+ visit remove_user_invitation_path(:invitation_token => user.invitation_token)
16
+ assert_equal root_path, current_path
17
+ assert page.has_css?('p#alert', :text => 'The invitation token provided is not valid!')
18
+ end
19
+
20
+ test 'accepted user cannot remove his account (by using the original invitation token)' do
21
+ user = User.invite!(:email => "valid@email.com")
22
+ saved_token = user.invitation_token
23
+ user.accept_invitation!
24
+
25
+ visit remove_user_invitation_path(:invitation_token => saved_token)
26
+ assert_equal root_path, current_path
27
+ assert page.has_css?('p#alert', :text => 'The invitation token provided is not valid!')
28
+ end
29
+ end
@@ -0,0 +1,223 @@
1
+ require 'test_helper'
2
+ require 'integration_tests_helper'
3
+
4
+ class InvitationTest < ActionDispatch::IntegrationTest
5
+ def teardown
6
+ Capybara.reset_sessions!
7
+ end
8
+
9
+ def send_invitation(url = new_user_invitation_path, &block)
10
+ visit url
11
+
12
+ fill_in 'user_email', :with => 'user@test.com'
13
+ yield if block_given?
14
+ click_button 'Send an invitation'
15
+ end
16
+
17
+ def set_password(options={}, &block)
18
+ unless options[:visit] == false
19
+ visit accept_user_invitation_path(:invitation_token => options[:invitation_token])
20
+ end
21
+
22
+ fill_in 'user_password', :with => '987654321'
23
+ fill_in 'user_password_confirmation', :with => '987654321'
24
+ yield if block_given?
25
+ click_button options[:button] || 'Set my password'
26
+ end
27
+
28
+ test 'not authenticated user should be able to send a free invitation' do
29
+ send_invitation new_free_invitation_path
30
+ assert_equal root_path, current_path
31
+ assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
32
+ end
33
+
34
+ test 'not authenticated user should not be able to send an invitation' do
35
+ get new_user_invitation_path
36
+ assert_redirected_to new_user_session_path
37
+ end
38
+
39
+ test 'authenticated user should be able to send an invitation' do
40
+ sign_in_as_user
41
+
42
+ send_invitation
43
+ assert_equal root_path, current_path
44
+ assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
45
+ end
46
+
47
+ test 'authenticated user with existing email should receive an error message' do
48
+ user = create_full_user
49
+ sign_in_as_user(user)
50
+ send_invitation do
51
+ fill_in 'user_email', :with => user.email
52
+ end
53
+
54
+ assert_equal user_invitation_path, current_path
55
+ assert page.has_css?("input[type=text][value='#{user.email}']")
56
+ assert page.has_css?('#error_explanation li', :text => 'Email has already been taken')
57
+ end
58
+
59
+ test 'authenticated user should not be able to visit edit invitation page' do
60
+ sign_in_as_user
61
+
62
+ visit accept_user_invitation_path
63
+
64
+ assert_equal root_path, current_path
65
+ end
66
+
67
+ test 'not authenticated user with invalid invitation token should not be able to set his password' do
68
+ user = User.invite!(:email => "valid@email.com")
69
+ user.accept_invitation!
70
+ visit accept_user_invitation_path(:invitation_token => 'invalid_token')
71
+
72
+ assert_equal root_path, current_path
73
+ assert page.has_css?('p#alert', :text => 'The invitation token provided is not valid!')
74
+ end
75
+
76
+ test 'not authenticated user with valid invitation token but invalid password should not be able to set his password' do
77
+ user = User.invite!(:email => "valid@email.com")
78
+ set_password :invitation_token => user.invitation_token do
79
+ fill_in 'Password confirmation', :with => 'other_password'
80
+ end
81
+ assert_equal user_invitation_path, current_path
82
+ assert page.has_css?('#error_explanation li', :text => /Password .*doesn\'t match/)
83
+ assert_blank user.encrypted_password
84
+ end
85
+
86
+ test 'not authenticated user with valid data should be able to change his password' do
87
+ user = User.invite!(:email => "valid@email.com")
88
+ set_password :invitation_token => user.invitation_token
89
+
90
+ assert_equal root_path, current_path
91
+ assert page.has_css?('p#notice', :text => 'Your password was set successfully. You are now signed in.')
92
+ assert user.reload.valid_password?('987654321')
93
+ end
94
+
95
+ test 'after entering invalid data user should still be able to set his password' do
96
+ user = User.invite!(:email => "valid@email.com")
97
+ set_password :invitation_token => user.invitation_token do
98
+ fill_in 'Password confirmation', :with => 'other_password'
99
+ end
100
+ assert_equal user_invitation_path, current_path
101
+ assert page.has_css?('#error_explanation')
102
+ assert_blank user.encrypted_password
103
+
104
+ set_password :visit => false
105
+ assert page.has_css?('p#notice', :text => 'Your password was set successfully. You are now signed in.')
106
+ assert user.reload.valid_password?('987654321')
107
+ end
108
+
109
+ test 'sign in user automatically after setting it\'s password' do
110
+ user = User.invite!(:email => "valid@email.com")
111
+ set_password :invitation_token => user.invitation_token
112
+ assert_equal root_path, current_path
113
+ end
114
+
115
+ test 'clear token and set invitation_accepted_at after recover password instead of accept_invitation' do
116
+ user = User.invite!(:email => "valid@email.com")
117
+
118
+ visit new_user_password_path
119
+ fill_in 'user_email', :with => 'valid@email.com'
120
+ click_button 'Send me reset password instructions'
121
+
122
+ user.reload
123
+ visit edit_user_password_path(:reset_password_token => user.reset_password_token)
124
+ set_password :visit => false, :button => 'Change my password'
125
+
126
+ user.reload
127
+ assert_nil user.invitation_token
128
+ assert user.invitation_accepted_at
129
+ end
130
+
131
+ test 'user with invites left should be able to send an invitation' do
132
+ User.stubs(:invitation_limit).returns(1)
133
+
134
+ user = create_full_user
135
+ user.invitation_limit = 1
136
+ user.save!
137
+ sign_in_as_user(user)
138
+
139
+ assert_difference 'User.count' do
140
+ send_invitation
141
+ end
142
+ assert_equal root_path, current_path
143
+ assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
144
+ user = User.find(user.id)
145
+ assert !user.has_invitations_left?
146
+ end
147
+
148
+ test 'user with no invites left should not be able to send an invitation' do
149
+ User.stubs(:invitation_limit).returns(1)
150
+
151
+ user = create_full_user
152
+ user.invitation_limit = 0
153
+ user.save!
154
+ sign_in_as_user(user)
155
+
156
+ assert_no_difference 'User.count' do
157
+ send_invitation
158
+ end
159
+ assert_equal user_invitation_path, current_path
160
+ assert page.has_css?('p#alert', :text => 'No invitations remaining')
161
+ end
162
+
163
+ test 'user with nil invitation_limit should default to User.invitation_limit' do
164
+ User.stubs(:invitation_limit).returns(3)
165
+
166
+ user = create_full_user
167
+ assert_nil user[:invitation_limit]
168
+ assert_equal 3, user.invitation_limit
169
+ sign_in_as_user(user)
170
+
171
+ send_invitation
172
+ assert_equal root_path, current_path
173
+ assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
174
+ user = User.find(user.id)
175
+ assert_equal 2, user.invitation_limit
176
+ end
177
+
178
+ test 'should not decrement invitation limit when trying to invite again a user which is invited' do
179
+ User.stubs(:invitation_limit).returns(3)
180
+
181
+ user = create_full_user
182
+ assert_nil user[:invitation_limit]
183
+ assert_equal 3, user.invitation_limit
184
+ sign_in_as_user(user)
185
+
186
+ send_invitation
187
+ assert_equal root_path, current_path
188
+ assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
189
+ user = User.find(user.id)
190
+ assert_equal 2, user.invitation_limit
191
+
192
+ send_invitation
193
+ assert_equal root_path, current_path
194
+ assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
195
+ user = User.find(user.id)
196
+ assert_equal 2, user.invitation_limit
197
+ end
198
+
199
+ test 'invited_by should be set when user invites someone' do
200
+ user = create_full_user
201
+ sign_in_as_user(user)
202
+ send_invitation
203
+
204
+ invited_user = User.where(:email => 'user@test.com').first
205
+ assert invited_user
206
+ assert_equal user, invited_user.invited_by
207
+ end
208
+
209
+ test 'authenticated user should not be able to send an admin invitation' do
210
+ sign_in_as_user
211
+
212
+ get new_admin_path
213
+ assert_redirected_to new_admin_session_path
214
+ end
215
+
216
+ test 'authenticated admin should be able to send an admin invitation' do
217
+ sign_in_as_user Admin.create(:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456')
218
+
219
+ send_invitation new_admin_path
220
+ assert_equal root_path, current_path
221
+ assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
222
+ end
223
+ end
@@ -0,0 +1,48 @@
1
+ class ActionController::IntegrationTest
2
+
3
+ def warden
4
+ request.env['warden']
5
+ end
6
+
7
+ def create_full_user
8
+ @user ||= begin
9
+ user = User.create!(
10
+ :username => 'usertest',
11
+ :email => 'fulluser@test.com',
12
+ :password => '123456',
13
+ :password_confirmation => '123456',
14
+ :created_at => Time.now.utc
15
+ )
16
+ user.confirm!
17
+ user
18
+ end
19
+ end
20
+
21
+ def sign_in_as_user(user = nil)
22
+ user ||= create_full_user
23
+ resource_name = user.class.name.underscore
24
+ visit send("new_#{resource_name}_session_path")
25
+ fill_in "#{resource_name}_email", :with => user.email
26
+ fill_in "#{resource_name}_password", :with => user.password
27
+ click_button 'Sign in'
28
+ end
29
+
30
+ # Fix assert_redirect_to in integration sessions because they don't take into
31
+ # account Middleware redirects.
32
+ #
33
+ def assert_redirected_to(url)
34
+ assert [301, 302].include?(@integration_session.status),
35
+ "Expected status to be 301 or 302, got #{@integration_session.status}"
36
+
37
+ url = prepend_host(url)
38
+ location = prepend_host(@integration_session.headers["Location"])
39
+ assert_equal url, location
40
+ end
41
+
42
+ protected
43
+
44
+ def prepend_host(url)
45
+ url = "http://#{request.host}#{url}" if url[0] == ?/
46
+ url
47
+ end
48
+ end
@@ -0,0 +1,59 @@
1
+ require 'test_helper'
2
+ require 'model_tests_helper'
3
+
4
+ class InvitationMailTest < ActionMailer::TestCase
5
+
6
+ def setup
7
+ setup_mailer
8
+ Devise.mailer_sender = 'test@example.com'
9
+ end
10
+
11
+ def user
12
+ @user ||= User.invite!(:email => "valid@email.com")
13
+ end
14
+
15
+ def mail
16
+ @mail ||= begin
17
+ user
18
+ ActionMailer::Base.deliveries.last
19
+ end
20
+ end
21
+
22
+ test 'email sent after reseting the user password' do
23
+ assert_not_nil mail
24
+ end
25
+
26
+ test 'content type should be set to html' do
27
+ assert_equal 'text/html; charset=UTF-8', mail.content_type
28
+ end
29
+
30
+ test 'send invitation to the user email' do
31
+ assert_equal [user.email], mail.to
32
+ end
33
+
34
+ test 'setup sender from configuration' do
35
+ assert_equal ['test@example.com'], mail.from
36
+ end
37
+
38
+ test 'setup subject from I18n' do
39
+ store_translations :en, :devise => { :mailer => { :invitation_instructions => { :subject => 'Localized Invitation' } } } do
40
+ assert_equal 'Localized Invitation', mail.subject
41
+ end
42
+ end
43
+
44
+ test 'subject namespaced by model' do
45
+ store_translations :en, :devise => { :mailer => { :invitation_instructions => { :user_subject => 'User Invitation' } } } do
46
+ assert_equal 'User Invitation', mail.subject
47
+ end
48
+ end
49
+
50
+ test 'body should have user info' do
51
+ assert_match /#{user.email}/, mail.body.decoded
52
+ end
53
+
54
+ test 'body should have link to confirm the account' do
55
+ host = ActionMailer::Base.default_url_options[:host]
56
+ invitation_url_regexp = %r{<a href=\"http://#{host}/users/invitation/accept\?invitation_token=#{user.invitation_token}">}
57
+ assert_match invitation_url_regexp, mail.body.decoded
58
+ end
59
+ end
@@ -0,0 +1,33 @@
1
+ class ActiveSupport::TestCase
2
+ def setup_mailer
3
+ ActionMailer::Base.deliveries = []
4
+ end
5
+
6
+ def store_translations(locale, translations, &block)
7
+ begin
8
+ I18n.backend.store_translations locale, translations
9
+ yield
10
+ ensure
11
+ I18n.reload!
12
+ end
13
+ end
14
+
15
+ # Helpers for creating new users
16
+ #
17
+ def generate_unique_email
18
+ @@email_count ||= 0
19
+ @@email_count += 1
20
+ "test#{@@email_count}@email.com"
21
+ end
22
+
23
+ def valid_attributes(attributes={})
24
+ { :email => generate_unique_email,
25
+ :password => '123456',
26
+ :password_confirmation => '123456' }.update(attributes)
27
+ end
28
+
29
+ def new_user(attributes={})
30
+ User.new(valid_attributes(attributes))
31
+ end
32
+
33
+ end
@@ -0,0 +1,533 @@
1
+ require 'test_helper'
2
+ require 'model_tests_helper'
3
+
4
+ class InvitableTest < ActiveSupport::TestCase
5
+
6
+ def setup
7
+ setup_mailer
8
+ end
9
+
10
+ test 'should not generate invitation token after creating a record' do
11
+ assert_nil new_user.invitation_token
12
+ end
13
+
14
+ test 'should not regenerate invitation token each time' do
15
+ user = new_user
16
+ user.invite!
17
+ token = user.invitation_token
18
+ assert_not_nil user.invitation_token
19
+ assert_not_nil user.invitation_created_at
20
+ 3.times do
21
+ user.invite!
22
+ assert_equal token, user.invitation_token
23
+ end
24
+ end
25
+
26
+ test 'should set invitation created and sent at each time' do
27
+ user = new_user
28
+ user.invite!
29
+ old_invitation_created_at = 3.days.ago
30
+ old_invitation_sent_at = 3.days.ago
31
+ user.update_attributes(:invitation_sent_at => old_invitation_sent_at, :invitation_created_at => old_invitation_created_at)
32
+ 3.times do
33
+ user.invite!
34
+ assert_not_equal old_invitation_sent_at, user.invitation_sent_at
35
+ assert_not_equal old_invitation_created_at, user.invitation_sent_at
36
+ user.update_attributes(:invitation_sent_at => old_invitation_sent_at, :invitation_created_at => old_invitation_created_at)
37
+ end
38
+ end
39
+
40
+ test 'should not regenerate invitation token even after the invitation token is not valid' do
41
+ User.stubs(:invite_for).returns(1.day)
42
+ user = new_user
43
+ user.invite!
44
+ token = user.invitation_token
45
+ user.invitation_created_at = 3.days.ago
46
+ user.save
47
+ user.invite!
48
+ assert_equal token, user.invitation_token
49
+ end
50
+
51
+ test 'should test invitation sent at with invite_for configuration value' do
52
+ user = User.invite!(:email => "valid@email.com")
53
+
54
+ User.stubs(:invite_for).returns(nil)
55
+ user.invitation_created_at = Time.now.utc
56
+ assert user.valid_invitation?
57
+
58
+ User.stubs(:invite_for).returns(nil)
59
+ user.invitation_created_at = 1.year.ago
60
+ assert user.valid_invitation?
61
+
62
+ User.stubs(:invite_for).returns(0)
63
+ user.invitation_created_at = Time.now.utc
64
+ assert user.valid_invitation?
65
+
66
+ User.stubs(:invite_for).returns(0)
67
+ user.invitation_created_at = 1.day.ago
68
+ assert user.valid_invitation?
69
+
70
+ User.stubs(:invite_for).returns(1.day)
71
+ user.invitation_created_at = Time.now.utc
72
+ assert user.valid_invitation?
73
+
74
+ User.stubs(:invite_for).returns(1.day)
75
+ user.invitation_created_at = 2.days.ago
76
+ assert !user.valid_invitation?
77
+ end
78
+
79
+ test 'should never generate the same invitation token for different users' do
80
+ invitation_tokens = []
81
+ 3.times do
82
+ user = new_user
83
+ user.invite!
84
+ token = user.invitation_token
85
+ assert !invitation_tokens.include?(token)
86
+ invitation_tokens << token
87
+ end
88
+ end
89
+
90
+ test 'should invite with mutiple columns for invite key' do
91
+ User.stubs(:invite_key).returns(:email => Devise.email_regexp, :username => /\A.+\z/)
92
+ user = User.invite!(:email => "valid@email.com", :username => "name")
93
+ assert user.persisted?
94
+ assert user.errors.empty?
95
+ end
96
+
97
+ test 'should not invite with some missing columns when invite key is an array' do
98
+ User.stubs(:invite_key).returns(:email => Devise.email_regexp, :username => /\A.+\z/)
99
+ user = User.invite!(:email => "valid@email.com")
100
+ assert user.new_record?
101
+ assert user.errors.present?
102
+ end
103
+
104
+ test 'should return mail object' do
105
+ mail = User.invite_mail!(:email => 'valid@email.com')
106
+ assert mail.class.name == 'Mail::Message'
107
+ end
108
+
109
+ test 'should disallow login when invited' do
110
+ invited_user = User.invite!(:email => "valid@email.com")
111
+ assert !invited_user.valid_password?('1234')
112
+ end
113
+
114
+ test 'should set password and password confirmation from params' do
115
+ invited_user = User.invite!(:email => "valid@email.com")
116
+ user = User.accept_invitation!(:invitation_token => invited_user.invitation_token, :password => '123456789', :password_confirmation => '123456789')
117
+ assert user.valid_password?('123456789')
118
+ end
119
+
120
+ test 'should set password and save the record' do
121
+ user = User.invite!(:email => "valid@email.com")
122
+ old_encrypted_password = user.encrypted_password
123
+ user = User.accept_invitation!(:invitation_token => user.invitation_token, :password => '123456789', :password_confirmation => '123456789')
124
+ assert_not_equal old_encrypted_password, user.encrypted_password
125
+ end
126
+
127
+ test 'should clear invitation token and set invitation_accepted_at while accepting the password' do
128
+ user = User.invite!(:email => "valid@email.com")
129
+ assert_present user.invitation_token
130
+ assert_nil user.invitation_accepted_at
131
+ user.accept_invitation!
132
+ user.reload
133
+ assert_nil user.invitation_token
134
+ assert_present user.invitation_accepted_at
135
+ end
136
+
137
+ test 'should not clear invitation token or set accepted_at if record is invalid' do
138
+ user = User.invite!(:email => "valid@email.com")
139
+ assert_present user.invitation_token
140
+ assert_nil user.invitation_accepted_at
141
+ User.accept_invitation!(:invitation_token => user.invitation_token, :password => '123456789', :password_confirmation => '987654321')
142
+ user.reload
143
+ assert_present user.invitation_token
144
+ assert_nil user.invitation_accepted_at
145
+ end
146
+
147
+ test 'should clear invitation token while resetting the password' do
148
+ user = User.invite!(:email => "valid@email.com")
149
+ assert user.invited_to_sign_up?
150
+ user.send(:generate_reset_password_token!)
151
+ assert_present user.reset_password_token
152
+ assert_present user.invitation_token
153
+ User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '123456789', :password_confirmation => '123456789')
154
+ assert_nil user.reload.invitation_token
155
+ assert !user.invited_to_sign_up?
156
+ end
157
+
158
+ test 'should not accept invitation on failing to reset the password' do
159
+ user = User.invite!(:email => "valid@email.com")
160
+ assert user.invited_to_sign_up?
161
+ user.send(:generate_reset_password_token!)
162
+ assert_present user.reset_password_token
163
+ assert_present user.invitation_token
164
+ User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '123456789', :password_confirmation => '12345678')
165
+ assert_present user.reload.invitation_token
166
+ assert user.invited_to_sign_up?
167
+ end
168
+
169
+ test 'should not set invitation_accepted_at if just resetting password' do
170
+ user = User.create!(:email => "valid@email.com", :password => "123456780")
171
+ assert !user.invited_to_sign_up?
172
+ user.send(:generate_reset_password_token!)
173
+ assert_present user.reset_password_token
174
+ assert_nil user.invitation_token
175
+ User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '123456789', :password_confirmation => '123456789')
176
+ assert_nil user.reload.invitation_token
177
+ assert_nil user.reload.invitation_accepted_at
178
+ end
179
+
180
+ test 'should reset invitation token and send invitation by email' do
181
+ user = new_user
182
+ assert_difference('ActionMailer::Base.deliveries.size') do
183
+ token = user.invitation_token
184
+ user.invite!
185
+ assert_not_equal token, user.invitation_token
186
+ end
187
+ end
188
+
189
+ test 'should return a record with invitation token and no errors to send invitation by email' do
190
+ invited_user = User.invite!(:email => "valid@email.com")
191
+ assert invited_user.errors.blank?
192
+ assert_present invited_user.invitation_token
193
+ assert_equal 'valid@email.com', invited_user.email
194
+ assert invited_user.persisted?
195
+ end
196
+
197
+ test 'should set all attributes with no errors' do
198
+ invited_user = User.invite!(:email => "valid@email.com", :username => 'first name')
199
+ assert invited_user.errors.blank?
200
+ assert_equal 'first name', invited_user.username
201
+ assert invited_user.persisted?
202
+ end
203
+
204
+ test 'should not validate other attributes when validate_on_invite is disabled' do
205
+ validate_on_invite = User.validate_on_invite
206
+ User.validate_on_invite = false
207
+ invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50)
208
+ assert invited_user.errors.empty?
209
+ User.validate_on_invite = validate_on_invite
210
+ end
211
+
212
+ test 'should validate other attributes when validate_on_invite is enabled' do
213
+ validate_on_invite = User.validate_on_invite
214
+ User.validate_on_invite = true
215
+ invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50)
216
+ assert invited_user.errors[:username].present?
217
+ User.validate_on_invite = validate_on_invite
218
+ end
219
+
220
+ test 'should not validate password when validate_on_invite is enabled' do
221
+ validate_on_invite = User.validate_on_invite
222
+ User.validate_on_invite = true
223
+ invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50)
224
+ assert invited_user.errors.present?
225
+ assert invited_user.errors[:password].empty?
226
+ User.validate_on_invite = validate_on_invite
227
+ end
228
+
229
+ test 'should validate other attributes when validate_on_invite is enabled and email is not present' do
230
+ validate_on_invite = User.validate_on_invite
231
+ User.validate_on_invite = true
232
+ invited_user = User.invite!(:email => "", :username => "a"*50)
233
+ assert invited_user.errors[:email].present?
234
+ assert invited_user.errors[:username].present?
235
+ User.validate_on_invite = validate_on_invite
236
+ end
237
+
238
+ test 'should return a record with errors if user was found by e-mail' do
239
+ existing_user = User.new(:email => "valid@email.com")
240
+ existing_user.save(:validate => false)
241
+ user = User.invite!(:email => "valid@email.com")
242
+ assert_equal user, existing_user
243
+ assert_equal ['has already been taken'], user.errors[:email]
244
+ end
245
+
246
+ test 'should return a record with errors if user with pending invitation was found by e-mail' do
247
+ existing_user = User.invite!(:email => "valid@email.com")
248
+ user = User.invite!(:email => "valid@email.com")
249
+ assert_equal user, existing_user
250
+ assert_equal [], user.errors[:email]
251
+ resend_invitation = User.resend_invitation
252
+ begin
253
+ User.resend_invitation = false
254
+
255
+ user = User.invite!(:email => "valid@email.com")
256
+ assert_equal user, existing_user
257
+ assert_equal ['has already been taken'], user.errors[:email]
258
+ ensure
259
+ User.resend_invitation = resend_invitation
260
+ end
261
+ end
262
+
263
+ test 'should return a record with errors if user was found by e-mail with validate_on_invite' do
264
+ begin
265
+ validate_on_invite = User.validate_on_invite
266
+ User.validate_on_invite = true
267
+ existing_user = User.new(:email => "valid@email.com")
268
+ existing_user.save(:validate => false)
269
+ user = User.invite!(:email => "valid@email.com", :username => "a"*50)
270
+ assert_equal user, existing_user
271
+ assert_equal ['has already been taken'], user.errors[:email]
272
+ assert user.errors[:username].present?
273
+ ensure
274
+ User.validate_on_invite = validate_on_invite
275
+ end
276
+ end
277
+
278
+ test 'should return a new record with errors if e-mail is blank' do
279
+ invited_user = User.invite!(:email => '')
280
+ assert invited_user.new_record?
281
+ assert_equal ["can't be blank"], invited_user.errors[:email]
282
+ end
283
+
284
+ test 'should return a new record with errors if e-mail is invalid' do
285
+ invited_user = User.invite!(:email => 'invalid_email')
286
+ assert invited_user.new_record?
287
+ assert_equal ["is invalid"], invited_user.errors[:email]
288
+ end
289
+
290
+ test 'should set all attributes with errors if e-mail is invalid' do
291
+ invited_user = User.invite!(:email => "invalid_email.com", :username => 'first name')
292
+ assert invited_user.new_record?
293
+ assert_equal 'first name', invited_user.username
294
+ assert invited_user.errors.present?
295
+ end
296
+
297
+ test 'should find a user to set his password based on invitation_token' do
298
+ user = new_user
299
+ user.invite!
300
+ invited_user = User.accept_invitation!(:invitation_token => user.invitation_token)
301
+ assert_equal invited_user, user
302
+ end
303
+
304
+ test 'should return a new record with errors if no invitation_token is found' do
305
+ invited_user = User.accept_invitation!(:invitation_token => 'invalid_token')
306
+ assert invited_user.new_record?
307
+ assert_equal ['is invalid'], invited_user.errors[:invitation_token]
308
+ end
309
+
310
+ test 'should return a new record with errors if invitation_token is blank' do
311
+ invited_user = User.accept_invitation!(:invitation_token => '')
312
+ assert invited_user.new_record?
313
+ assert_equal ["can't be blank"], invited_user.errors[:invitation_token]
314
+ end
315
+
316
+ test 'should return record with errors if invitation_token has expired' do
317
+ User.stubs(:invite_for).returns(10.hours)
318
+ invited_user = User.invite!(:email => "valid@email.com")
319
+ invited_user.invitation_created_at = 2.days.ago
320
+ invited_user.save(:validate => false)
321
+ user = User.accept_invitation!(:invitation_token => invited_user.invitation_token)
322
+ assert_equal user, invited_user
323
+ assert_equal ["is invalid"], user.errors[:invitation_token]
324
+ end
325
+
326
+ test 'should allow record modification using block' do
327
+ invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50) do |u|
328
+ u.password = '123123'
329
+ u.password_confirmation = '123123'
330
+ end
331
+ assert_equal '123123', invited_user.reload.password
332
+ end
333
+
334
+ test 'should set successfully user password given the new password and confirmation' do
335
+ user = new_user(:password => nil, :password_confirmation => nil)
336
+ user.invite!
337
+
338
+ invited_user = User.accept_invitation!(
339
+ :invitation_token => user.invitation_token,
340
+ :password => 'new_password',
341
+ :password_confirmation => 'new_password'
342
+ )
343
+ user.reload
344
+
345
+ assert user.valid_password?('new_password')
346
+ end
347
+
348
+ test 'should return errors on other attributes even when password is valid' do
349
+ user = new_user(:password => nil, :password_confirmation => nil)
350
+ user.invite!
351
+
352
+ invited_user = User.accept_invitation!(
353
+ :invitation_token => user.invitation_token,
354
+ :password => 'new_password',
355
+ :password_confirmation => 'new_password',
356
+ :username => 'a'*50
357
+ )
358
+ assert invited_user.errors[:username].present?
359
+
360
+ assert !user.valid_password?('new_password')
361
+ end
362
+
363
+ test 'should not confirm user on invite' do
364
+ user = new_user
365
+
366
+ user.invite!
367
+
368
+ assert !user.confirmed?
369
+ end
370
+
371
+ test 'user.has_invitations_left? test' do
372
+ # By default with invitation_limit nil, users can send unlimited invitations
373
+ user = new_user
374
+ assert_nil user.invitation_limit
375
+ assert user.has_invitations_left?
376
+
377
+ # With invitation_limit set to a value, all users can send that many invitations
378
+ User.stubs(:invitation_limit).returns(2)
379
+ assert user.has_invitations_left?
380
+
381
+ # With an individual invitation_limit of 0, a user shouldn't be able to send an invitation
382
+ user.invitation_limit = 0
383
+ assert user.save
384
+ assert !user.has_invitations_left?
385
+
386
+ # With in invitation_limit of 2, a user should be able to send two invitations
387
+ user.invitation_limit = 2
388
+ assert user.save
389
+ assert user.has_invitations_left?
390
+ end
391
+
392
+ test 'should not send an invitation if we want to skip the invitation' do
393
+ assert_no_difference('ActionMailer::Base.deliveries.size') do
394
+ invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50, :skip_invitation => true)
395
+ end
396
+ end
397
+
398
+ test 'should not send an invitation if we want to skip the invitation with block' do
399
+ assert_no_difference('ActionMailer::Base.deliveries.size') do
400
+ invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50) do |u|
401
+ u.skip_invitation = true
402
+ end
403
+ end
404
+ end
405
+
406
+ test 'user.invite! should not send an invitation if we want to skip the invitation' do
407
+ user = new_user
408
+ user.skip_invitation = true
409
+ assert_no_difference('ActionMailer::Base.deliveries.size') do
410
+ user.invite!
411
+ end
412
+ assert_present user.invitation_created_at
413
+ assert_nil user.invitation_sent_at
414
+ end
415
+
416
+ test 'user.invite! should not set the invited_by attribute if not passed' do
417
+ user = new_user
418
+ user.invite!
419
+ assert_equal nil, user.invited_by
420
+ end
421
+
422
+ test 'user.invite! should set the invited_by attribute if passed' do
423
+ user = new_user
424
+ inviting_user = User.new(:email => "valid@email.com")
425
+ inviting_user.save(:validate => false)
426
+ user.invite!(inviting_user)
427
+ assert_equal inviting_user, user.invited_by
428
+ assert_equal inviting_user.class.to_s, user.invited_by_type
429
+ end
430
+
431
+ test 'user.accept_invitation! should trigger callbacks' do
432
+ user = User.invite!(:email => "valid@email.com")
433
+ assert_callbacks_not_fired user
434
+ user.accept_invitation!
435
+ assert_callbacks_fired user
436
+ end
437
+
438
+ test 'user.accept_invitation! should not trigger callbacks if validation fails' do
439
+ user = User.invite!(:email => "valid@email.com")
440
+ assert_callbacks_not_fired user
441
+ user.username='a'*50
442
+ user.accept_invitation!
443
+ assert_callbacks_not_fired user
444
+ end
445
+
446
+ test 'user.accept_invitation! should confirm user if confirmable' do
447
+ user = User.invite!(:email => "valid@email.com")
448
+ user.accept_invitation!
449
+
450
+ assert user.confirmed?
451
+ end
452
+
453
+ test 'user.accept_invitation! should not confirm user if validation fails' do
454
+ user = User.invite!(:email => "valid@email.com")
455
+ user.username='a'*50
456
+ user.accept_invitation!
457
+
458
+ assert !user.confirmed?
459
+ end
460
+
461
+ def assert_callbacks_fired(user)
462
+ assert_callbacks_status user, true
463
+ end
464
+
465
+ def assert_callbacks_not_fired(user)
466
+ assert_callbacks_status user, nil
467
+ end
468
+
469
+ def assert_callbacks_status(user, fired)
470
+ assert_equal fired, user.callback_works
471
+ end
472
+
473
+ test "user.invite! should downcase the class's case_insensitive_keys" do
474
+ # Devise default is :email
475
+ user = User.invite!(:email => "UPPERCASE@email.com")
476
+ assert user.email == "uppercase@email.com"
477
+ end
478
+
479
+ test "user.invite! should strip whitespace from the class's strip_whitespace_keys" do
480
+ # Devise default is email
481
+ user = User.invite!(:email => " valid@email.com ")
482
+ assert user.email == "valid@email.com"
483
+ end
484
+
485
+ test 'should pass validation before accept if field is required in post-invited instance' do
486
+ user = User.invite!(:email => "valid@email.com")
487
+ user.testing_accepting_or_not_invited = true
488
+ assert_equal true, user.valid?
489
+ end
490
+
491
+ test 'should fail validation after accept if field is required in post-invited instance' do
492
+ user = User.invite!(:email => "valid@email.com")
493
+ user.testing_accepting_or_not_invited = true
494
+ user.accept_invitation!
495
+ assert_equal false, user.valid?
496
+ end
497
+
498
+ test 'should pass validation after accept if field is required in post-invited instance' do
499
+ user = User.invite!(:email => "valid@email.com")
500
+ user.username = 'test'
501
+ user.testing_accepting_or_not_invited = true
502
+ user.bio = "Test"
503
+ user.accept_invitation!
504
+ assert_equal true, user.valid?
505
+ end
506
+
507
+ test 'should return instance with errors if invitation_token is nil' do
508
+ registered_user = User.create(:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456')
509
+ user = User.accept_invitation!
510
+ assert !user.errors.empty?
511
+ end
512
+
513
+ test "should count accepted and not accepted invitations" do
514
+ assert_equal 0, User.invitation_not_accepted.count
515
+ assert_equal 0, User.invitation_accepted.count
516
+
517
+ User.invite!(:email => "invalid@email.com")
518
+ user = User.invite!(:email => "valid@email.com")
519
+
520
+ assert_equal 2, User.invitation_not_accepted.count
521
+ assert_equal 0, User.invitation_accepted.count
522
+
523
+ user.accept_invitation!
524
+ assert_equal 1, User.invitation_not_accepted.count
525
+ assert_equal 1, User.invitation_accepted.count
526
+ end
527
+
528
+ test "should preserve return values of Devise::Recoverable#reset_password!" do
529
+ user = new_user
530
+ retval = user.reset_password!('anewpassword', 'anewpassword')
531
+ assert_equal true, retval
532
+ end
533
+ end