goma 0.0.1.gamma → 0.0.1.rc1

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/Gemfile.lock +13 -9
  4. data/Rakefile +14 -0
  5. data/goma.gemspec +6 -0
  6. data/lib/generators/goma/erb/templates/confirmation/new.html.erb +2 -2
  7. data/lib/generators/goma/erb/templates/password/edit.html.erb +6 -6
  8. data/lib/generators/goma/erb/templates/unlock/new.html.erb +1 -1
  9. data/lib/generators/goma/erb/templates/user/_form.html.erb +1 -1
  10. data/lib/generators/goma/erb/templates/user/new.html.erb +4 -0
  11. data/lib/generators/goma/mailer/erb/templates/activation_needed_email.text.erb +1 -1
  12. data/lib/generators/goma/model/active_record_generator.rb +1 -0
  13. data/lib/generators/goma/model/oauth/active_record_generator.rb +3 -3
  14. data/lib/generators/goma/resource_route/resource_route_generator.rb +13 -9
  15. data/lib/generators/goma/scaffold_controller/templates/confirmation_controller.rb +8 -4
  16. data/lib/generators/goma/scaffold_controller/templates/oauth_controller.rb +5 -0
  17. data/lib/generators/goma/scaffold_controller/templates/password_controller.rb +9 -4
  18. data/lib/generators/goma/scaffold_controller/templates/unlock_controller.rb +1 -0
  19. data/lib/generators/goma/scaffold_controller/templates/user_controller.rb +41 -1
  20. data/lib/goma/config.rb +4 -4
  21. data/lib/goma/models/authenticatable.rb +20 -9
  22. data/lib/goma/models/confirmable.rb +15 -9
  23. data/lib/goma/models/password_authenticatable.rb +2 -1
  24. data/lib/goma/models/recoverable.rb +1 -1
  25. data/lib/goma/models/validatable.rb +4 -4
  26. data/lib/goma/railtie.rb +1 -0
  27. data/lib/goma/version.rb +1 -1
  28. data/test/integration/confirmable_integration_test.rb +185 -0
  29. data/test/integration/lockable_integration_test.rb +49 -0
  30. data/test/integration/omniauthable_integration_test.rb +64 -12
  31. data/test/integration/password_authenticatable_integration_test.rb +40 -0
  32. data/test/integration/recoverable_integration_test.rb +96 -0
  33. data/test/integration/rememberable_integration_test.rb +14 -0
  34. data/test/models/confirmable_test.rb +6 -6
  35. data/test/models/omniauthable_test.rb +2 -2
  36. data/test/rails_app/app/controllers/authentications_controller.rb +5 -0
  37. data/test/rails_app/app/controllers/confirmations_controller.rb +8 -4
  38. data/test/rails_app/app/controllers/passwords_controller.rb +9 -4
  39. data/test/rails_app/app/controllers/unlocks_controller.rb +1 -0
  40. data/test/rails_app/app/controllers/users_controller.rb +25 -2
  41. data/test/rails_app/app/views/confirmations/new.html.erb +2 -2
  42. data/test/rails_app/app/views/layouts/application.html.erb +3 -1
  43. data/test/rails_app/app/views/passwords/edit.html.erb +6 -6
  44. data/test/rails_app/app/views/unlocks/new.html.erb +1 -1
  45. data/test/rails_app/app/views/user_mailer/activation_needed_email.text.erb +1 -1
  46. data/test/rails_app/app/views/users/_form.html.erb +1 -1
  47. data/test/rails_app/app/views/users/new.html.erb +1 -0
  48. data/test/rails_app/config/initializers/omniauth.rb +0 -1
  49. data/test/rails_app/config/routes.rb +6 -10
  50. data/test/rails_app/db/migrate/{20140512081308_create_users.rb → 20140515111009_create_users.rb} +0 -0
  51. data/test/rails_app/db/migrate/{20140512081309_create_authentications.rb → 20140515111010_create_authentications.rb} +0 -0
  52. data/test/rails_app/db/schema.rb +1 -1
  53. data/test/test_helper.rb +43 -0
  54. metadata +33 -13
  55. data/test/controllers/confirmations_controller_test.rb +0 -14
  56. data/test/controllers/users_controller_test.rb +0 -12
  57. data/test/integration/authenticatable_integration_test.rb +0 -26
