gravis-clearance 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/LICENSE +21 -0
  2. data/README.textile +165 -0
  3. data/Rakefile +46 -0
  4. data/TODO.textile +22 -0
  5. data/generators/clearance/USAGE +1 -0
  6. data/generators/clearance/clearance_generator.rb +73 -0
  7. data/generators/clearance/templates/app/controllers/application.rb +5 -0
  8. data/generators/clearance/templates/app/controllers/confirmations_controller.rb +3 -0
  9. data/generators/clearance/templates/app/controllers/passwords_controller.rb +3 -0
  10. data/generators/clearance/templates/app/controllers/sessions_controller.rb +3 -0
  11. data/generators/clearance/templates/app/controllers/users_controller.rb +3 -0
  12. data/generators/clearance/templates/app/models/clearance_mailer.rb +5 -0
  13. data/generators/clearance/templates/app/models/user.rb +3 -0
  14. data/generators/clearance/templates/app/views/clearance_mailer/change_password.html.erb +6 -0
  15. data/generators/clearance/templates/app/views/clearance_mailer/confirmation.html.erb +1 -0
  16. data/generators/clearance/templates/app/views/confirmations/new.html.erb +6 -0
  17. data/generators/clearance/templates/app/views/passwords/edit.html.erb +23 -0
  18. data/generators/clearance/templates/app/views/passwords/new.html.erb +15 -0
  19. data/generators/clearance/templates/app/views/sessions/new.html.erb +26 -0
  20. data/generators/clearance/templates/app/views/users/_form.html.erb +13 -0
  21. data/generators/clearance/templates/app/views/users/edit.html.erb +4 -0
  22. data/generators/clearance/templates/app/views/users/new.html.erb +4 -0
  23. data/generators/clearance/templates/test/factories.rb +9 -0
  24. data/generators/clearance/templates/test/functional/confirmations_controller_test.rb +5 -0
  25. data/generators/clearance/templates/test/functional/passwords_controller_test.rb +5 -0
  26. data/generators/clearance/templates/test/functional/sessions_controller_test.rb +5 -0
  27. data/generators/clearance/templates/test/functional/users_controller_test.rb +5 -0
  28. data/generators/clearance/templates/test/unit/clearance_mailer_test.rb +6 -0
  29. data/generators/clearance/templates/test/unit/user_test.rb +5 -0
  30. data/lib/clearance.rb +15 -0
  31. data/lib/clearance/app/controllers/application_controller.rb +84 -0
  32. data/lib/clearance/app/controllers/confirmations_controller.rb +46 -0
  33. data/lib/clearance/app/controllers/passwords_controller.rb +67 -0
  34. data/lib/clearance/app/controllers/sessions_controller.rb +79 -0
  35. data/lib/clearance/app/controllers/users_controller.rb +47 -0
  36. data/lib/clearance/app/models/clearance_mailer.rb +33 -0
  37. data/lib/clearance/app/models/user.rb +93 -0
  38. data/lib/clearance/test/functional/confirmations_controller_test.rb +85 -0
  39. data/lib/clearance/test/functional/passwords_controller_test.rb +188 -0
  40. data/lib/clearance/test/functional/sessions_controller_test.rb +148 -0
  41. data/lib/clearance/test/functional/users_controller_test.rb +67 -0
  42. data/lib/clearance/test/test_helper.rb +94 -0
  43. data/lib/clearance/test/unit/clearance_mailer_test.rb +63 -0
  44. data/lib/clearance/test/unit/user_test.rb +222 -0
  45. data/lib/clearance/version.rb +7 -0
  46. metadata +120 -0
