muck-users 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/MIT-LICENSE +20 -0
- data/README.rdoc +27 -0
- data/Rakefile +96 -0
- data/VERSION +1 -0
- data/app/controllers/admin/muck/roles_controller.rb +57 -0
- data/app/controllers/admin/muck/users_controller.rb +122 -0
- data/app/controllers/muck/activations_controller.rb +31 -0
- data/app/controllers/muck/password_resets_controller.rb +81 -0
- data/app/controllers/muck/user_sessions_controller.rb +40 -0
- data/app/controllers/muck/username_request_controller.rb +43 -0
- data/app/controllers/muck/users_controller.rb +211 -0
- data/app/models/muck_user_mailer.rb +53 -0
- data/app/models/permission.rb +17 -0
- data/app/models/role.rb +25 -0
- data/app/views/admin/roles/_role.html.erb +9 -0
- data/app/views/admin/roles/edit.html.erb +17 -0
- data/app/views/admin/roles/index.html.erb +8 -0
- data/app/views/admin/roles/new.html.erb +16 -0
- data/app/views/admin/roles/show.html.erb +7 -0
- data/app/views/admin/users/_activate.html.erb +5 -0
- data/app/views/admin/users/_ajax_search_box.html.erb +6 -0
- data/app/views/admin/users/_row.html.erb +6 -0
- data/app/views/admin/users/_search_box.html.erb +6 -0
- data/app/views/admin/users/_table.html.erb +21 -0
- data/app/views/admin/users/_user_navigation.html.erb +11 -0
- data/app/views/admin/users/do_search.html.erb +5 -0
- data/app/views/admin/users/inactive.html.erb +8 -0
- data/app/views/admin/users/inactive_emails.html.erb +6 -0
- data/app/views/admin/users/index.html.erb +12 -0
- data/app/views/admin/users/search.html.erb +5 -0
- data/app/views/muck_user_mailer/activation_confirmation.html.erb +7 -0
- data/app/views/muck_user_mailer/activation_instructions.html.erb +7 -0
- data/app/views/muck_user_mailer/password_not_active_instructions.html.erb +10 -0
- data/app/views/muck_user_mailer/password_reset_instructions.html.erb +10 -0
- data/app/views/muck_user_mailer/username_request.html.erb +3 -0
- data/app/views/muck_user_mailer/welcome_notification.html.erb +5 -0
- data/app/views/password_resets/edit.html.erb +9 -0
- data/app/views/password_resets/new.html.erb +11 -0
- data/app/views/user_sessions/new.html.erb +17 -0
- data/app/views/username_request/new.html.erb +11 -0
- data/app/views/users/_user.html.erb +15 -0
- data/app/views/users/activation_confirmation.html.erb +1 -0
- data/app/views/users/activation_instructions.html.erb +1 -0
- data/app/views/users/edit.html.erb +45 -0
- data/app/views/users/new.html.erb +51 -0
- data/app/views/users/show.html.erb +4 -0
- data/app/views/users/welcome.html.erb +4 -0
- data/config/muck_users_routes.rb +56 -0
- data/db/migrate/20090320174818_create_muck_permissions_and_roles.rb +16 -0
- data/db/migrate/20090512013727_add_photo_to_user.rb +13 -0
- data/install.rb +1 -0
- data/lib/action_controller/authentic_application.rb +213 -0
- data/lib/active_record/acts/muck_user.rb +192 -0
- data/lib/muck-users/exceptions.rb +5 -0
- data/lib/muck-users/initialize_routes.rb +8 -0
- data/lib/muck-users/tasks.rb +46 -0
- data/lib/muck-users.rb +7 -0
- data/locales/ar.yml +124 -0
- data/locales/bg.yml +124 -0
- data/locales/ca.yml +124 -0
- data/locales/cs.yml +124 -0
- data/locales/da.yml +124 -0
- data/locales/de.yml +124 -0
- data/locales/el.yml +124 -0
- data/locales/en.yml +127 -0
- data/locales/es.yml +124 -0
- data/locales/fr.yml +124 -0
- data/locales/it.yml +124 -0
- data/locales/iw.yml +124 -0
- data/locales/ja.yml +124 -0
- data/locales/ko.yml +124 -0
- data/locales/lt.yml +124 -0
- data/locales/lv.yml +124 -0
- data/locales/nl.yml +124 -0
- data/locales/no.yml +125 -0
- data/locales/pl.yml +124 -0
- data/locales/pt.yml +124 -0
- data/locales/ro.yml +124 -0
- data/locales/ru.yml +124 -0
- data/locales/sk.yml +124 -0
- data/locales/sl.yml +124 -0
- data/locales/sr.yml +124 -0
- data/locales/sv.yml +124 -0
- data/locales/tl.yml +124 -0
- data/locales/uk.yml +124 -0
- data/locales/vi.yml +124 -0
- data/locales/zh-CN.yml +124 -0
- data/locales/zh-TW.yml +124 -0
- data/locales/zh.yml +124 -0
- data/muck-users.gemspec +170 -0
- data/pkg/muck-users-0.1.0.gem +0 -0
- data/public/images/profile_default.jpg +0 -0
- data/rails/init.rb +18 -0
- data/tasks/muck_users_engine.rake +27 -0
- data/tasks/rails.rake +2 -0
- data/test/factories.rb +56 -0
- data/test/functional/activations_controller_test.rb +73 -0
- data/test/functional/admin/roles_controller_test.rb +10 -0
- data/test/functional/admin/users_controller_test.rb +55 -0
- data/test/functional/password_resets_controller_test.rb +60 -0
- data/test/functional/user_sessions_controller_test.rb +62 -0
- data/test/functional/users_controller_test.rb +255 -0
- data/test/shoulda_macros/controller.rb +43 -0
- data/test/shoulda_macros/forms.rb +28 -0
- data/test/shoulda_macros/models.rb +34 -0
- data/test/shoulda_macros/pagination.rb +48 -0
- data/test/shoulda_macros/plugins.rb +30 -0
- data/test/test_helper.rb +36 -0
- data/test/unit/muck_user_mailer_test.rb +64 -0
- data/test/unit/permission_test.rb +19 -0
- data/test/unit/role_test.rb +17 -0
- data/uninstall.rb +1 -0
- metadata +198 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
2
|
+
|
|
3
|
+
class Muck::PasswordResetsControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
tests Muck::PasswordResetsController
|
|
6
|
+
|
|
7
|
+
context "user sessions controller" do
|
|
8
|
+
setup do
|
|
9
|
+
@user = Factory(:user)
|
|
10
|
+
end
|
|
11
|
+
context "get new" do
|
|
12
|
+
setup do
|
|
13
|
+
get :new
|
|
14
|
+
end
|
|
15
|
+
should_respond_with :success
|
|
16
|
+
should_render_template :new
|
|
17
|
+
end
|
|
18
|
+
context "find user using email and send email message" do
|
|
19
|
+
setup do
|
|
20
|
+
post :create, :email => @user.email
|
|
21
|
+
end
|
|
22
|
+
should "send password reset instructions" do
|
|
23
|
+
assert_sent_email do |email|
|
|
24
|
+
email.to.include?(@user.email)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
should_redirect_to("login") { login_path }
|
|
28
|
+
end
|
|
29
|
+
context "bad email - fail to reset password" do
|
|
30
|
+
setup do
|
|
31
|
+
post :create, :email => 'quentin@bad_email_example.com'
|
|
32
|
+
end
|
|
33
|
+
should_respond_with :success
|
|
34
|
+
should_render_template :new
|
|
35
|
+
end
|
|
36
|
+
context "get edit" do
|
|
37
|
+
setup do
|
|
38
|
+
get :edit, :id => @user.perishable_token
|
|
39
|
+
end
|
|
40
|
+
should_respond_with :success
|
|
41
|
+
should_render_template :edit
|
|
42
|
+
end
|
|
43
|
+
context "PUT update" do
|
|
44
|
+
setup do
|
|
45
|
+
put :update, :id => @user.perishable_token, :user => {:password => "foobar", :password_confirmation => "foobar" }
|
|
46
|
+
end
|
|
47
|
+
should_redirect_to("user account") { account_path }
|
|
48
|
+
end
|
|
49
|
+
context "PUT update - password mismatch" do
|
|
50
|
+
setup do
|
|
51
|
+
put :update, :id => @user.perishable_token, :user => {:password => "foobar", :password_confirmation => "foobarbaz"}
|
|
52
|
+
end
|
|
53
|
+
should "fail to update user password because passwords do not match" do
|
|
54
|
+
assert assigns(:user).errors.on(:password)
|
|
55
|
+
end
|
|
56
|
+
should_respond_with :success
|
|
57
|
+
should_render_template :edit
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
2
|
+
|
|
3
|
+
class Muck::UserSessionsControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
tests Muck::UserSessionsController
|
|
6
|
+
|
|
7
|
+
should_filter_params :password
|
|
8
|
+
|
|
9
|
+
context "user sessions controller" do
|
|
10
|
+
setup do
|
|
11
|
+
@login = 'quentin'
|
|
12
|
+
@good_password = 'test'
|
|
13
|
+
@user = Factory(:user, :login => @login, :password => @good_password, :password_confirmation => @good_password)
|
|
14
|
+
end
|
|
15
|
+
context "get new" do
|
|
16
|
+
setup do
|
|
17
|
+
get :new
|
|
18
|
+
end
|
|
19
|
+
should_respond_with :success
|
|
20
|
+
should_render_template :new
|
|
21
|
+
end
|
|
22
|
+
context "login and redirect" do
|
|
23
|
+
setup do
|
|
24
|
+
post :create, :user_session => { :login => @login, :password => @good_password }
|
|
25
|
+
end
|
|
26
|
+
should "create a user session" do
|
|
27
|
+
assert user_session = UserSession.find
|
|
28
|
+
assert_equal @user, user_session.user
|
|
29
|
+
end
|
|
30
|
+
should_redirect_to("user account") { user_path(@user) }
|
|
31
|
+
end
|
|
32
|
+
context "fail login" do
|
|
33
|
+
setup do
|
|
34
|
+
post :create, :user_session => { :login => @login, :password => 'bad password' }
|
|
35
|
+
end
|
|
36
|
+
should "not create a user session" do
|
|
37
|
+
assert_nil UserSession.find
|
|
38
|
+
end
|
|
39
|
+
should_respond_with :success
|
|
40
|
+
should_render_template :new
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "authlogic enabled" do
|
|
44
|
+
setup do
|
|
45
|
+
@user = Factory(:user)
|
|
46
|
+
activate_authlogic
|
|
47
|
+
end
|
|
48
|
+
context "logout" do
|
|
49
|
+
setup do
|
|
50
|
+
login_as(@user)
|
|
51
|
+
delete :destroy
|
|
52
|
+
end
|
|
53
|
+
should "logout by destroying the user session" do
|
|
54
|
+
assert_nil UserSession.find
|
|
55
|
+
end
|
|
56
|
+
should_redirect_to("login") { login_path }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
2
|
+
|
|
3
|
+
class Muck::UsersControllerTest < ActionController::TestCase
|
|
4
|
+
|
|
5
|
+
tests Muck::UsersController
|
|
6
|
+
|
|
7
|
+
context "configuration tests" do
|
|
8
|
+
teardown do
|
|
9
|
+
GlobalConfig.automatically_activate = false
|
|
10
|
+
GlobalConfig.automatically_login_after_account_create = false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context "automatically activate account and log user in. " do
|
|
14
|
+
setup do
|
|
15
|
+
GlobalConfig.automatically_activate = true
|
|
16
|
+
GlobalConfig.automatically_login_after_account_create = true
|
|
17
|
+
end
|
|
18
|
+
context "on POST to :create" do
|
|
19
|
+
setup do
|
|
20
|
+
post_create_user
|
|
21
|
+
end
|
|
22
|
+
should_redirect_to("sign up complete path") { signup_complete_path(assigns(:user)) }
|
|
23
|
+
should "activate user" do
|
|
24
|
+
assert assigns(:user).active? == true, "user was not activated"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
context "on POST to :create with bad login (space in login name)" do
|
|
28
|
+
setup do
|
|
29
|
+
post_create_user(:login => 'test guy')
|
|
30
|
+
end
|
|
31
|
+
should_respond_with :success
|
|
32
|
+
should_render_template :new
|
|
33
|
+
should "assign an error to the login field" do
|
|
34
|
+
assert assigns(:user).errors.on(:login), "no errors were assign on login field"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "automatically activate account do not log user in" do
|
|
40
|
+
setup do
|
|
41
|
+
GlobalConfig.automatically_activate = true
|
|
42
|
+
GlobalConfig.automatically_login_after_account_create = false
|
|
43
|
+
end
|
|
44
|
+
context "on POST to :create" do
|
|
45
|
+
setup do
|
|
46
|
+
post_create_user
|
|
47
|
+
end
|
|
48
|
+
should_redirect_to("signup complete login required path") { signup_complete_login_required_path(assigns(:user)) }
|
|
49
|
+
end
|
|
50
|
+
context "on POST to :create with bad login (space in login name)" do
|
|
51
|
+
setup do
|
|
52
|
+
post_create_user(:login => 'test guy')
|
|
53
|
+
end
|
|
54
|
+
should_respond_with :success
|
|
55
|
+
should_render_template :new
|
|
56
|
+
should "assign an error to the login field" do
|
|
57
|
+
assert assigns(:user).errors.on(:login), "no errors were assign on login field"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "do not auto activate. do not login after create" do
|
|
63
|
+
setup do
|
|
64
|
+
GlobalConfig.automatically_activate = false
|
|
65
|
+
GlobalConfig.automatically_login_after_account_create = false
|
|
66
|
+
end
|
|
67
|
+
context "on POST to :create -- Allow signup. " do
|
|
68
|
+
setup do
|
|
69
|
+
post_create_user
|
|
70
|
+
end
|
|
71
|
+
should_redirect_to("activation required information page") { signup_complete_activation_required_path(assigns(:user)) }
|
|
72
|
+
end
|
|
73
|
+
context "on POST to :create -- require login on signup. " do
|
|
74
|
+
setup do
|
|
75
|
+
post_create_user :login => ''
|
|
76
|
+
end
|
|
77
|
+
should_respond_with :success
|
|
78
|
+
should_render_template :new
|
|
79
|
+
should "assign an error to the login field" do
|
|
80
|
+
assert assigns(:user).errors.on(:login)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
context "on POST to :create with bad login (space in login name)" do
|
|
84
|
+
setup do
|
|
85
|
+
post_create_user(:login => 'test guy')
|
|
86
|
+
end
|
|
87
|
+
should_respond_with :success
|
|
88
|
+
should_render_template :new
|
|
89
|
+
should "assign an error to the login field" do
|
|
90
|
+
assert assigns(:user).errors.on(:login)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
context "on POST to :create -- require password on signup. " do
|
|
94
|
+
setup do
|
|
95
|
+
post_create_user(:password => nil)
|
|
96
|
+
end
|
|
97
|
+
should_respond_with :success
|
|
98
|
+
should_render_template :new
|
|
99
|
+
should "assign an error to the password field" do
|
|
100
|
+
assert assigns(:user).errors.on(:password)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
context "on POST to :create -- require password confirmation on signup. " do
|
|
104
|
+
setup { post_create_user(:password_confirmation => nil) }
|
|
105
|
+
should_respond_with :success
|
|
106
|
+
should_render_template :new
|
|
107
|
+
|
|
108
|
+
should "assign an error to the password confirmation field" do
|
|
109
|
+
assert assigns(:user).errors.on(:password_confirmation)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
context "on POST to :create -- require email on signup. " do
|
|
113
|
+
setup { post_create_user(:email => nil) }
|
|
114
|
+
should_respond_with :success
|
|
115
|
+
should_render_template :new
|
|
116
|
+
should "assign an error to the email field" do
|
|
117
|
+
assert assigns(:user).errors.on(:email)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
context "logged in" do
|
|
124
|
+
setup do
|
|
125
|
+
activate_authlogic
|
|
126
|
+
@user = Factory(:user)
|
|
127
|
+
login_as @user
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
context "on GET to :welcome" do
|
|
131
|
+
setup do
|
|
132
|
+
@user = Factory(:user)
|
|
133
|
+
get :welcome, :id => @user.to_param
|
|
134
|
+
end
|
|
135
|
+
should_respond_with :success
|
|
136
|
+
should_render_template :welcome
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
context "on GET to new (signup) while logged in" do
|
|
140
|
+
setup do
|
|
141
|
+
get :new
|
|
142
|
+
end
|
|
143
|
+
should_redirect_to("the logged in user's main user page") { user_url(@user) }
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context "on GET to show" do
|
|
147
|
+
setup do
|
|
148
|
+
get :show
|
|
149
|
+
end
|
|
150
|
+
should_respond_with :success
|
|
151
|
+
should_render_template :show
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
context "on GET to edit" do
|
|
155
|
+
setup do
|
|
156
|
+
get :edit, :id => @user.to_param
|
|
157
|
+
end
|
|
158
|
+
should_respond_with :success
|
|
159
|
+
should_render_template :edit
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
context "on GET to edit logged in but wrong user" do
|
|
163
|
+
setup do
|
|
164
|
+
@other_user = Factory(:user)
|
|
165
|
+
get :edit, :id => @other_user.to_param
|
|
166
|
+
end
|
|
167
|
+
should_respond_with :success
|
|
168
|
+
should "set the user to the logged in user" do
|
|
169
|
+
assert_equal assigns(:user), @user
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
context "on PUT to :update" do
|
|
174
|
+
setup do
|
|
175
|
+
@user = Factory(:user)
|
|
176
|
+
put_update_user(@user)
|
|
177
|
+
end
|
|
178
|
+
should_redirect_to("user path") { user_path(assigns(:user)) }
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context "not logged in" do
|
|
184
|
+
setup do
|
|
185
|
+
assure_logout
|
|
186
|
+
end
|
|
187
|
+
context "on GET to :welcome" do
|
|
188
|
+
setup do
|
|
189
|
+
@user = Factory(:user)
|
|
190
|
+
get :welcome, :id => @user.to_param
|
|
191
|
+
end
|
|
192
|
+
should_redirect_to("login") { login_path }
|
|
193
|
+
end
|
|
194
|
+
context "on GET to :activation_instructions" do
|
|
195
|
+
setup do
|
|
196
|
+
@user = Factory(:user)
|
|
197
|
+
get :activation_instructions, :id => @user.to_param
|
|
198
|
+
end
|
|
199
|
+
should_respond_with :success
|
|
200
|
+
should_render_template :activation_instructions
|
|
201
|
+
end
|
|
202
|
+
context "on GET to new (signup)" do
|
|
203
|
+
setup do
|
|
204
|
+
get :new
|
|
205
|
+
end
|
|
206
|
+
should_respond_with :success
|
|
207
|
+
should_render_template :new
|
|
208
|
+
end
|
|
209
|
+
context "on GET to show" do
|
|
210
|
+
setup do
|
|
211
|
+
@user = Factory(:user)
|
|
212
|
+
get :show
|
|
213
|
+
end
|
|
214
|
+
should_redirect_to("login") { login_path }
|
|
215
|
+
end
|
|
216
|
+
context "on GET to edit" do
|
|
217
|
+
setup do
|
|
218
|
+
@user = Factory(:user)
|
|
219
|
+
get :edit, :id => @user.to_param
|
|
220
|
+
end
|
|
221
|
+
should_redirect_to("login") { login_path }
|
|
222
|
+
end
|
|
223
|
+
context "on PUT to :update" do
|
|
224
|
+
setup do
|
|
225
|
+
@user = Factory(:user)
|
|
226
|
+
put_update_user(@user)
|
|
227
|
+
end
|
|
228
|
+
should_redirect_to("login") { login_path }
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def put_update_user(user, options = {})
|
|
233
|
+
put :update,
|
|
234
|
+
:id => user.id,
|
|
235
|
+
:user => { :login => 'testguy',
|
|
236
|
+
:email => rand(1000).to_s + 'testguy@example.com',
|
|
237
|
+
:password => 'testpasswrod',
|
|
238
|
+
:password_confirmation => 'testpasswrod',
|
|
239
|
+
:first_name => 'Ed',
|
|
240
|
+
:last_name => 'Decker',
|
|
241
|
+
:terms_of_service => true }.merge(options)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def post_create_user(options = {})
|
|
245
|
+
post :create,
|
|
246
|
+
:user => { :login => 'testguy',
|
|
247
|
+
:email => rand(1000).to_s + 'testguy@example.com',
|
|
248
|
+
:password => 'testpasswrod',
|
|
249
|
+
:password_confirmation => 'testpasswrod',
|
|
250
|
+
:first_name => 'Ed',
|
|
251
|
+
:last_name => 'Decker',
|
|
252
|
+
:terms_of_service => true }.merge(options)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
ActiveSupport::TestCase.class_eval do
|
|
2
|
+
|
|
3
|
+
def self.should_require_login(*args)
|
|
4
|
+
args = Hash[*args]
|
|
5
|
+
login_url = args.delete :login_url
|
|
6
|
+
args.each do |action, verb|
|
|
7
|
+
should "Require login for '#{action}' action" do
|
|
8
|
+
send(verb, action)
|
|
9
|
+
assert_redirected_to(login_url)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.should_require_role(role, redirect_url, *actions)
|
|
15
|
+
actions.each do |action|
|
|
16
|
+
should "require role for '#{action}' action" do
|
|
17
|
+
get(action)
|
|
18
|
+
ensure_flash(/permission/i)
|
|
19
|
+
assert_response :redirect
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#from: http://blog.internautdesign.com/2008/9/11/more-on-custom-shoulda-macros-scoping-of-instance-variables
|
|
25
|
+
def self.should_not_allow action, object, url= "/login", msg=nil
|
|
26
|
+
msg ||= "a #{object.class.to_s.downcase}"
|
|
27
|
+
should "not be able to #{action} #{msg}" do
|
|
28
|
+
object = eval(object, self.send(:binding), __FILE__, __LINE__)
|
|
29
|
+
get action, :id => object.id
|
|
30
|
+
assert_redirected_to url
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.should_allow action, object, msg=nil
|
|
35
|
+
msg ||= "a #{object.class.to_s.downcase}"
|
|
36
|
+
should "be able to #{action} #{msg}" do
|
|
37
|
+
object = eval(object, self.send(:binding), __FILE__, __LINE__)
|
|
38
|
+
get action, :id => object.id
|
|
39
|
+
assert_response :success
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class ActiveSupport::TestCase
|
|
2
|
+
def self.should_have_form(opts)
|
|
3
|
+
model = self.name.gsub(/ControllerTest$/, '').singularize.downcase
|
|
4
|
+
model = model[model.rindex('::')+2..model.size] if model.include?('::')
|
|
5
|
+
http_method, hidden_http_method = form_http_method opts[:method]
|
|
6
|
+
should "have a #{model} form" do
|
|
7
|
+
assert_select "form[action=?][method=#{http_method}]", eval(opts[:action]) do
|
|
8
|
+
if hidden_http_method
|
|
9
|
+
assert_select "input[type=hidden][name=_method][value=#{hidden_http_method}]"
|
|
10
|
+
end
|
|
11
|
+
opts[:fields].each do |attribute, type|
|
|
12
|
+
attribute = attribute.is_a?(Symbol) ? "#{model}[#{attribute.to_s}]" : attribute
|
|
13
|
+
assert_select "input[type=#{type.to_s}][name=?]", attribute
|
|
14
|
+
end
|
|
15
|
+
assert_select "input[type=submit]"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.form_http_method(http_method)
|
|
21
|
+
http_method = http_method.nil? ? 'post' : http_method.to_s
|
|
22
|
+
if http_method == "post" || http_method == "get"
|
|
23
|
+
return http_method, nil
|
|
24
|
+
else
|
|
25
|
+
return "post", http_method
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
ActiveSupport::TestCase.class_eval do
|
|
2
|
+
|
|
3
|
+
def self.should_whitelist(*attributes)
|
|
4
|
+
bad_scripts = [
|
|
5
|
+
%|';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>|,
|
|
6
|
+
%|'';!--"<XSS>=&{()}|,
|
|
7
|
+
%|<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>|,
|
|
8
|
+
%|<IMG SRC="javascript:alert('XSS');">|,
|
|
9
|
+
%|<IMG SRC=javascript:alert('XSS')>|,
|
|
10
|
+
%|<IMG SRC=JaVaScRiPt:alert('XSS')>|,
|
|
11
|
+
%|<IMG SRC=JaVaScRiPt:alert('XSS')>|,
|
|
12
|
+
%|<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>|,
|
|
13
|
+
%|<IMG """><SCRIPT>alert("XSS")</SCRIPT>">|,
|
|
14
|
+
%|<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>|,
|
|
15
|
+
%|<A HREF="h
|
|
16
|
+
tt p://6	6.000146.0x7.147/">XSS</A>|,
|
|
17
|
+
%|<script>alert('message');</script>| ]
|
|
18
|
+
|
|
19
|
+
klass = model_class
|
|
20
|
+
attributes.each do |attribute|
|
|
21
|
+
attribute = attribute.to_sym
|
|
22
|
+
should "white list #{attribute}" do
|
|
23
|
+
assert object = klass.find(:first), "Can't find first #{klass}"
|
|
24
|
+
bad_scripts.each do |bad_value|
|
|
25
|
+
object.send("#{attribute}=", bad_value)
|
|
26
|
+
object.save
|
|
27
|
+
clean_value = object.send("#{attribute}")
|
|
28
|
+
assert !clean_value.include?(bad_value), "#{attribute} is not white listed. #{bad_value} made it through"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
class ActiveSupport::TestCase
|
|
2
|
+
# Example:
|
|
3
|
+
# context "a GET to index logged in as admin" do
|
|
4
|
+
# setup do
|
|
5
|
+
# login_as_admin
|
|
6
|
+
# get :index
|
|
7
|
+
# end
|
|
8
|
+
# should_paginate_collection :users
|
|
9
|
+
# should_display_pagination
|
|
10
|
+
# end
|
|
11
|
+
def self.should_paginate_collection(collection_name)
|
|
12
|
+
should "paginate #{collection_name}" do
|
|
13
|
+
assert collection = assigns(collection_name),
|
|
14
|
+
"Controller isn't assigning to @#{collection_name.to_s}."
|
|
15
|
+
assert_kind_of WillPaginate::Collection, collection,
|
|
16
|
+
"@#{collection_name.to_s} isn't a WillPaginate collection."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.should_display_pagination
|
|
21
|
+
should "display pagination" do
|
|
22
|
+
assert_select "div.pagination", { :minimum => 1 },
|
|
23
|
+
"View isn't displaying pagination. Add <%= will_paginate @collection %>."
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Example:
|
|
28
|
+
# context "a GET to index not logged in as admin" do
|
|
29
|
+
# setup { get :index }
|
|
30
|
+
# should_not_paginate_collection :users
|
|
31
|
+
# should_not_display_pagination
|
|
32
|
+
# end
|
|
33
|
+
def self.should_not_paginate_collection(collection_name)
|
|
34
|
+
should "not paginate #{collection_name}" do
|
|
35
|
+
assert collection = assigns(collection_name),
|
|
36
|
+
"Controller isn't assigning to @#{collection_name.to_s}."
|
|
37
|
+
assert_not_equal WillPaginate::Collection, collection.class,
|
|
38
|
+
"@#{collection_name.to_s} is a WillPaginate collection."
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.should_not_display_pagination
|
|
43
|
+
should "not display pagination" do
|
|
44
|
+
assert_select "div.pagination", { :count => 0 },
|
|
45
|
+
"View is displaying pagination. Check your logic."
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class ActiveSupport::TestCase
|
|
2
|
+
|
|
3
|
+
def self.should_act_as_taggable_on_steroids
|
|
4
|
+
klass = self.name.gsub(/Test$/, '').constantize
|
|
5
|
+
|
|
6
|
+
should "include ActsAsTaggableOnSteroids methods" do
|
|
7
|
+
assert klass.extended_by.include?(ActiveRecord::Acts::Taggable::ClassMethods)
|
|
8
|
+
assert klass.extended_by.include?(ActiveRecord::Acts::Taggable::SingletonMethods)
|
|
9
|
+
assert klass.include?(ActiveRecord::Acts::Taggable::InstanceMethods)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
should_have_many :taggings, :tags
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def self.should_act_as_list
|
|
17
|
+
klass = self.name.gsub(/Test$/, '').constantize
|
|
18
|
+
|
|
19
|
+
context "To support acts_as_list" do
|
|
20
|
+
should_have_db_column('position', :type => :integer)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
should "include ActsAsList methods" do
|
|
24
|
+
assert klass.include?(ActiveRecord::Acts::List::InstanceMethods)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
should_have_instance_methods :acts_as_list_class, :position_column, :scope_condition
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
$:.reject! { |e| e.include? 'TextMate' }
|
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
|
3
|
+
#require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
|
|
4
|
+
require 'test_help'
|
|
5
|
+
require 'factory_girl'
|
|
6
|
+
require 'ruby-debug'
|
|
7
|
+
require 'mocha'
|
|
8
|
+
require 'authlogic/test_case'
|
|
9
|
+
require 'redgreen' rescue LoadError
|
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/factories')
|
|
11
|
+
require File.join(File.dirname(__FILE__), 'shoulda_macros', 'controller')
|
|
12
|
+
class ActiveSupport::TestCase
|
|
13
|
+
self.use_transactional_fixtures = true
|
|
14
|
+
self.use_instantiated_fixtures = false
|
|
15
|
+
|
|
16
|
+
include Authlogic::TestCase
|
|
17
|
+
|
|
18
|
+
def login_as(user)
|
|
19
|
+
success = UserSession.create(user)
|
|
20
|
+
if !success
|
|
21
|
+
errors = user.errors.full_messages.to_sentence
|
|
22
|
+
message = 'User has not been activated' if !user.active?
|
|
23
|
+
raise "could not login as #{user.to_param}. Please make sure the user is valid. #{message} #{errors}"
|
|
24
|
+
end
|
|
25
|
+
UserSession.find
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def assure_logout
|
|
29
|
+
user_session = UserSession.find
|
|
30
|
+
user_session.destroy if user_session
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def ensure_flash(val)
|
|
34
|
+
assert_contains flash.values, val, ", Flash: #{flash.inspect}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
2
|
+
require 'muck_user_mailer'
|
|
3
|
+
|
|
4
|
+
class MuckUserMailerTest < ActiveSupport::TestCase
|
|
5
|
+
|
|
6
|
+
context "deliver emails" do
|
|
7
|
+
|
|
8
|
+
def setup
|
|
9
|
+
ActionMailer::Base.delivery_method = :test
|
|
10
|
+
ActionMailer::Base.perform_deliveries = true
|
|
11
|
+
ActionMailer::Base.deliveries = []
|
|
12
|
+
@expected = TMail::Mail.new
|
|
13
|
+
@expected.set_content_type "text", "plain", { "charset" => 'utf-8' }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
should "send activation confirmation email" do
|
|
17
|
+
user = Factory(:user)
|
|
18
|
+
response = MuckUserMailer.deliver_activation_confirmation(user)
|
|
19
|
+
assert !ActionMailer::Base.deliveries.empty?, "No email was sent"
|
|
20
|
+
assert_match "#{user.login}", response.body, "User login was not found in the email"
|
|
21
|
+
email = ActionMailer::Base.deliveries.last
|
|
22
|
+
assert_equal email.to, [user.email]
|
|
23
|
+
assert_equal email.from, [GlobalConfig.from_email]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
should "send activation instructions email" do
|
|
27
|
+
user = Factory(:user)
|
|
28
|
+
response = MuckUserMailer.deliver_activation_instructions(user)
|
|
29
|
+
assert !ActionMailer::Base.deliveries.empty?, "No email was sent"
|
|
30
|
+
assert_match "#{user.login}", response.body, "User login was not found in the email"
|
|
31
|
+
email = ActionMailer::Base.deliveries.last
|
|
32
|
+
assert_equal email.to, [user.email]
|
|
33
|
+
assert_equal email.from, [GlobalConfig.from_email]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
should "send password reset account not active instructions email" do
|
|
37
|
+
user = Factory(:user)
|
|
38
|
+
response = MuckUserMailer.deliver_password_not_active_instructions(user)
|
|
39
|
+
assert !ActionMailer::Base.deliveries.empty?, "No email was sent"
|
|
40
|
+
email = ActionMailer::Base.deliveries.last
|
|
41
|
+
assert_equal email.to, [user.email]
|
|
42
|
+
assert_equal email.from, [GlobalConfig.from_email]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
should "send password reset instructions email" do
|
|
46
|
+
user = Factory(:user)
|
|
47
|
+
response = MuckUserMailer.deliver_password_reset_instructions(user)
|
|
48
|
+
assert !ActionMailer::Base.deliveries.empty?, "No email was sent"
|
|
49
|
+
email = ActionMailer::Base.deliveries.last
|
|
50
|
+
assert_equal email.to, [user.email]
|
|
51
|
+
assert_equal email.from, [GlobalConfig.from_email]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
should "send welcome email" do
|
|
55
|
+
user = Factory(:user)
|
|
56
|
+
response = MuckUserMailer.deliver_welcome_notification(user)
|
|
57
|
+
assert !ActionMailer::Base.deliveries.empty?, "No email was sent"
|
|
58
|
+
email = ActionMailer::Base.deliveries.last
|
|
59
|
+
assert_equal email.to, [user.email]
|
|
60
|
+
assert_equal email.from, [GlobalConfig.from_email]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
2
|
+
|
|
3
|
+
class PermissionTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
should_belong_to :user
|
|
6
|
+
should_belong_to :role
|
|
7
|
+
|
|
8
|
+
context "Create new permission" do
|
|
9
|
+
should "should create a new permission" do
|
|
10
|
+
assert_difference 'Permission.count' do
|
|
11
|
+
user = Factory(:user)
|
|
12
|
+
role = Factory(:role)
|
|
13
|
+
permission = Permission.create(:user => user, :role => role)
|
|
14
|
+
permission.save
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|