data/lib/goma/config.rb CHANGED
@@ -134,6 +134,10 @@ module Goma
134
134
  config_accessor(:oauth_uid_attribute_name) { :uid }
135
135
 
136
136
 
137
+ def password_confirmation_attribute_name
138
+ @password_confirmation_attribute_name ||= "#{password_attribute_name}_confirmation".to_sym
139
+ end
140
+
137
141
  self.instance_methods(false).grep(/attribute_name$/).each do |conf_name|
138
142
  name = conf_name.to_s[0...-15]
139
143
 
@@ -153,10 +157,6 @@ module Goma
153
157
  RUBY
154
158
  end
155
159
 
156
- def password_confirmation_attribute_name
157
- @password_confirmation_attribute_name ||= "#{password_attribute_name}_confirmation".to_sym
158
- end
159
-
160
160
  def oauth_association_name
161
161
  @oauth_association_name ||=
162
162
  oauth_authentication_class_name ? oauth_authentication_class_name.underscore.pluralize.to_sym : ''
@@ -34,10 +34,10 @@ module Goma
34
34
  # You don't have to call this method directly.
35
35
  # This method is called from the modules defined under {Goma::Models}
36
36
  # @return [Object, Symbol] Object load from the token and nil or, if it failed, nil and a symbol which indicates reason
37
- def load_from_token_with_error(raw_token, token_attr, token_sent_at_attr, valid_period)
37
+ def load_from_token_with_error(raw_token, token_attr, token_sent_at_attr, valid_period=nil)
38
38
  token = Goma.token_generator.digest(token_attr, raw_token)
39
39
  if record = self.find_by(token_attr => token)
40
- if Time.new.utc - record.send(token_sent_at_attr) <= valid_period
40
+ if valid_period.nil? || (Time.new.utc - record.send(token_sent_at_attr) <= valid_period)
41
41
  [record, nil]
42
42
  else
43
43
  [nil, :token_expired]
@@ -77,14 +77,25 @@ module Goma
77
77
  class << self
78
78
  # class methods
79
79
 
80
- def define_load_from_token_with_error_method_for(target, purpose)
81
- target.module_eval <<-METHOD, __FILE__, __LINE__ + 1
82
- def load_from_#{purpose}_token_with_error(raw_token, valid_period)
83
- token_attr = goma_config.#{purpose}_token_attribute_name
84
- token_sent_at_attr = goma_config.#{purpose}_token_sent_at_attribute_name
85
- load_from_token_with_error(raw_token, token_attr, token_sent_at_attr, valid_period)
80
+ def define_load_from_token_with_error_method_for(target, name, valid_period_config=nil, purpose=name)
81
+ if valid_period_config
82
+ target.module_eval <<-METHOD, __FILE__, __LINE__ + 1
83
+ def load_from_#{purpose}_token_with_error(raw_token)
84
+ token_attr = goma_config.#{name}_token_attribute_name
85
+ token_sent_at_attr = goma_config.#{name}_token_sent_at_attribute_name
86
+ valid_period = goma_config.#{valid_period_config}
87
+ load_from_token_with_error(raw_token, token_attr, token_sent_at_attr, valid_period)
88
+ end
89
+ METHOD
90
+ else
91
+ target.module_eval <<-METHOD, __FILE__, __LINE__ + 1
92
+ def load_from_#{purpose}_token_with_error(raw_token)
93
+ token_attr = goma_config.#{name}_token_attribute_name
94
+ token_sent_at_attr = goma_config.#{name}_token_sent_at_attribute_name
95
+ load_from_token_with_error(raw_token, token_attr, token_sent_at_attr)
96
+ end
97
+ METHOD
86
98
  end
87
- METHOD
88
99
  end
89
100
 
90
101
  def define_load_from_token_methods_for(target, purpose)
@@ -14,17 +14,11 @@ module Goma
14
14
 