@@ -0,0 +1,67 @@
1
+ module Clearance
2
+ module Test
3
+ module Functional
4
+ module UsersControllerTest
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ public_context do
9
+
10
+ context "on GET to /users/new" do
11
+ setup { get :new }
12
+ should_respond_with :success
13
+ should_render_template :new
14
+ should_not_set_the_flash
15
+ should_have_form :action => "users_path",
16
+ :method => :post,
17
+ :fields => { :email => :text,
18
+ :password => :password,
19
+ :password_confirmation => :password }
20
+
21
+ context "with params" do
22
+ setup do
23
+ @email = 'a@example.com'
24
+ get :new, :user => {:email => @email}
25
+ end
26
+
27
+ should_assign_to :user
28
+ should "set the @user's params" do
29
+ assert_equal @email, assigns(:user).email
30
+ end
31
+ end
32
+ end
33
+
34
+ context "on POST to /users" do
35
+ setup do
36
+ post :create, :user => Factory.build(:user).attributes.merge(
37
+ {:password => 'skerit',
38
+ :password_confirmation => 'skerit'})
39
+ end
40
+
41
+ should_set_the_flash_to /confirm/i
42
+ should_redirect_to "@controller.send(:url_after_create)"
43
+ should_assign_to :user
44
+ should_change 'User.count', :by => 1
45
+ end
46
+
47
+ end
48
+
49
+ logged_in_user_context do
50
+ context "GET to new" do
51
+ setup { get :new }
52
+ should_redirect_to 'root_url'
53
+ end
54
+
55
+ context "POST to create" do
56
+ setup { post :create, :user => {} }
57
+ should_redirect_to 'root_url'
58
+ end
59
+
60
+ should_filter_params :password
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,94 @@
1
+ module Clearance
2
+ module Test
3
+ module TestHelper
4
+
5
+ def self.included(base)
6
+ base.class_eval do
7
+ include InstanceMethods
8
+ extend ClassMethods
9
+ end
10
+ end
11
+
12
+ module InstanceMethods
13
+ def login_as(user = nil)
14
+ user ||= Factory(:user)
15
+ @request.session[:user_id] = user.id
16
+ return user
17
+ end
18
+
19
+ def logout
20
+ @request.session[:user_id] = nil
21
+ end
22
+ end
23
+
24
+ module ClassMethods
25
+ def should_deny_access_on(command, opts = {})
26
+
27
+ context "on #{command}" do
28
+ setup { eval command }
29
+ should_deny_access(opts)
30
+ end
31
+ end
32
+
33
+ def should_deny_access(opts = {})
34
+ opts[:redirect] ||= "new_session_path"
35
+ should_redirect_to opts[:redirect]
36
+ if opts[:flash]
37
+ should_set_the_flash_to opts[:flash]
38
+ else
39
+ should_not_set_the_flash
40
+ end
41
+ end
42
+
43
+ # should_have_form :action => 'admin_users_path',
44
+ # :method => :get,
45
+ # :fields => { 'email' => :text }
46
+ # TODO: http_method should be pulled out
47
+ def should_have_form(opts)
48
+ model = self.name.gsub(/ControllerTest$/, '').singularize.downcase
49
+ model = model[model.rindex('::')+2..model.size] if model.include?('::')
50
+ http_method, hidden_http_method = form_http_method opts[:method]
51
+ should "have a #{model} form" do
52
+ assert_select "form[action=?][method=#{http_method}]", eval(opts[:action]) do
53
+ if hidden_http_method
54
+ assert_select "input[type=hidden][name=_method][value=#{hidden_http_method}]"
55
+ end
56
+ opts[:fields].each do |attribute, type|
57
+ attribute = attribute.is_a?(Symbol) ? "#{model}[#{attribute.to_s}]" : attribute
58
+ assert_select "input[type=#{type.to_s}][name=?]", attribute
59
+ end
60
+ assert_select "input[type=submit]"
61
+ end
62
+ end
63
+ end
64
+
65
+ def form_http_method(http_method)
66
+ http_method = http_method.nil? ? 'post' : http_method.to_s
67
+ if http_method == "post" || http_method == "get"
68
+ return http_method, nil
69
+ else
70
+ return "post", http_method
71
+ end
72
+ end
73
+
74
+ def logged_in_user_context(&blk)
75
+ context "A logged in user" do
76
+ setup do
77
+ @user = Factory :user
78
+ login_as @user
79
+ end
80
+ merge_block(&blk)
81
+ end
82
+ end
83
+
84
+ def public_context(&blk)
85
+ context "The public" do
86
+ setup { logout }
87
+ merge_block(&blk)
88
+ end
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,63 @@
1
+ module Clearance
2
+ module Test
3
+ module Unit
4
+ module ClearanceMailerTest
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ context "A change password email" do
9
+ setup do
10
+ @user = Factory :user
11
+ @email = ClearanceMailer.create_change_password @user
12
+ end
13
+
14
+ should "set its from address to DO_NOT_REPLY" do
15
+ assert_equal DO_NOT_REPLY, @email.from[0]
16
+ end
17
+
18
+ should "contain a link to edit the user's password" do
19
+ host = ActionMailer::Base.default_url_options[:host]
20
+ regexp = %r{http://#{host}/users/#{@user.id}/password/edit\?email=#{@user.email.gsub("@", "%40")}&password=#{@user.crypted_password}}
21
+ assert_match regexp, @email.body
22
+ end
23
+
24
+ should "be sent to the user" do
25
+ assert_equal [@user.email], @email.to
26
+ end
27
+
28
+ should "have a subject of '[PROJECT_NAME] Change your password'" do
29
+ assert_equal @email.subject, "[#{PROJECT_NAME.humanize}] Change your password"
30
+ end
31
+ end
32
+
33
+ context "A confirmation email" do
34
+ setup do
35
+ @user = Factory :user
36
+ @email = ClearanceMailer.create_confirmation @user
37
+ end
38
+
39
+ should 'set its recipient to the given user' do
40
+ assert_equal @user.email, @email.to[0]
41
+ end
42
+
43
+ should 'set its subject' do
44
+ assert_equal "[#{PROJECT_NAME.humanize}] Account confirmation", @email.subject
45
+ end
46
+
47
+ should 'set its from address to DO_NOT_REPLY' do
48
+ assert_equal DO_NOT_REPLY, @email.from[0]
49
+ end
50
+
51
+ should "contain a link to confirm the user's account" do
52
+ host = ActionMailer::Base.default_url_options[:host]
53
+ regexp = %r{http://#{host}/users/#{@user.id}/confirmation/new\?salt=#{@user.salt}}
54
+ assert_match regexp, @email.body
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,222 @@
1
+ module Clearance
2
+ module Test
3
+ module Unit
4
+ module UserTest
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ should_require_attributes :email, :password
9
+ should_allow_values_for :email, 'foo@example.com'
10
+ should_not_allow_values_for :email, 'foo'
11
+ should_not_allow_values_for :email, 'example.com'
12
+
13
+ should "require password validation on create" do
14
+ user = Factory.build(:user, :password => 'blah', :password_confirmation => 'boogidy')
15
+ assert !user.save
16
+ assert_match(/confirmation/i, user.errors.on(:password))
17
+ end
18
+
19
+ should "create a crypted_password on save" do
20
+ assert_not_nil Factory(:user, :crypted_password => nil).crypted_password
21
+ end
22
+
23
+ context 'updating a password' do
24
+ setup do
25
+ @user = Factory(:user)
26
+ assert_not_nil @user.crypted_password
27
+ @crypt = @user.crypted_password
28
+ assert_not_nil @user.salt
29
+ @salt = @user.salt
30
+ @user.password = 'a_new_password'
31
+ @user.password_confirmation = 'a_new_password'
32
+ assert @user.save
33
+ end
34
+
35
+ should 'update a crypted_password' do
36
+ @user.reload
37
+ assert @user.crypted_password != @crypt
38
+ end
39
+ end
40
+
41
+ context 'A user' do
42
+ setup do
43
+ @salt = 'salt'
44
+ User.any_instance.stubs(:initialize_salt)
45
+ @user = Factory :user, :salt => @salt
46
+ @password = @user.password
47
+ end
48
+
49
+ should "require password validation on update" do
50
+ @user.update_attributes(:password => "blah", :password_confirmation => "boogidy")
51
+ assert !@user.save
52
+ assert_match(/confirmation/i, @user.errors.on(:password))
53
+ end
54
+
55
+ should_require_unique_attributes :email
56
+
57
+ context 'authenticating a user' do
58
+ context 'with good credentials' do
59
+ setup do
60
+ @result = User.authenticate @user.email, @password
61
+ end
62
+
63
+ should 'return true' do
64
+ assert @result
65
+ end
66
+ end
67
+
68
+ context 'with bad credentials' do
69
+ setup do
70
+ @result = User.authenticate @user.email, 'horribly_wrong_password'
71
+ end
72
+
73
+ should 'return false' do
74
+ assert !@result
75
+ end
76
+ end
77
+
78
+ context 'with an upcase email' do
79
+ setup do
80
+ @result = User.authenticate @user.email.upcase, @password
81
+ end
82
+
83
+ should 'return true' do
84
+ assert @result
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ context 'authenticated?' do
91
+ context 'with good credentials' do
92
+ setup do
93
+ @result = @user.authenticated? @password
94
+ end
95
+
96
+ should 'return true' do
97
+ assert @result
98
+ end
99
+ end
100
+
101
+ context 'with bad credentials' do
102
+ setup do
103
+ @result = @user.authenticated? 'horribly_wrong_password'
104
+ end
105
+
106
+ should 'return false' do
107
+ assert !@result
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'encrypt' do
113
+ setup do
114
+ @crypted = @user.encrypt(@password)
115
+ @expected = Digest::SHA1.hexdigest("--#{@salt}--#{@password}--")
116
+ end
117
+
118
+ should 'create a Hash using SHA1 encryption' do
119
+ assert_equal @expected, @crypted
120
+ assert_not_equal @password, @crypted
121
+ end
122
+ end
123
+
124
+ context 'remember_me!' do
125
+ setup do
126
+ assert_nil @user.remember_token
127
+ assert_nil @user.remember_token_expires_at
128
+ @user.remember_me!
129
+ end
130
+
131
+ should 'set the remember token and expiration date' do
132
+ assert_not_nil @user.remember_token
133
+ assert_not_nil @user.remember_token_expires_at
134
+ end
135
+
136
+ should 'remember_token?' do
137
+ assert @user.remember_token?
138
+ end
139
+
140
+ context 'forget_me!' do
141
+ setup do
142
+ @user.forget_me!
143
+ end
144
+
145
+ should 'unset the remember token and expiration date' do
146
+ assert_nil @user.remember_token
147
+ assert_nil @user.remember_token_expires_at
148
+ end
149
+
150
+ should 'not remember_token?' do
151
+ assert ! @user.remember_token?
152
+ end
153
+ end
154
+ end
155
+
156
+ context 'remember_token?' do
157
+ context 'when token expires in the future' do
158
+ setup do
159
+ @user.update_attribute :remember_token_expires_at, 2.weeks.from_now.utc
160
+ end
161
+
162
+ should 'be true' do
163
+ assert @user.remember_token?
164
+ end
165
+ end
166
+
167
+ context 'when token expired' do
168
+ setup do
169
+ @user.update_attribute :remember_token_expires_at, 2.weeks.ago.utc
170
+ end
171
+
172
+ should 'be false' do
173
+ assert ! @user.remember_token?
174
+ end
175
+ end
176
+ end
177
+
178
+ context "User.authenticate with a valid email and password" do
179
+ setup do
180
+ @found_user = User.authenticate @user.email, @user.password
181
+ end
182
+
183
+ should "find that user" do
184
+ assert_equal @user, @found_user
185
+ end
186
+ end
187
+
188
+ context "When sent authenticate with an invalid email and password" do
189
+ setup do
190
+ @found_user = User.authenticate "not", "valid"
191
+ end
192
+
193
+ should "find nothing" do
194
+ assert_nil @found_user
195
+ end
196
+ end
197
+ end
198
+
199
+ context "A user" do
200
+ setup do
201
+ @user = Factory :user
202
+ end
203
+
204
+ context 'when sent #confirm!' do
205
+ setup do
206
+ assert ! @user.confirmed?
207
+ assert @user.confirm!
208
+ @user.reload
209
+ end
210
+
211
+ should 'mark the User record as confirmed' do
212
+ assert @user.confirmed?
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ end
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,7 @@
1
+ module Clearance
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 3
5
+ PATCH = 6
6
+ end
7
+ end