headstart 0.1.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.
- data/LICENSE +20 -0
- data/README.rdoc +117 -0
- data/Rakefile +95 -0
- data/VERSION +1 -0
- data/app/controllers/headstart/confirmations_controller.rb +76 -0
- data/app/controllers/headstart/impersonations_controller.rb +44 -0
- data/app/controllers/headstart/passwords_controller.rb +93 -0
- data/app/controllers/headstart/sessions_controller.rb +76 -0
- data/app/controllers/headstart/users_controller.rb +85 -0
- data/app/models/deliver_change_password_job.rb +19 -0
- data/app/models/deliver_welcome_job.rb +17 -0
- data/app/models/generic_mailer.rb +31 -0
- data/app/models/headstart_mailer.rb +28 -0
- data/app/models/impersonation.rb +26 -0
- data/app/models/mimi_mailer.rb +30 -0
- data/app/views/generic_mailer/change_password.html.erb +9 -0
- data/app/views/generic_mailer/confirmation.html.erb +5 -0
- data/app/views/generic_mailer/welcome.html.erb +1 -0
- data/app/views/impersonations/index.html.erb +5 -0
- data/app/views/passwords/edit.html.erb +23 -0
- data/app/views/passwords/new.html.erb +15 -0
- data/app/views/sessions/new.html.erb +48 -0
- data/app/views/users/_form.html.erb +21 -0
- data/app/views/users/edit.html.erb +6 -0
- data/app/views/users/new.html.erb +6 -0
- data/app/views/users/show.html.erb +8 -0
- data/generators/headstart/USAGE +1 -0
- data/generators/headstart/headstart_generator.rb +86 -0
- data/generators/headstart/lib/insert_commands.rb +33 -0
- data/generators/headstart/lib/rake_commands.rb +22 -0
- data/generators/headstart/templates/README +20 -0
- data/generators/headstart/templates/app/controllers/sessions_controller.rb +6 -0
- data/generators/headstart/templates/app/views/sessions/index.html.erb +1 -0
- data/generators/headstart/templates/application.html.erb +75 -0
- data/generators/headstart/templates/factories.rb +23 -0
- data/generators/headstart/templates/headstart.rb +25 -0
- data/generators/headstart/templates/headstart.yml +45 -0
- data/generators/headstart/templates/layout.css +353 -0
- data/generators/headstart/templates/migrations/create_users.rb +26 -0
- data/generators/headstart/templates/migrations/update_users.rb +44 -0
- data/generators/headstart/templates/report.css +69 -0
- data/generators/headstart/templates/reset.css +1 -0
- data/generators/headstart/templates/style.css +31 -0
- data/generators/headstart/templates/text.css +1 -0
- data/generators/headstart/templates/user.rb +3 -0
- data/generators/headstart/templates/xd_receiver.html +10 -0
- data/generators/headstart/templates/xd_receiver_ssl.html +10 -0
- data/generators/headstart_admin/USAGE +1 -0
- data/generators/headstart_admin/headstart_admin_generator.rb +32 -0
- data/generators/headstart_admin/lib/insert_commands.rb +33 -0
- data/generators/headstart_admin/templates/README +16 -0
- data/generators/headstart_admin/templates/app/controllers/admin/admin_controller.rb +17 -0
- data/generators/headstart_admin/templates/app/controllers/admin/users_controller.rb +52 -0
- data/generators/headstart_admin/templates/app/views/admin/admin/index.html.erb +2 -0
- data/generators/headstart_admin/templates/app/views/admin/users/_form.html.erb +25 -0
- data/generators/headstart_admin/templates/app/views/admin/users/edit.html.erb +6 -0
- data/generators/headstart_admin/templates/app/views/admin/users/index.html.erb +7 -0
- data/generators/headstart_admin/templates/app/views/admin/users/new.html.erb +6 -0
- data/generators/headstart_admin/templates/app/views/admin/users/show.html.erb +10 -0
- data/generators/headstart_admin/templates/test/integration/admin/users_test.rb +201 -0
- data/generators/headstart_tests/USAGE +1 -0
- data/generators/headstart_tests/headstart_tests_generator.rb +21 -0
- data/generators/headstart_tests/templates/README +58 -0
- data/generators/headstart_tests/templates/test/integration/edit_profile_test.rb +35 -0
- data/generators/headstart_tests/templates/test/integration/facebook_test.rb +61 -0
- data/generators/headstart_tests/templates/test/integration/impersonation_test.rb +39 -0
- data/generators/headstart_tests/templates/test/integration/password_reset_test.rb +128 -0
- data/generators/headstart_tests/templates/test/integration/sign_in_test.rb +66 -0
- data/generators/headstart_tests/templates/test/integration/sign_out_test.rb +28 -0
- data/generators/headstart_tests/templates/test/integration/sign_up_test.rb +47 -0
- data/lib/headstart/authentication.rb +138 -0
- data/lib/headstart/configuration.rb +34 -0
- data/lib/headstart/extensions/errors.rb +6 -0
- data/lib/headstart/extensions/rescue.rb +5 -0
- data/lib/headstart/routes.rb +67 -0
- data/lib/headstart/user.rb +279 -0
- data/lib/headstart.rb +7 -0
- data/rails/init.rb +4 -0
- data/shoulda_macros/headstart.rb +244 -0
- data/test/controllers/passwords_controller_test.rb +184 -0
- data/test/controllers/sessions_controller_test.rb +129 -0
- data/test/controllers/users_controller_test.rb +57 -0
- data/test/models/headstart_mailer_test.rb +52 -0
- data/test/models/impersonation_test.rb +25 -0
- data/test/models/user_test.rb +213 -0
- data/test/rails_root/app/controllers/accounts_controller.rb +10 -0
- data/test/rails_root/app/controllers/application_controller.rb +6 -0
- data/test/rails_root/app/helpers/application_helper.rb +5 -0
- data/test/rails_root/app/helpers/confirmations_helper.rb +2 -0
- data/test/rails_root/app/helpers/passwords_helper.rb +2 -0
- data/test/rails_root/config/boot.rb +110 -0
- data/test/rails_root/config/environment.rb +22 -0
- data/test/rails_root/config/environments/development.rb +19 -0
- data/test/rails_root/config/environments/production.rb +1 -0
- data/test/rails_root/config/environments/test.rb +37 -0
- data/test/rails_root/config/initializers/inflections.rb +10 -0
- data/test/rails_root/config/initializers/mime_types.rb +5 -0
- data/test/rails_root/config/initializers/requires.rb +13 -0
- data/test/rails_root/config/initializers/time_formats.rb +4 -0
- data/test/rails_root/config/routes.rb +9 -0
- data/test/rails_root/public/dispatch.rb +10 -0
- data/test/rails_root/script/create_project.rb +52 -0
- data/test/rails_root/test/functional/accounts_controller_test.rb +23 -0
- data/test/test_helper.rb +21 -0
- metadata +232 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
module Headstart
|
|
2
|
+
module Shoulda
|
|
3
|
+
|
|
4
|
+
# STATE OF AUTHENTICATION
|
|
5
|
+
|
|
6
|
+
def should_be_signed_in_as(&block)
|
|
7
|
+
warn "[DEPRECATION] should_be_signed_in_as cannot be used in functional tests anymore now that it depends on cookies, which are unavailable until the next request."
|
|
8
|
+
should "be signed in as #{block.bind(self).call}" do
|
|
9
|
+
user = block.bind(self).call
|
|
10
|
+
assert_not_nil user,
|
|
11
|
+
"please pass a User. try: should_be_signed_in_as { @user }"
|
|
12
|
+
assert_equal user, @controller.send(:current_user),
|
|
13
|
+
"#{user.inspect} is not the current_user, " <<
|
|
14
|
+
"which is #{@controller.send(:current_user).inspect}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def should_not_be_signed_in
|
|
19
|
+
warn "[DEPRECATION] should_not_be_signed_in is no longer a valid test since we now store a remember_token in cookies, not user_id in session"
|
|
20
|
+
should "not be signed in" do
|
|
21
|
+
assert_nil session[:user_id]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def should_deny_access_on(http_method, action, opts = {})
|
|
26
|
+
warn "[DEPRECATION] should_deny_access_on: use a setup & should_deny_access(:flash => ?)"
|
|
27
|
+
flash_message = opts.delete(:flash)
|
|
28
|
+
context "on #{http_method} to #{action}" do
|
|
29
|
+
setup do
|
|
30
|
+
send(http_method, action, opts)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
should_deny_access(:flash => flash_message)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def should_deny_access(opts = {})
|
|
38
|
+
if opts[:flash]
|
|
39
|
+
should_set_the_flash_to opts[:flash]
|
|
40
|
+
else
|
|
41
|
+
should_not_set_the_flash
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
should_redirect_to('sign in page') { sign_in_url }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# HTTP FLUENCY
|
|
48
|
+
|
|
49
|
+
def should_forbid(description, &block)
|
|
50
|
+
should "forbid #{description}" do
|
|
51
|
+
assert_raises ActionController::Forbidden do
|
|
52
|
+
instance_eval(&block)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# CONTEXTS
|
|
58
|
+
|
|
59
|
+
def signed_in_user_context(&blk)
|
|
60
|
+
warn "[DEPRECATION] signed_in_user_context: creates a Mystery Guest, causes Obscure Test"
|
|
61
|
+
context "A signed in user" do
|
|
62
|
+
setup do
|
|
63
|
+
@user = Factory(:user)
|
|
64
|
+
sign_in_as @user
|
|
65
|
+
end
|
|
66
|
+
merge_block(&blk)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def public_context(&blk)
|
|
71
|
+
warn "[DEPRECATION] public_context: common case is no-op. call sign_out otherwise"
|
|
72
|
+
context "The public" do
|
|
73
|
+
setup { sign_out }
|
|
74
|
+
merge_block(&blk)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# CREATING USERS
|
|
79
|
+
|
|
80
|
+
def should_create_user_successfully
|
|
81
|
+
warn "[DEPRECATION] should_create_user_successfully: not meant to be public, no longer used internally"
|
|
82
|
+
should_assign_to :user
|
|
83
|
+
should_change 'User.count', :by => 1
|
|
84
|
+
should_redirect_to_url_after_create
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# RENDERING
|
|
88
|
+
|
|
89
|
+
def should_render_nothing
|
|
90
|
+
should "render nothing" do
|
|
91
|
+
assert @response.body.blank?
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# REDIRECTS
|
|
96
|
+
|
|
97
|
+
def should_redirect_to_url_after_create
|
|
98
|
+
should_redirect_to("the post-create url") do
|
|
99
|
+
@controller.send(:url_after_create)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def should_redirect_to_url_after_update
|
|
104
|
+
should_redirect_to("the post-update url") do
|
|
105
|
+
@controller.send(:url_after_update)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def should_redirect_to_url_after_destroy
|
|
110
|
+
should_redirect_to("the post-destroy url") do
|
|
111
|
+
@controller.send(:url_after_destroy)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def should_redirect_to_url_already_confirmed
|
|
116
|
+
should_redirect_to("the already confirmed url") do
|
|
117
|
+
@controller.send(:url_already_confirmed)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# VALIDATIONS
|
|
122
|
+
|
|
123
|
+
def should_validate_confirmation_of(attribute, opts = {})
|
|
124
|
+
warn "[DEPRECATION] should_validate_confirmation_of: not meant to be public, no longer used internally"
|
|
125
|
+
raise ArgumentError if opts[:factory].nil?
|
|
126
|
+
|
|
127
|
+
context "on save" do
|
|
128
|
+
should_validate_confirmation_is_not_blank opts[:factory], attribute
|
|
129
|
+
should_validate_confirmation_is_not_bad opts[:factory], attribute
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def should_validate_confirmation_is_not_blank(factory, attribute, opts = {})
|
|
134
|
+
warn "[DEPRECATION] should_validate_confirmation_is_not_blank: not meant to be public, no longer used internally"
|
|
135
|
+
should "validate #{attribute}_confirmation is not blank" do
|
|
136
|
+
model = Factory.build(factory, blank_confirmation_options(attribute))
|
|
137
|
+
model.save
|
|
138
|
+
assert_confirmation_error(model, attribute,
|
|
139
|
+
"#{attribute}_confirmation cannot be blank")
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def should_validate_confirmation_is_not_bad(factory, attribute, opts = {})
|
|
144
|
+
warn "[DEPRECATION] should_validate_confirmation_is_not_bad: not meant to be public, no longer used internally"
|
|
145
|
+
should "validate #{attribute}_confirmation is different than #{attribute}" do
|
|
146
|
+
model = Factory.build(factory, bad_confirmation_options(attribute))
|
|
147
|
+
model.save
|
|
148
|
+
assert_confirmation_error(model, attribute,
|
|
149
|
+
"#{attribute}_confirmation cannot be different than #{attribute}")
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# FORMS
|
|
154
|
+
|
|
155
|
+
def should_display_a_password_update_form
|
|
156
|
+
warn "[DEPRECATION] should_display_a_password_update_form: not meant to be public, no longer used internally"
|
|
157
|
+
should "have a form for the user's token, password, and password confirm" do
|
|
158
|
+
update_path = ERB::Util.h(
|
|
159
|
+
user_password_path(@user, :token => @user.password_reset_token)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
assert_select 'form[action=?]', update_path do
|
|
163
|
+
assert_select 'input[name=_method][value=?]', 'put'
|
|
164
|
+
assert_select 'input[name=?]', 'user[password]'
|
|
165
|
+
assert_select 'input[name=?]', 'user[password_confirmation]'
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def should_display_a_sign_up_form
|
|
171
|
+
warn "[DEPRECATION] should_display_a_sign_up_form: not meant to be public, no longer used internally"
|
|
172
|
+
should "display a form to sign up" do
|
|
173
|
+
assert_select "form[action=#{users_path}][method=post]",
|
|
174
|
+
true, "There must be a form to sign up" do
|
|
175
|
+
assert_select "input[type=text][name=?]",
|
|
176
|
+
"user[email]", true, "There must be an email field"
|
|
177
|
+
assert_select "input[type=password][name=?]",
|
|
178
|
+
"user[password]", true, "There must be a password field"
|
|
179
|
+
assert_select "input[type=password][name=?]",
|
|
180
|
+
"user[password_confirmation]", true, "There must be a password confirmation field"
|
|
181
|
+
assert_select "input[type=submit]", true,
|
|
182
|
+
"There must be a submit button"
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def should_display_a_sign_in_form
|
|
188
|
+
warn "[DEPRECATION] should_display_a_sign_in_form: not meant to be public, no longer used internally"
|
|
189
|
+
should 'display a "sign in" form' do
|
|
190
|
+
assert_select "form[action=#{session_path}][method=post]",
|
|
191
|
+
true, "There must be a form to sign in" do
|
|
192
|
+
assert_select "input[type=text][name=?]",
|
|
193
|
+
"session[email]", true, "There must be an email field"
|
|
194
|
+
assert_select "input[type=password][name=?]",
|
|
195
|
+
"session[password]", true, "There must be a password field"
|
|
196
|
+
assert_select "input[type=submit]", true,
|
|
197
|
+
"There must be a submit button"
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
module Headstart
|
|
205
|
+
module Shoulda
|
|
206
|
+
module Helpers
|
|
207
|
+
def sign_in_as(user)
|
|
208
|
+
@controller.current_user = user
|
|
209
|
+
return user
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def sign_in
|
|
213
|
+
sign_in_as Factory(:user)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def sign_out
|
|
217
|
+
@controller.current_user = nil
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def blank_confirmation_options(attribute)
|
|
221
|
+
warn "[DEPRECATION] blank_confirmation_options: not meant to be public, no longer used internally"
|
|
222
|
+
opts = { attribute => attribute.to_s }
|
|
223
|
+
opts.merge("#{attribute}_confirmation".to_sym => "")
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def bad_confirmation_options(attribute)
|
|
227
|
+
warn "[DEPRECATION] bad_confirmation_options: not meant to be public, no longer used internally"
|
|
228
|
+
opts = { attribute => attribute.to_s }
|
|
229
|
+
opts.merge("#{attribute}_confirmation".to_sym => "not_#{attribute}")
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def assert_confirmation_error(model, attribute, message = "confirmation error")
|
|
233
|
+
warn "[DEPRECATION] assert_confirmation_error: not meant to be public, no longer used internally"
|
|
234
|
+
assert model.errors.on(attribute).include?("doesn't match confirmation"),
|
|
235
|
+
message
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
class Test::Unit::TestCase
|
|
242
|
+
include Headstart::Shoulda::Helpers
|
|
243
|
+
end
|
|
244
|
+
Test::Unit::TestCase.extend(Headstart::Shoulda)
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class PasswordsControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
tests Headstart::PasswordsController
|
|
6
|
+
|
|
7
|
+
should_route :get, '/users/1/password/edit',
|
|
8
|
+
:controller => 'headstart/passwords', :action => 'edit', :user_id => '1'
|
|
9
|
+
|
|
10
|
+
context "a signed up user" do
|
|
11
|
+
setup do
|
|
12
|
+
@user = Factory(:user)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context "on GET to #new" do
|
|
16
|
+
setup { get :new, :user_id => @user.to_param }
|
|
17
|
+
|
|
18
|
+
should_respond_with :success
|
|
19
|
+
should_render_template "new"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "on POST to #create" do
|
|
23
|
+
context "with correct email address" do
|
|
24
|
+
setup do
|
|
25
|
+
ActionMailer::Base.deliveries.clear
|
|
26
|
+
post :create, :password => { :email => @user.email }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
should "generate a token for the change your password email" do
|
|
30
|
+
assert_not_nil @user.reload.password_reset_token
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
should "send the change your password email" do
|
|
34
|
+
Delayed::Job.work_off
|
|
35
|
+
assert_sent_email do |email|
|
|
36
|
+
email.subject =~ /change your password/i
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
should_set_the_flash_to /password/i
|
|
41
|
+
should_redirect_to_url_after_create
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "with incorrect email address" do
|
|
45
|
+
setup do
|
|
46
|
+
email = "user1@example.com"
|
|
47
|
+
assert ! ::User.exists?(['email = ?', email])
|
|
48
|
+
ActionMailer::Base.deliveries.clear
|
|
49
|
+
assert_equal @user.password_reset_token,
|
|
50
|
+
@user.reload.password_reset_token
|
|
51
|
+
|
|
52
|
+
post :create, :password => { :email => email }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
should "not generate a token for the change your password email" do
|
|
56
|
+
assert_equal @user.password_reset_token,
|
|
57
|
+
@user.reload.password_reset_token
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
should "not send a password reminder email" do
|
|
61
|
+
assert ActionMailer::Base.deliveries.empty?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
should "set the failure flash to Unknown email" do
|
|
65
|
+
assert_match /unknown email/i, flash.now[:failure]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
should_render_template :new
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context "a signed up user and forgotten password" do
|
|
74
|
+
setup do
|
|
75
|
+
@user = Factory(:user)
|
|
76
|
+
@user.forgot_password!
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "on GET to #edit with correct id and token" do
|
|
80
|
+
setup do
|
|
81
|
+
get :edit, :user_id => @user.to_param,
|
|
82
|
+
:token => @user.password_reset_token
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
should "find the user" do
|
|
86
|
+
assert_equal @user, assigns(:user)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
should_respond_with :success
|
|
90
|
+
should_render_template "edit"
|
|
91
|
+
should_display_a_password_update_form
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
should_forbid "on GET to #edit with correct id but blank token" do
|
|
95
|
+
get :edit, :user_id => @user.to_param, :token => ""
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
should_forbid "on GET to #edit with correct id but no token" do
|
|
99
|
+
get :edit, :user_id => @user.to_param
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "on PUT to #update with matching password and password confirmation" do
|
|
103
|
+
setup do
|
|
104
|
+
new_password = "new_password"
|
|
105
|
+
@encrypted_new_password = @user.send(:encrypt, new_password)
|
|
106
|
+
assert_not_equal @encrypted_new_password, @user.encrypted_password
|
|
107
|
+
|
|
108
|
+
put(:update,
|
|
109
|
+
:user_id => @user,
|
|
110
|
+
:token => @user.password_reset_token,
|
|
111
|
+
:user => {
|
|
112
|
+
:password => new_password,
|
|
113
|
+
:password_confirmation => new_password
|
|
114
|
+
})
|
|
115
|
+
@user.reload
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
should "update password" do
|
|
119
|
+
assert_equal @encrypted_new_password,
|
|
120
|
+
@user.encrypted_password
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
should "clear confirmation token" do
|
|
124
|
+
assert_nil @user.password_reset_token
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
should "set remember token" do
|
|
128
|
+
assert_not_nil @user.remember_token
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
should_set_the_flash_to(/signed in/i)
|
|
132
|
+
should_redirect_to_url_after_update
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context "on PUT to #update with password but blank password confirmation" do
|
|
136
|
+
setup do
|
|
137
|
+
new_password = "new_password"
|
|
138
|
+
@encrypted_new_password = @user.send(:encrypt, new_password)
|
|
139
|
+
|
|
140
|
+
put(:update,
|
|
141
|
+
:user_id => @user.to_param,
|
|
142
|
+
:token => @user.password_reset_token,
|
|
143
|
+
:user => {
|
|
144
|
+
:password => new_password,
|
|
145
|
+
:password_confirmation => ''
|
|
146
|
+
})
|
|
147
|
+
@user.reload
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
should "not update password" do
|
|
151
|
+
assert_not_equal @encrypted_new_password,
|
|
152
|
+
@user.encrypted_password
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
should "not clear token" do
|
|
156
|
+
assert_not_nil @user.password_reset_token
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
should_not_be_signed_in
|
|
160
|
+
should_not_set_the_flash
|
|
161
|
+
should_respond_with :success
|
|
162
|
+
should_render_template :edit
|
|
163
|
+
|
|
164
|
+
should_display_a_password_update_form
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
should_forbid "on PUT to #update with id but no token" do
|
|
168
|
+
put :update, :user_id => @user.to_param, :token => ""
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
context "given two users and user one signs in" do
|
|
173
|
+
setup do
|
|
174
|
+
@user_one = Factory(:user)
|
|
175
|
+
@user_two = Factory(:user)
|
|
176
|
+
sign_in_as @user_one
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
should_forbid "when user one tries to change user two's password on GET with no token" do
|
|
180
|
+
get :edit, :user_id => @user_two.to_param
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class SessionsControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
tests Headstart::SessionsController
|
|
6
|
+
|
|
7
|
+
should_filter_params :password
|
|
8
|
+
|
|
9
|
+
context "on GET to /sessions/new" do
|
|
10
|
+
setup { get :new }
|
|
11
|
+
|
|
12
|
+
should_respond_with :success
|
|
13
|
+
should_render_template :new
|
|
14
|
+
should_not_set_the_flash
|
|
15
|
+
should_display_a_sign_in_form
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context "on POST to #create with good credentials" do
|
|
19
|
+
setup do
|
|
20
|
+
@user = Factory(:user)
|
|
21
|
+
@user.update_attribute(:remember_token, "old-token")
|
|
22
|
+
post :create, :session => {
|
|
23
|
+
:email => @user.email,
|
|
24
|
+
:password => @user.password }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
should_set_the_flash_to /signed in/i
|
|
28
|
+
should_redirect_to_url_after_create
|
|
29
|
+
|
|
30
|
+
should 'set the cookie' do
|
|
31
|
+
assert ! cookies['remember_token'].empty?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
should "not change the remember token" do
|
|
35
|
+
assert_equal "old-token", @user.reload.remember_token
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "on POST to #create with good credentials and a session return url" do
|
|
40
|
+
setup do
|
|
41
|
+
@user = Factory(:user)
|
|
42
|
+
@return_url = '/url_in_the_session'
|
|
43
|
+
@request.session[:return_to] = @return_url
|
|
44
|
+
post :create, :session => {
|
|
45
|
+
:email => @user.email,
|
|
46
|
+
:password => @user.password }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
should_redirect_to("the return URL") { @return_url }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "on POST to #create with good credentials and a request return url" do
|
|
53
|
+
setup do
|
|
54
|
+
@user = Factory(:user)
|
|
55
|
+
@return_url = '/url_in_the_request'
|
|
56
|
+
post :create, :session => {
|
|
57
|
+
:email => @user.email,
|
|
58
|
+
:password => @user.password },
|
|
59
|
+
:return_to => @return_url
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
should_redirect_to("the return URL") { @return_url }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "on POST to #create with good credentials and a session return url and request return url" do
|
|
66
|
+
setup do
|
|
67
|
+
@user = Factory(:user)
|
|
68
|
+
@return_url = '/url_in_the_session'
|
|
69
|
+
@request.session[:return_to] = @return_url
|
|
70
|
+
post :create, :session => {
|
|
71
|
+
:email => @user.email,
|
|
72
|
+
:password => @user.password },
|
|
73
|
+
:return_to => '/url_in_the_request'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
should_redirect_to("the return URL") { @return_url }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "on POST to #create with bad credentials" do
|
|
80
|
+
setup do
|
|
81
|
+
post :create, :session => {
|
|
82
|
+
:email => 'bad.email@example.com',
|
|
83
|
+
:password => "bad value" }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
should_set_the_flash_to /bad/i
|
|
87
|
+
should_respond_with :unauthorized
|
|
88
|
+
should_render_template :new
|
|
89
|
+
should_not_be_signed_in
|
|
90
|
+
|
|
91
|
+
should 'not create the cookie' do
|
|
92
|
+
assert_nil cookies['remember_token']
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "on DELETE to #destroy given a signed out user" do
|
|
97
|
+
setup do
|
|
98
|
+
sign_out
|
|
99
|
+
delete :destroy
|
|
100
|
+
end
|
|
101
|
+
should_set_the_flash_to(/signed out/i)
|
|
102
|
+
should_redirect_to_url_after_destroy
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context "on DELETE to #destroy with a cookie" do
|
|
106
|
+
setup do
|
|
107
|
+
@user = Factory(:user)
|
|
108
|
+
@user.update_attribute(:remember_token, "old-token")
|
|
109
|
+
@request.cookies["remember_token"] = "old-token"
|
|
110
|
+
delete :destroy
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
should_set_the_flash_to(/signed out/i)
|
|
114
|
+
should_redirect_to_url_after_destroy
|
|
115
|
+
|
|
116
|
+
should "delete the cookie token" do
|
|
117
|
+
assert_nil cookies['remember_token']
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
should "reset the remember token" do
|
|
121
|
+
assert_not_equal "old-token", @user.reload.remember_token
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
should "unset the current user" do
|
|
125
|
+
assert_nil @controller.current_user
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class UsersControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
tests Headstart::UsersController
|
|
6
|
+
|
|
7
|
+
should_filter_params :password
|
|
8
|
+
|
|
9
|
+
context "when signed out" do
|
|
10
|
+
setup { sign_out }
|
|
11
|
+
|
|
12
|
+
context "on GET to #new" do
|
|
13
|
+
setup { get :new }
|
|
14
|
+
|
|
15
|
+
should_respond_with :success
|
|
16
|
+
should_render_template :new
|
|
17
|
+
should_not_set_the_flash
|
|
18
|
+
|
|
19
|
+
should_display_a_sign_up_form
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "on GET to #new with email" do
|
|
23
|
+
setup do
|
|
24
|
+
@email = "a@example.com"
|
|
25
|
+
get :new, :user => { :email => @email }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
should "set assigned user's email" do
|
|
29
|
+
assert_equal @email, assigns(:user).email
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "on POST to #create with valid attributes" do
|
|
34
|
+
setup do
|
|
35
|
+
user_attributes = Factory.attributes_for(:user)
|
|
36
|
+
post :create, :user => user_attributes
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
should_assign_to :user
|
|
40
|
+
should_change 'User.count', :by => 1
|
|
41
|
+
should_redirect_to_url_after_create
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
signed_in_user_context do
|
|
46
|
+
context "GET to new" do
|
|
47
|
+
setup { get :new }
|
|
48
|
+
should_redirect_to("the home page") { root_url }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "POST to create" do
|
|
52
|
+
setup { post :create, :user => {} }
|
|
53
|
+
should_redirect_to("the home page") { root_url }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class HeadstartMailerTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
context "A change password email" do
|
|
6
|
+
setup do
|
|
7
|
+
@user = Factory(:user)
|
|
8
|
+
@user.forgot_password!
|
|
9
|
+
HeadstartMailer.deliver_mimi_change_password @user
|
|
10
|
+
@email = ActionMailer::Base.deliveries.last
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
should "be from DO_NOT_REPLY" do
|
|
14
|
+
assert_equal Headstart.configuration.mailer_sender, @email.from
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
should "be sent to user" do
|
|
18
|
+
assert_match /#{@user.email}/i, @email.recipients
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
should "contain a link to edit the user's password" do
|
|
22
|
+
host = ActionMailer::Base.default_url_options[:host]
|
|
23
|
+
regexp = %r{http://#{host}/users/#{@user.id}/password/edit\?token=#{@user.password_reset_token}}
|
|
24
|
+
assert_match regexp, @email.body[:url]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
should "set its subject" do
|
|
28
|
+
assert_match /Change your password/, @email.subject
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "A welcome email" do
|
|
33
|
+
setup do
|
|
34
|
+
@user = Factory(:user)
|
|
35
|
+
Delayed::Job.work_off
|
|
36
|
+
@email = ActionMailer::Base.deliveries.last
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
should "be from DO_NOT_REPLY" do
|
|
40
|
+
assert_equal Headstart.configuration.mailer_sender, @email.from
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
should "be sent to user" do
|
|
44
|
+
assert_match /#{@user.email}/i, @email.recipients
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
should "set its subject" do
|
|
48
|
+
assert_match /welcome/i, @email.subject
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class ImpersonationTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
context 'An Impersonation' do
|
|
6
|
+
|
|
7
|
+
should 'generate a hash based on the id' do
|
|
8
|
+
hash1 = Impersonation.hash_for(1)
|
|
9
|
+
hash2 = Impersonation.hash_for(2)
|
|
10
|
+
assert_not_equal(hash1, hash2)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
should 'not generate a nil hash' do
|
|
14
|
+
assert_not_nil(Impersonation.hash_for(23))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
should 'not raise an exception for nil' do
|
|
18
|
+
assert_raise(ArgumentError) do
|
|
19
|
+
Impersonation.hash_for(nil)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|