15
15
  # @!parse extend ClassMethods
16
16
  module ClassMethods
17
- DefinitionHelper.define_load_from_token_with_error_method_for(self, :confirmation)
18
-
19
- def load_from_activation_token_with_error(raw_token)
20
- load_from_confirmation_token_with_error(raw_token, goma_config.activate_within)
21
- end
17
+ DefinitionHelper.define_load_from_token_with_error_method_for(self, :confirmation, :activate_within, :activation)
18
+ DefinitionHelper.define_load_from_token_methods_for(self, :activation)
22
19
 
23
- def load_from_email_confirmation_token_with_error(raw_token)
24
- load_from_confirmation_token_with_error(raw_token, goma_config.confirm_email_within)
25
- end
20
+ DefinitionHelper.define_load_from_token_with_error_method_for(self, :confirmation, :confirm_email_within, :email_confirmation)
26
21
 
27
- DefinitionHelper.define_load_from_token_methods_for(self, :activation)
28
22
  DefinitionHelper.define_load_from_token_methods_for(self, :email_confirmation)
29
23
  end
30
24
 
@@ -97,6 +91,18 @@ module Goma
97
91
  goma_config.email_confirmation_success_email_method_name && !@skip_email_confirmation_success_email
98
92
  end
99
93
 
94
+ def resend_activation_needed_email(to: nil)
95
+ if to
96
+ @skip_email_confirmation = true
97
+ self.send(goma_config.email_setter, to)
98
+ return false unless self.save
99
+ @skip_email_confirmation = false
100
+ end
101
+ setup_activation
102
+ save(validate: false)
103
+ send_activation_needed_email
104
+ end
105
+
100
106
  DefinitionHelper.define_token_generator_method_for(self, :confirmation)
101
107
 
102
108
  protected
@@ -5,10 +5,11 @@ module Goma
5
5
 
6
6
  included do
7
7
  password_attr = goma_config.password_attribute_name
8
- attr_reader password_attr, "current_#{password_attr}"
8
+ attr_reader password_attr
9
9
 
10
10
  class_eval <<-METHOD, __FILE__, __LINE__ + 1
11
11
  def #{password_attr}=(new_#{password_attr})
12
+ return if new_#{password_attr}.blank?
12
13
  @#{password_attr} = new_#{password_attr}
13
14
  self.#{Goma.config.encrypted_password_attribute_name} = encrypt_password(new_#{password_attr})
14
15
  end
@@ -8,7 +8,7 @@ module Goma
8
8
  end
9
9
 
10
10
  module ClassMethods
11
- DefinitionHelper.define_load_from_token_with_error_method_for(self, :reset_password)
11
+ DefinitionHelper.define_load_from_token_with_error_method_for(self, :reset_password, :reset_password_within)
12
12
  DefinitionHelper.define_load_from_token_methods_for(self, :reset_password)
13
13
  end
14
14
 
@@ -41,16 +41,16 @@ module Goma
41
41
  def password_required?
42
42
  !@creating_with_omniauth && #{goma_config.oauth_association_name}.empty? && (
43
43
  !persisted? ||
44
- !#{goma_config.password_attribute_name}.nil? ||
45
- !#{goma_config.password_confirmation_attribute_name}.nil?)
44
+ #{goma_config.password_attribute_name}.present? ||
45
+ #{goma_config.password_confirmation_attribute_name}.present?)
46
46
  end
47
47
  RUBY
48
48
  else
49
49
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
50
50
  def password_required?
51
51
  !persisted? ||
52
- !#{goma_config.password_attribute_name}.nil? ||
53
- !#{goma_config.password_confirmation_attribute_name}.nil?
52
+ #{goma_config.password_attribute_name}.present? ||
53
+ #{goma_config.password_confirmation_attribute_name}.present?
54
54
  end
55
55
  RUBY
56
56
  end
data/lib/goma/railtie.rb CHANGED
@@ -6,6 +6,7 @@ module Goma
6
6
  class Railtie < ::Rails::Railtie
7
7
  config.app_middleware.use Warden::Manager do |config|
8
8
  if Goma.config && Goma.config.modules.include?(:rememberable)
