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.
- data/README.rdoc +12 -2
- data/app/controllers/devise/invitations_controller.rb +13 -5
- data/app/controllers/devise_invitable/registrations_controller.rb +2 -2
- data/lib/devise_invitable.rb +1 -0
- data/lib/devise_invitable/model.rb +18 -22
- data/lib/devise_invitable/parameter_sanitizer.rb +11 -0
- data/lib/devise_invitable/rails.rb +1 -0
- data/lib/devise_invitable/version.rb +1 -1
- data/lib/generators/active_record/templates/migration.rb +2 -1
- data/test/functional/controller_helpers_test.rb +39 -0
- data/test/functional/registrations_controller_test.rb +59 -0
- data/test/generators/views_generator_test.rb +40 -0
- data/test/generators_test.rb +34 -0
- data/test/integration/invitation_remove_test.rb +29 -0
- data/test/integration/invitation_test.rb +223 -0
- data/test/integration_tests_helper.rb +48 -0
- data/test/mailers/invitation_mail_test.rb +59 -0
- data/test/model_tests_helper.rb +33 -0
- data/test/models/invitable_test.rb +533 -0
- data/test/models_test.rb +74 -0
- data/test/orm/active_record.rb +4 -0
- data/test/orm/mongoid.rb +20 -0
- data/test/rails_app/Rakefile +7 -0
- data/test/rails_app/app/controllers/admins_controller.rb +6 -0
- data/test/rails_app/app/controllers/application_controller.rb +10 -0
- data/test/rails_app/app/controllers/free_invitations_controller.rb +6 -0
- data/test/rails_app/app/controllers/home_controller.rb +4 -0
- data/test/rails_app/app/controllers/users_controller.rb +12 -0
- data/test/rails_app/app/helpers/application_helper.rb +2 -0
- data/test/rails_app/app/models/admin.rb +23 -0
- data/test/rails_app/app/models/octopussy.rb +15 -0
- data/test/rails_app/app/models/user.rb +51 -0
- data/test/rails_app/app/views/admins/new.html.erb +12 -0
- data/test/rails_app/app/views/free_invitations/new.html.erb +12 -0
- data/test/rails_app/app/views/home/index.html.erb +0 -0
- data/test/rails_app/app/views/layouts/application.html.erb +16 -0
- data/test/rails_app/app/views/users/invitations/new.html.erb +15 -0
- data/test/rails_app/config.ru +4 -0
- data/test/rails_app/config/application.rb +24 -0
- data/test/rails_app/config/boot.rb +11 -0
- data/test/rails_app/config/database.yml +22 -0
- data/test/rails_app/config/environment.rb +5 -0
- data/test/rails_app/config/environments/development.rb +25 -0
- data/test/rails_app/config/environments/production.rb +49 -0
- data/test/rails_app/config/environments/test.rb +33 -0
- data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_app/config/initializers/devise.rb +207 -0
- data/test/rails_app/config/initializers/inflections.rb +10 -0
- data/test/rails_app/config/initializers/mime_types.rb +5 -0
- data/test/rails_app/config/initializers/secret_token.rb +7 -0
- data/test/rails_app/config/initializers/session_store.rb +8 -0
- data/test/rails_app/config/initializers/wrap_parameters.rb +14 -0
- data/test/rails_app/config/locales/devise.en.yml +57 -0
- data/test/rails_app/config/locales/en.yml +14 -0
- data/test/rails_app/config/routes.rb +9 -0
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +39 -0
- data/test/rails_app/mongoid.yml +10 -0
- data/test/rails_app/script/rails +6 -0
- data/test/routes_test.rb +20 -0
- data/test/test_helper.rb +24 -0
- metadata +128 -40
- data/app/controllers/devise_invitable/registrations_controller.rb~ +0 -15
- data/lib/devise_invitable.rb~ +0 -65
- data/lib/devise_invitable/controllers/helpers.rb~ +0 -21
- data/lib/devise_invitable/controllers/registrations.rb~ +0 -21
- data/lib/devise_invitable/model.rb~ +0 -224
- 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
|