clearance 0.10.3.2 → 0.10.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ 0.10.4
2
+ ------------------
3
+
4
+ * Formtastic views generator removed.
5
+ * Emails forced to be downcased (particularly for iPhone user case). (Adam Conrad)
6
+ * Suite converted from test/unit to RSpec. (Joe Ferris)
7
+ * Password reset requires a password. (Joel Meador)
8
+ * Use HTML5 email fields.
9
+
1
10
  0.10.3.2
2
11
  ------------------
3
12
 
data/Gemfile CHANGED
@@ -5,17 +5,13 @@ gem "rake"
5
5
  gem "rails", ">= 3.0.3"
6
6
  gem "thin"
7
7
  gem "shoulda"
8
- gem "sqlite3-ruby"
8
+ gem "sqlite3"
9
9
  gem "factory_girl"
10
10
  gem "diesel"
11
11
  gem "cucumber-rails"
12
12
  gem "capybara"
13
13
  gem "factory_girl_rails"
14
14
  gem "rspec-rails"
15
- gem "formtastic"
16
- gem "database_cleaner"
17
15
  gem "dynamic_form"
18
16
  gem "launchy"
19
- gem "redgreen"
20
17
  gem "mocha"
21
-
data/Gemfile.lock CHANGED
@@ -57,7 +57,6 @@ GEM
57
57
  cucumber (>= 0.8.0)
58
58
  culerity (0.2.14)
59
59
  daemons (1.1.0)
60
- database_cleaner (0.6.0)
61
60
  diesel (0.1.4)
62
61
  railties (~> 3.0.3)
63
62
  diff-lcs (1.1.2)
@@ -71,10 +70,6 @@ GEM
71
70
  railties (>= 3.0.0)
72
71
  ffi (0.6.3)
73
72
  rake (>= 0.8.7)
74
- formtastic (1.2.3)
75
- actionpack (>= 2.3.7)
76
- activesupport (>= 2.3.7)
77
- i18n (~> 0.4)
78
73
  gherkin (2.3.3)
79
74
  json (~> 1.4.6)
80
75
  i18n (0.5.0)
@@ -112,7 +107,6 @@ GEM
112
107
  rake (>= 0.8.7)
113
108
  thor (~> 0.14.4)
114
109
  rake (0.8.7)
115
- redgreen (1.2.2)
116
110
  rspec (2.3.0)
117
111
  rspec-core (~> 2.3.0)
118
112
  rspec-expectations (~> 2.3.0)
@@ -133,7 +127,7 @@ GEM
133
127
  json_pure
134
128
  rubyzip
135
129
  shoulda (2.11.3)
136
- sqlite3-ruby (1.3.2)
130
+ sqlite3 (1.3.3)
137
131
  term-ansicolor (1.0.5)
138
132
  thin (1.2.7)
139
133
  daemons (>= 1.0.9)
@@ -154,18 +148,15 @@ DEPENDENCIES
154
148
  capybara
155
149
  cucumber
156
150
  cucumber-rails
157
- database_cleaner
158
151
  diesel
159
152
  dynamic_form
160
153
  factory_girl
161
154
  factory_girl_rails
162
- formtastic
163
155
  launchy
164
156
  mocha
165
157
  rails (>= 3.0.3)
166
158
  rake
167
- redgreen
168
159
  rspec-rails
169
160
  shoulda
170
- sqlite3-ruby
161
+ sqlite3
171
162
  thin
data/README.md CHANGED
@@ -73,13 +73,17 @@ See config/routes.rb for all the routes Clearance provides.
73
73
  Actions that redirect (create, update, and destroy) in Clearance controllers
74
74
  can be overridden by re-defining url_after_(action) methods as seen above.
75
75
 
76
+ Clearance is an engine, so it provides views for you. If you want to customize those views, there is a handy shortcut to copy the views into your app:
77
+
78
+ rails generate clearance:views
79
+
76
80
  Optional Cucumber features