9
+ require 'goma/strategies/rememberable'
9
10
  config.default_strategies :rememberable
10
11
  end
11
12
  end
data/lib/goma/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Goma
2
- VERSION = "0.0.1.gamma"
2
+ VERSION = "0.0.1.rc1"
3
3
  end
@@ -0,0 +1,185 @@
1
+ require 'test_helper'
2
+
3
+ class ConfirmableIntegrationTest < ActionDispatch::IntegrationTest
4
+ test 'should work activation proccess' do
5
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
6
+
7
+ visit new_user_url
8
+ fill_in :user_username, with: 'user'
9
+ fill_in :user_email, with: 'user@example.com'
10
+ fill_in :user_password, with: 'password'
11
+ fill_in :user_password_confirmation, with: 'password'
12
+
13
+ assert_difference ['User.count', 'ActionMailer::Base.deliveries.size'], 1 do
14
+ click_button 'Sign up'
15
+ end
16
+ user = User.order(created_at: :desc).first
17
+ refute user.activated?
18
+
19
+ email = ActionMailer::Base.deliveries.last
20
+ assert_match %r{/confirmations/sesame}, email.body.encoded
21
+
22
+ visit confirmation_url('sesame')
23
+ assert_equal 'Your account was successfully activated.', _flash[:notice]
24
+ assert_equal new_session_url, current_url
25
+ user.reload
26
+ assert user.activated?
27
+ end
28
+
29
+ test 'should be able to change email and resend activation token before activation with username and password which is entered in registration' do
30
+ Goma.token_generator.expects(:friendly_token).twice.returns('sesame', 'simsim')
31
+
32
+ visit new_user_url
33
+ fill_in :user_username, with: 'user'
34
+ fill_in :user_email, with: 'wrong@example.com'
35
+ fill_in :user_password, with: 'password'
36
+ fill_in :user_password_confirmation, with: 'password'
37
+ click_button 'Sign up'
38
+
39
+ user = User.order(created_at: :desc).first
40
+ refute user.activated?
41
+
42
+
43
+ visit new_user_url
44
+ assert_match /If you signed up with wrong email address/, page.body
45
+ fill_in :user_username, with: 'user'
46
+ fill_in :user_email, with: 'correct@example.com'
47
+ fill_in :user_password, with: 'password'
48
+ fill_in :user_password_confirmation, with: 'password'
49
+
50
+ assert_no_difference 'User.count' do
51
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
52
+ click_button 'Sign up'
53
+ end
54
+ end
55
+
56
+ email = ActionMailer::Base.deliveries.last
57
+ assert_match %r{/confirmations/simsim}, email.body.encoded
58
+ assert_equal 'correct@example.com', email.to.first
59
+
60
+ visit confirmation_url('simsim')
61
+ assert_equal 'Your account was successfully activated.', _flash[:notice]
62
+ assert_equal new_session_url, current_url
63
+ user.reload
64
+ assert user.activated?
65
+ end
66
+
67
+ test 'should not activate user with wrong token' do
68
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
69
+
70
+ visit new_user_url
71
+ fill_in :user_username, with: 'user'
72
+ fill_in :user_email, with: 'user@example.com'
73
+ fill_in :user_password, with: 'password'
74
+ fill_in :user_password_confirmation, with: 'password'
75
+ click_button 'Sign up'
76
+
77
+ user = User.order(created_at: :desc).first
78
+ refute user.activated?
79
+
80
+ visit confirmation_url('beans')
81
+ assert_equal confirmation_url('beans'), current_url
82
+ assert_match /Not found any account by this URL/, _flash[:alert]
83
+ user.reload
84
+ refute user.activated?
85
+ end
86
+
87
+ test 'should resend activation token by username' do
88
+ Goma.token_generator.expects(:friendly_token).twice.returns('sesame', 'simsim')
89
+
90
+ visit new_user_url
91
+ fill_in :user_username, with: 'user'
92
+ fill_in :user_email, with: 'user@example.com'
93
+ fill_in :user_password, with: 'password'
94
+ fill_in :user_password_confirmation, with: 'password'
95
+ click_button 'Sign up'
96
+
97
+ user = User.order(created_at: :desc).first
98
+ refute user.activated?
99
+
100
+ visit new_confirmation_url
101
+ fill_in :username_or_email, with: 'user'
102
+
103
+ assert_no_difference 'User.count' do
104
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
105
+ click_button 'Resend activation instructions'
106
+ end
107
+ end
108
+ email = ActionMailer::Base.deliveries.last
109
+ assert_match %r{/confirmations/simsim}, email.body.encoded
110
+
111
+ visit confirmation_url('simsim')
112
+ assert_equal 'Your account was successfully activated.', _flash[:notice]
113
+ assert_equal new_session_url, current_url
114
+ user.reload
115
+ assert user.activated?
116
+ end
117
+
118
+ test 'should resend activation token by email' do
119
+ Goma.token_generator.expects(:friendly_token).twice.returns('sesame', 'simsim')
120
+
121
+ visit new_user_url
122
+ fill_in :user_username, with: 'user'
123
+ fill_in :user_email, with: 'user@example.com'
124
+ fill_in :user_password, with: 'password'
125
+ fill_in :user_password_confirmation, with: 'password'
126
+ click_button 'Sign up'
127
+
128
+ user = User.order(created_at: :desc).first
129
+ refute user.activated?
130
+
131
+ visit new_confirmation_url
132
+ fill_in :username_or_email, with: 'user@example.com'
133
+
134
+ assert_no_difference 'User.count' do
135
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
136
+ click_button 'Resend activation instructions'
137
+ end
138
+ end
139
+ email = ActionMailer::Base.deliveries.last
140
+ assert_match %r{/confirmations/simsim}, email.body.encoded
141
+
142
+ visit confirmation_url('simsim')
143
+ assert_equal 'Your account was successfully activated.', _flash[:notice]
144
+ assert_equal new_session_url, current_url
145
+ user.reload
146
+ assert user.activated?
147
+ end
148
+
149
+ test 'should work email confirmation process' do
150
+ user = Fabricate(:user, email: 'old@example.com')
151
+
152
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
153
+
154
+ visit new_session_url
155
+ fill_in :username_or_email, with: 'old@example.com'
156
+ fill_in :password, with: 'password'
157
+ click_button 'Login'
158
+
159
+ visit edit_user_url(user)
160
+ fill_in :user_email, with: 'new@example.com'
161
+
162
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
163
+ click_button 'Update'
164
+ end
165
+ assert_match /but we need to verify your new email address/, _flash[:notice]
166
+
167
+ email = ActionMailer::Base.deliveries.last
168
+ assert_match %r{/confirmations/sesame/email}, email.body.encoded
169
+
170
+ user.reload
171
+ assert_equal 'old@example.com', user.email
172
+ assert_equal 'new@example.com', user.unconfirmed_email
173
+
174
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
175
+ visit email_confirmation_url('sesame')
176
+ end
177
+ email = ActionMailer::Base.deliveries.last
178
+ assert_match /You have successfully changed your account email/, email.body.encoded
179
+
180
+ user.reload
181
+ assert_equal root_url, current_url
182
+ assert_equal 'new@example.com', user.email
183
+ assert_nil user.unconfirmed_email
184
+ end
185
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class LockableIntegrationTest < ActionDispatch::IntegrationTest
4
+ def setup
5
+ @user = Fabricate(:user)
6
+ end
7
+
8
+
9
+ test 'should work unlock process' do
10
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
11
+ @user.lock_access!
12
+ assert @user.access_locked?
13
+
14
+ email = ActionMailer::Base.deliveries.last
15
+ assert_match %r{/unlocks/sesame}, email.body.encoded
16
+
17
+ visit unlock_url('sesame')
18
+
19
+ @user.reload
20
+ assert_equal new_session_url, current_url
21
+ refute @user.access_locked?
22
+ end
23
+
24
+ test 'should work resending unlock token process' do
25
+ @user.lock_access!
26
+ assert @user.access_locked?
27
+ old_token = @user.unlock_token
28
+
29
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
30
+
31
+ visit new_unlock_url
32
+ fill_in :username_or_email, with: @user.email
33
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
34
+ click_button 'Resend unlock instructions'
35
+ end
36
+ email = ActionMailer::Base.deliveries.last
37
+ assert_match %r{/unlocks/sesame}, email.body.encoded
38
+
39
+ @user.reload
40
+ refute_equal old_token, @user.unlock_token
41
+ assert_equal new_session_url, current_url
42
+
43
+ visit unlock_url('sesame')
44
+
45
+ @user.reload
46
+ assert_equal new_session_url, current_url
47
+ refute @user.access_locked?
48
+ end
49
+ end
@@ -2,25 +2,77 @@ require 'test_helper'
2
2
 
3
3
  class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
4
4
  def setup
5
- OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new({
6
- provider: 'twitter',
5
+ OmniAuth.config.mock_auth[:developer] = OmniAuth::AuthHash.new({
6
+ provider: 'developer',
7
7
  uid: '1234567'
8
8
  })
9
9
  end
10
10
 
11
11
  test 'should create user with omniauth' do
12
- get '/auth/twitter'
13
- assert_redirected_to '/auth/twitter/callback'
12
+ visit new_session_url
14
13
 
15
- assert_no_difference 'ActionMailer::Base.deliveries.count' do
16
- assert_difference ['User.count', 'Authentication.count'], 1 do
17
- follow_redirect!
18
- end
14
+ assert_difference ['User.count', 'Authentication.count'], 1 do
15
+ click_link 'Sign in with Developer'
16
+ end
17
+
18
+ assert_equal root_url, current_url, 'should be redirected to root_url'
19
+ assert_equal 'Successfully authenticated from developer account.', _flash[:notice]
20
+
21
+ assert _current_user
22
+ assert_equal 'developer', _current_user.authentications.first.provider
23
+ assert_equal '1234567', _current_user.authentications.first.uid
24
+ end
25
+
26
+ test 'should redirect back after creating user with omniauth ' do
27
+ visit secret_url
28
+ assert_equal root_url, current_url, 'should be redirect to root_url'
29
+
30
+ visit new_session_url
31
+ click_link 'Sign in with Developer'
32
+
33
+ assert_equal secret_url, current_url, 'should redirect back'
34
+ assert_equal 'Successfully authenticated from developer account.', _flash[:notice]
35
+ end
36
+
37
+ test 'should authenticate but not create user if already created' do
38
+ visit new_session_url
39
+ click_link 'Sign in with Developer'
40
+ _warden.logout(:user)
41
+
42
+
43
+ visit new_session_url
44
+
45
+ assert_no_difference ['User.count', 'Authentication.count'] do
46
+ click_link 'Sign in with Developer'
19
47
  end
20
- assert_redirected_to root_url
21
48
 
22
- assert current_user
23
- assert_equal 'twitter', current_user.authentications.first.provider
24
- assert_equal '1234567', current_user.authentications.first.uid
49
+ assert_equal root_url, current_url, 'should be redirected to root_url'
50
+ assert_equal 'Successfully authenticated from developer account.', _flash[:notice]
51
+
52
+ assert _current_user
53
+ assert_equal 'developer', _current_user.authentications.first.provider
54
+ assert_equal '1234567', _current_user.authentications.first.uid
55
+ end
56
+
57
+
58
+ test 'should handle errors' do
59
+ OmniAuth.config.mock_auth[:developer] = :access_denied
60
+
61
+ visit new_session_url
62
+
63
+ assert_no_difference ['User.count', 'Authentication.count'] do
64
+ click_link 'Sign in with Developer'
65
+ end
66
+
67
+ assert_match /Could not authenticate you from Developer because "Access denied"/, _flash[:alert]
68
+ assert_equal new_session_url, current_url
69
+ end
70
+
71
+ test 'should not accept unknown provider' do
72
+ assert_no_difference ['User.count', 'Authentication.count'] do
73
+ assert_raise ActionController::RoutingError do
74
+ visit 'auth/unknown'
75
+ end
76
+ end
25
77
  end
26
78
  end