77
81
  --------------------------
78
82
 
79
83
  As your app evolves, you want to know that authentication still works. If you
80
84
  use [Cucumber](http://cukes.info), run the Clearance features generator:
81
85
 
82
- rails generate clearance_features
86
+ rails generate clearance:features
83
87
 
84
88
  Edit your Gemfile to include:
85
89
 
@@ -93,13 +97,6 @@ Then run your tests!
93
97
 
94
98
  rake
95
99
 
96
- Optional Formtastic views
97
- -------------------------
98
-
99
- Clearance can also generate [Formtastic](http://github.com/justinfrench/formtastic) views:
100
-
101
- rails generate clearance_views
102
-
103
100
  Extensions
104
101
  ----------
105
102
 
data/Rakefile CHANGED
@@ -6,12 +6,10 @@ require 'rake'
6
6
  require 'rake/gempackagetask'
7
7
  require 'cucumber/rake/task'
8
8
  require 'diesel/tasks'
9
+ require 'rspec/core/rake_task'
9
10
 
10
- Rake::TestTask.new do |task|
11
- task.libs << "lib"
12
- task.libs << "test"
13
- task.pattern = "test/*/*_test.rb"
14
- task.verbose = false
11
+ RSpec::Core::RakeTask.new do |t|
12
+ t.pattern = 'spec/**/*_spec.rb'
15
13
  end
16
14
 
17
15
  Cucumber::Rake::Task.new(:cucumber) do |t|
@@ -19,6 +17,6 @@ Cucumber::Rake::Task.new(:cucumber) do |t|
19
17
  t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
20
18
  end
21
19
 
22
- desc "Default: run the unit tests and cucumber features"
23
- task :default => [:test, :cucumber]
20
+ desc "Default: run the specs and cucumber features"
21
+ task :default => [:spec, :cucumber]
24
22
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.3.2
1
+ 0.10.4
@@ -7,7 +7,7 @@
7
7
  <%= form_for :password, :url => passwords_path do |form| %>
8
8
  <div class="text_field">
9
9
  <%= form.label :email, "Email address" %>
10
- <%= form.text_field :email %>
10
+ <%= form.text_field :email, :type => "email" %>
11
11
  </div>
12
12
  <div class="submit_field">
13
13
  <%= form.submit "Reset password" %>
@@ -3,7 +3,7 @@
3
3
  <%= form_for :session, :url => session_path do |form| %>
4
4
  <div class="text_field">
5
5
  <%= form.label :email %>
6
- <%= form.text_field :email %>
6
+ <%= form.text_field :email, :type => "email" %>
7
7
  </div>
8
8
  <div class="text_field">
9
9
  <%= form.label :password %>
@@ -1,7 +1,7 @@
1
1
  <%= form.error_messages %>
2
2
  <div class="text_field">
3
3
  <%= form.label :email %>
4
- <%= form.text_field :email %>
4
+ <%= form.text_field :email, :type => "email" %>
5
5
  </div>
6
6
  <div class="password_field">
7
7
  <%= form.label :password %>
@@ -15,6 +15,17 @@ Feature: Password reset
15
15
  Then I should see "instructions for changing your password"
16
16
  And a password reset message should be sent to "email@example.com"
17
17
 
18
+ Scenario: User is signed up updated his password and tries blank password and confirmation
19
+ Given I signed up with "email@example.com/password"
20
+ And I go to the password reset request page
21
+ Then I should see an email field
22
+ And I fill in "Email address" with "email@example.com"
23
+ And I press "Reset password"
24
+ When I follow the password reset link sent to "email@example.com"
25
+ And I update my password with "/"
26
+ Then I should see an error message
27
+ And I should be signed out
28
+
18
29
  Scenario: User is signed up updated his password and types wrong confirmation
19
30
  Given I signed up with "email@example.com/password"
20
31
  And I go to the password reset request page
@@ -21,8 +21,18 @@ Feature: Sign in
21
21
  Scenario: Visitor signs in successfully
22
22
  Given I am signed up as "email@person.com/password"
23
23
  When I go to the sign in page
24
+ Then I should see an email field
24
25
  And I sign in as "email@person.com/password"
25
26
  Then I should see "Signed in"
26
27
  And I should be signed in
27
28
  When I return next time
28
29
  Then I should be signed in
30
+
31
+ Scenario: Visitor signs in successfully with uppercase email
32
+ Given I am signed up as "email@person.com/password"
33
+ When I go to the sign in page
34
+ And I sign in as "Email@person.com/password"
35
+ Then I should see "Signed in"
36
+ And I should be signed in
37
+ When I return next time
38
+ Then I should be signed in
@@ -4,17 +4,19 @@ Feature: Sign up
4
4
  As a visitor
5
5
  I want to sign up
6
6
 
7
- Scenario: Visitor signs up with invalid data
7
+ Background:
8
8
  When I go to the sign up page
9
- And I fill in "Email" with "invalidemail"
9
+ Then I should see an email field
10
+
11
+ Scenario: Visitor signs up with invalid data
12
+ When I fill in "Email" with "invalidemail"
10
13
  And I fill in "Password" with "password"
11
14
  And I fill in "Confirm password" with ""
12
15
  And I press "Sign up"
13
16
  Then I should see error messages
14
17
 
15
18
  Scenario: Visitor signs up with valid data
16
- When I go to the sign up page
17
- And I fill in "Email" with "email@person.com"
19
+ When I fill in "Email" with "email@person.com"
18
20
  And I fill in "Password" with "password"
19
21
  And I fill in "Confirm password" with "password"
20
22
  And I press "Sign up"
@@ -11,9 +11,9 @@ Feature: integrate with application
11
11
  And I add the "cucumber-rails" gem
12
12
  And I add the "capybara" gem
13
13
  And I add the "rspec-rails" gem
14
- And I add the "formtastic" gem
15
14
  And I add the "factory_girl_rails" gem
16
15
  And I add the "dynamic_form" gem
16
+ And I add the "database_cleaner" gem
17
17
  And I add the "clearance" gem from this project
18
18
  And I add the "diesel" gem
19
19
  And I run "bundle install --local"
@@ -8,6 +8,14 @@ Then /^I should see an error message$/ do
8
8
  Then %{I should see "error prohibited"}
9
9
  end
10
10
 
11
+ Then /^I should see an email field$/ do
12
+ if page.respond_to?(:should)
13
+ page.should have_css("input[type='email']")
14
+ else
15
+ assert page.has_css("input[type='email']")
16
+ end
17
+ end
18
+
11
19
  # Database
12
20
 
13
21
  Given /^no user exists with an email of "(.*)"$/ do |email|
@@ -65,7 +65,9 @@ module Clearance
65
65
  end
66
66
  end
67
67
 
68
- class Test::Unit::TestCase
69
- include Clearance::Shoulda::Helpers
68
+ if defined?(Test::Unit::TestCase)
69
+ class Test::Unit::TestCase
70
+ include Clearance::Shoulda::Helpers
71
+ end
72
+ Test::Unit::TestCase.extend(Clearance::Shoulda)
70
73
  end
71
- Test::Unit::TestCase.extend(Clearance::Shoulda)
@@ -35,6 +35,8 @@ module Clearance
35
35
  def self.included(model)
36
36
  model.class_eval do
37
37
  attr_accessor :password, :password_confirmation
38
+ private
39
+ attr_accessor :password_changing
38
40
  end
39
41
  end
40
42
  end
@@ -64,6 +66,7 @@ module Clearance
64
66
  # salt, token, password encryption are handled before_save.
65
67
  def self.included(model)
66
68
  model.class_eval do
69
+ before_validation :downcase_email
67
70
  before_save :initialize_salt,
68
71
  :encrypt_password
69
72
  before_create :generate_remember_token
@@ -115,6 +118,7 @@ module Clearance
115
118
  # @example
116
119
  # user.update_password('new-password', 'new-password')
117
120
  def update_password(new_password, new_password_confirmation)
121
+ self.password_changing = true
118
122
  self.password = new_password
119
123
  self.password_confirmation = new_password_confirmation
120
124
  if valid?
@@ -162,17 +166,21 @@ module Clearance
162
166
  end
163
167
 
164
168
  # True if the password has been set and the password is not being
165
- # updated. Override to allow other forms of # authentication (username,
166
- # facebook, etc).
169
+ # updated and we are not updating the password. Override to allow
170
+ # other forms of authentication (username, facebook, etc).
167
171
  # @return [Boolean] true if the password field can be left blank for this user
168
172
  def password_optional?
169
- encrypted_password.present? && password.blank?
173
+ encrypted_password.present? && password.blank? && password_changing.blank?
170
174
  end
171
175
 
172
176
  def password_required?
173
177
  # warn "[DEPRECATION] password_required?: use !password_optional? instead"
174
178
  !password_optional?
175
179
  end
180
+
181
+ def downcase_email
182
+ self.email = email.to_s.downcase
183
+ end
176
184
  end
177
185
 
178
186
  module ClassMethods
@@ -183,7 +191,7 @@ module Clearance
183
191
  # @example
184
192
  # User.authenticate("email@example.com", "password")
185
193
  def authenticate(email, password)
186
- return nil unless user = find_by_email(email)
194
+ return nil unless user = find_by_email(email.to_s.downcase)
187
195
  return user if user.authenticated?(password)
188
196
  end
189
197
  end
@@ -20,9 +20,9 @@ module Clearance
20
20
  end
21
21
 
22
22
  if File.exists?("spec")
23
- template "test/factories.rb", "spec/factories/clearance.rb"
23
+ template "spec/factories.rb", "spec/factories/clearance.rb"
24
24
  else
25
- template "test/factories.rb", "test/factories/clearance.rb"
25
+ template "spec/factories.rb", "test/factories/clearance.rb"
26
26
  end
27
27
 
28
28
  readme "README"
@@ -0,0 +1,177 @@
1
+ require 'spec_helper'
2
+
3
+ describe Clearance::PasswordsController do
4
+
5
+ include Shoulda::ActionMailer::Matchers
6
+
7
+ it { should route(:get, '/users/1/password/edit').
8
+ to(:controller => 'clearance/passwords', :action => 'edit', :user_id => '1') }
9
+
10
+ describe "a signed up user" do
11
+ before do
12
+ @user = Factory(:user)
13
+ end
14
+
15
+ describe "on GET to #new" do
16
+ before { get :new, :user_id => @user.to_param }
17
+
18
+ it { should respond_with(:success) }
19
+ it { should render_template(:new) }
20
+ end
21
+
22
+ describe "on POST to #create" do
23
+ describe "with correct email address" do
24
+ before do
25
+ ActionMailer::Base.deliveries.clear
26
+ post :create, :password => { :email => @user.email }
27
+ end
28
+
29
+ it "should generate a token for the change your password email" do
30
+ @user.reload.confirmation_token.should_not be_nil
31
+ end
32
+
33
+ it { should have_sent_email.with_subject(/change your password/i) }
34
+
35
+ it { should set_the_flash.to(/password/i) }
36
+ it { should redirect_to_url_after_create }
37
+ end
38
+
39
+ describe "with incorrect email address" do
40
+ before do
41
+ email = "user1@example.com"
42
+ (::User.exists?(['email = ?', email])).should_not be
43
+ ActionMailer::Base.deliveries.clear
44
+ @user.reload.confirmation_token.should == @user.confirmation_token
45
+
46
+ post :create, :password => { :email => email }
47
+ end
48
+
49
+ it "should not generate a token for the change your password email" do
50
+ @user.reload.confirmation_token.should == @user.confirmation_token
51
+ end
52
+
53
+ it "should not send a password reminder email" do
54
+ ActionMailer::Base.deliveries.should be_empty
55
+ end
56
+
57
+ it "should set the failure flash to Unknown email" do
58
+ flash.now[:failure].should =~ /unknown email/i
59
+ end
60
+
61
+ it { should render_template(:new) }
62
+ end
63
+ end
64
+ end
65
+
66
+ describe "a signed up user and forgotten password" do
67
+ before do
68
+ @user = Factory(:user)
69
+ @user.forgot_password!
70
+ end
71
+
72
+ describe "on GET to #edit with correct id and token" do
73
+ before do
74
+ get :edit, :user_id => @user.to_param,
75
+ :token => @user.confirmation_token
76
+ end
77
+
78
+ it "should find the user" do
79
+ assigns(:user).should == @user
80
+ end
81
+
82
+ it { should respond_with(:success) }
83
+ it { should render_template(:edit) }
84
+ end
85
+
86
+ describe "on GET to #edit with correct id but blank token" do
87
+ before do
88
+ get :edit, :user_id => @user.to_param, :token => ""
89
+ end
90
+
91
+ it { should set_the_flash.to(/double check the URL/i) }
92
+ it { should render_template(:new) }
93
+ end
94
+
95
+ describe "on GET to #edit with correct id but no token" do
96
+ before do
97
+ get :edit, :user_id => @user.to_param
98
+ end
99
+
100
+ it { should set_the_flash.to(/double check the URL/i) }
101
+ it { should render_template(:new) }
102
+ end
103
+
104
+ describe "on PUT to #update with matching password and password confirmation" do
105
+ before do
106
+ new_password = "new_password"
107
+ @encrypted_new_password = @user.send(:encrypt, new_password)
108
+ @user.encrypted_password.should_not == @encrypted_new_password
109
+
110
+ put(:update,
111
+ :user_id => @user,
112
+ :token => @user.confirmation_token,
113
+ :user => {
114
+ :password => new_password,
115
+ :password_confirmation => new_password
116
+ })
117
+ @user.reload
118
+ end
119
+
120
+ it "should update password" do
121
+ @user.encrypted_password.should == @encrypted_new_password
122
+ end
123
+
124
+ it "should clear confirmation token" do
125
+ @user.confirmation_token.should be_nil
126
+ end
127
+
128
+ it "should set remember token" do
129
+ @user.remember_token.should_not be_nil
130
+ end
131
+
132
+ it { should set_the_flash.to(/signed in/i) }
133
+ it { should redirect_to_url_after_update }
134
+ end
135
+
136
+ describe "on PUT to #update with password but blank password confirmation" do
137
+ before do
138
+ new_password = "new_password"
139
+ @encrypted_new_password = @user.send(:encrypt, new_password)
140
+
141
+ put(:update,
142
+ :user_id => @user.to_param,
143
+ :token => @user.confirmation_token,
144
+ :user => {
145
+ :password => new_password,
146
+ :password_confirmation => ''
147
+ })
148
+ @user.reload
149
+ end
150
+
151
+ it "should not update password" do
152
+ @user.encrypted_password.should_not == @encrypted_new_password
153
+ end
154
+
155
+ it "should not clear token" do
156
+ @user.confirmation_token.should_not be_nil
157
+ end
158
+
159
+ it "should not be signed in" do
160
+ cookies[:remember_token].should be_nil
161
+ end
162
+
163
+ it { should_not set_the_flash }
164
+ it { should respond_with(:success) }
165
+ it { should render_template(:edit) }
166
+ end
167
+ end
168
+
169
+ describe "given two users and user one signs in" do
170
+ before do
171
+ @user_one = Factory(:user)
172
+ @user_two = Factory(:user)
173
+ sign_in_as @user_one
174
+ end
175
+ end
176
+
177
+ end