cops 0.2.0.6

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 (98) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +113 -0
  3. data/Rakefile +95 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/blue_light_special/confirmations_controller.rb +76 -0
  6. data/app/controllers/blue_light_special/impersonations_controller.rb +44 -0
  7. data/app/controllers/blue_light_special/passwords_controller.rb +93 -0
  8. data/app/controllers/blue_light_special/sessions_controller.rb +76 -0
  9. data/app/controllers/blue_light_special/users_controller.rb +85 -0
  10. data/app/models/blue_light_special_mailer.rb +28 -0
  11. data/app/models/deliver_change_password_job.rb +19 -0
  12. data/app/models/deliver_welcome_job.rb +17 -0
  13. data/app/models/generic_mailer.rb +31 -0
  14. data/app/models/impersonation.rb +26 -0
  15. data/app/models/mimi_mailer.rb +30 -0
  16. data/app/views/generic_mailer/change_password.html.erb +9 -0
  17. data/app/views/generic_mailer/confirmation.html.erb +5 -0
  18. data/app/views/generic_mailer/welcome.html.erb +1 -0
  19. data/app/views/impersonations/index.html.erb +5 -0
  20. data/app/views/passwords/edit.html.erb +23 -0
  21. data/app/views/passwords/new.html.erb +15 -0
  22. data/app/views/sessions/new.html.erb +48 -0
  23. data/app/views/users/_form.html.erb +21 -0
  24. data/app/views/users/edit.html.erb +6 -0
  25. data/app/views/users/new.html.erb +6 -0
  26. data/app/views/users/show.html.erb +8 -0
  27. data/generators/blue_light_special/USAGE +1 -0
  28. data/generators/blue_light_special/blue_light_special_generator.rb +78 -0
  29. data/generators/blue_light_special/lib/insert_commands.rb +33 -0
  30. data/generators/blue_light_special/lib/rake_commands.rb +22 -0
  31. data/generators/blue_light_special/templates/README +20 -0
  32. data/generators/blue_light_special/templates/application.html.erb +50 -0
  33. data/generators/blue_light_special/templates/blue_light_special.rb +25 -0
  34. data/generators/blue_light_special/templates/blue_light_special.yml +45 -0
  35. data/generators/blue_light_special/templates/factories.rb +23 -0
  36. data/generators/blue_light_special/templates/migrations/create_users.rb +24 -0
  37. data/generators/blue_light_special/templates/migrations/update_users.rb +44 -0
  38. data/generators/blue_light_special/templates/style.css +31 -0
  39. data/generators/blue_light_special/templates/user.rb +3 -0
  40. data/generators/blue_light_special/templates/xd_receiver.html +10 -0
  41. data/generators/blue_light_special/templates/xd_receiver_ssl.html +10 -0
  42. data/generators/blue_light_special_admin/USAGE +1 -0
  43. data/generators/blue_light_special_admin/blue_light_special_admin_generator.rb +30 -0
  44. data/generators/blue_light_special_admin/lib/insert_commands.rb +33 -0
  45. data/generators/blue_light_special_admin/templates/README +16 -0
  46. data/generators/blue_light_special_admin/templates/app/controllers/admin/admin_controller.rb +14 -0
  47. data/generators/blue_light_special_admin/templates/app/controllers/admin/users_controller.rb +52 -0
  48. data/generators/blue_light_special_admin/templates/app/views/admin/users/_form.html.erb +25 -0
  49. data/generators/blue_light_special_admin/templates/app/views/admin/users/edit.html.erb +6 -0
  50. data/generators/blue_light_special_admin/templates/app/views/admin/users/index.html.erb +7 -0
  51. data/generators/blue_light_special_admin/templates/app/views/admin/users/new.html.erb +6 -0
  52. data/generators/blue_light_special_admin/templates/app/views/admin/users/show.html.erb +10 -0
  53. data/generators/blue_light_special_admin/templates/test/integration/admin/users_test.rb +201 -0
  54. data/generators/blue_light_special_tests/USAGE +1 -0
  55. data/generators/blue_light_special_tests/blue_light_special_tests_generator.rb +21 -0
  56. data/generators/blue_light_special_tests/templates/README +58 -0
  57. data/generators/blue_light_special_tests/templates/test/integration/edit_profile_test.rb +35 -0
  58. data/generators/blue_light_special_tests/templates/test/integration/facebook_test.rb +61 -0
  59. data/generators/blue_light_special_tests/templates/test/integration/impersonation_test.rb +39 -0
  60. data/generators/blue_light_special_tests/templates/test/integration/password_reset_test.rb +128 -0
  61. data/generators/blue_light_special_tests/templates/test/integration/sign_in_test.rb +66 -0
  62. data/generators/blue_light_special_tests/templates/test/integration/sign_out_test.rb +28 -0
  63. data/generators/blue_light_special_tests/templates/test/integration/sign_up_test.rb +47 -0
  64. data/lib/blue_light_special/authentication.rb +138 -0
  65. data/lib/blue_light_special/configuration.rb +34 -0
  66. data/lib/blue_light_special/extensions/errors.rb +6 -0
  67. data/lib/blue_light_special/extensions/rescue.rb +5 -0
  68. data/lib/blue_light_special/routes.rb +62 -0
  69. data/lib/blue_light_special/user.rb +279 -0
  70. data/lib/blue_light_special.rb +7 -0
  71. data/rails/init.rb +4 -0
  72. data/shoulda_macros/blue_light_special.rb +244 -0
  73. data/test/controllers/passwords_controller_test.rb +184 -0
  74. data/test/controllers/sessions_controller_test.rb +129 -0
  75. data/test/controllers/users_controller_test.rb +57 -0
  76. data/test/models/blue_light_special_mailer_test.rb +52 -0
  77. data/test/models/impersonation_test.rb +25 -0
  78. data/test/models/user_test.rb +213 -0
  79. data/test/rails_root/app/controllers/accounts_controller.rb +10 -0
  80. data/test/rails_root/app/controllers/application_controller.rb +6 -0
  81. data/test/rails_root/app/helpers/application_helper.rb +5 -0
  82. data/test/rails_root/app/helpers/confirmations_helper.rb +2 -0
  83. data/test/rails_root/app/helpers/passwords_helper.rb +2 -0
  84. data/test/rails_root/config/boot.rb +110 -0
  85. data/test/rails_root/config/environment.rb +22 -0
  86. data/test/rails_root/config/environments/development.rb +19 -0
  87. data/test/rails_root/config/environments/production.rb +1 -0
  88. data/test/rails_root/config/environments/test.rb +37 -0
  89. data/test/rails_root/config/initializers/inflections.rb +10 -0
  90. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  91. data/test/rails_root/config/initializers/requires.rb +13 -0
  92. data/test/rails_root/config/initializers/time_formats.rb +4 -0
  93. data/test/rails_root/config/routes.rb +9 -0
  94. data/test/rails_root/public/dispatch.rb +10 -0
  95. data/test/rails_root/script/create_project.rb +52 -0
  96. data/test/rails_root/test/functional/accounts_controller_test.rb +23 -0
  97. data/test/test_helper.rb +21 -0
  98. metadata +212 -0
@@ -0,0 +1,279 @@
1
+ require 'digest/sha1'
2
+
3
+ module BlueLightSpecial
4
+ module User
5
+
6
+ Admin = 'admin'
7
+
8
+ # Hook for all BlueLightSpecial::User modules.
9
+ #
10
+ # If you need to override parts of BlueLightSpecial::User,
11
+ # extend and include à la carte.
12
+ #
13
+ # @example
14
+ # extend ClassMethods
15
+ # include InstanceMethods
16
+ # include AttrAccessor
17
+ # include Callbacks
18
+ #
19
+ # @see ClassMethods
20
+ # @see InstanceMethods
21
+ # @see AttrAccessible
22
+ # @see AttrAccessor
23
+ # @see Validations
24
+ # @see Callbacks
25
+ def self.included(model)
26
+ model.extend(ClassMethods)
27
+
28
+ model.send(:include, InstanceMethods)
29
+ model.send(:include, AttrAccessor)
30
+ model.send(:include, Validations)
31
+ model.send(:include, Callbacks)
32
+ end
33
+
34
+ module AttrAccessor
35
+ # Hook for attr_accessor virtual attributes.
36
+ #
37
+ # :password, :password_confirmation
38
+ def self.included(model)
39
+ model.class_eval do
40
+ attr_accessor :password, :password_confirmation
41
+ end
42
+ end
43
+ end
44
+
45
+ module Validations
46
+ # Hook for validations.
47
+ #
48
+ # :email must be present, unique, formatted
49
+ #
50
+ # If password is required,
51
+ # :password must be present, confirmed
52
+ def self.included(model)
53
+ model.class_eval do
54
+ validates_presence_of :email, :unless => :email_optional?
55
+ validates_uniqueness_of :email, :case_sensitive => false, :allow_blank => true
56
+ validates_format_of :email, :with => %r{.+@.+\..+}, :allow_blank => true
57
+
58
+ validates_presence_of :password, :unless => :password_optional?
59
+ validates_confirmation_of :password, :unless => :password_optional?
60
+
61
+ validates_presence_of :first_name, :last_name
62
+ end
63
+ end
64
+ end
65
+
66
+ module Callbacks
67
+ # Hook for callbacks.
68
+ #
69
+ # salt, token, password encryption are handled before_save.
70
+ def self.included(model)
71
+ model.class_eval do
72
+ before_save :initialize_salt,
73
+ :encrypt_password
74
+ before_create :generate_confirmation_token,
75
+ :generate_remember_token
76
+ after_create :send_welcome_email, :unless => :suppress_receive_welcome_email?
77
+ end
78
+ end
79
+ end
80
+
81
+ module InstanceMethods
82
+ # Am I authenticated with given password?
83
+ #
84
+ # @param [String] plain-text password
85
+ # @return [true, false]
86
+ # @example
87
+ # user.authenticated?('password')
88
+ def authenticated?(password)
89
+ encrypted_password == encrypt(password)
90
+ end
91
+
92
+ # Don't send welcome email if email already confirmed, or
93
+ # use is a facebook connect user
94
+ def suppress_receive_welcome_email?
95
+ return true if email_confirmed?
96
+ if self.facebook_uid.present?
97
+ self.email_confirmed = true
98
+ self.confirmation_token = nil
99
+ self.save
100
+ return true
101
+ end
102
+ return false
103
+ end
104
+
105
+ # Set the remember token.
106
+ #
107
+ # @deprecated Use {#reset_remember_token!} instead
108
+ def remember_me!
109
+ warn "[DEPRECATION] remember_me!: use reset_remember_token! instead"
110
+ reset_remember_token!
111
+ end
112
+
113
+ # Reset the remember token.
114
+ #
115
+ # @example
116
+ # user.reset_remember_token!
117
+ def reset_remember_token!
118
+ generate_remember_token
119
+ save(false)
120
+ end
121
+
122
+ # Confirm my email.
123
+ #
124
+ # @example
125
+ # user.confirm_email!
126
+ def confirm_email!
127
+ self.email_confirmed = true
128
+ self.confirmation_token = nil
129
+ save(false)
130
+ end
131
+
132
+ # Mark my account as forgotten password.
133
+ #
134
+ # @example
135
+ # user.forgot_password!
136
+ def forgot_password!
137
+ generate_password_reset_token
138
+ save(false)
139
+ end
140
+
141
+ # Update my password.
142
+ #
143
+ # @param [String, String] password and password confirmation
144
+ # @return [true, false] password was updated or not
145
+ # @example
146
+ # user.update_password('new-password', 'new-password')
147
+ def update_password(new_password, new_password_confirmation)
148
+ self.password = new_password
149
+ self.password_confirmation = new_password_confirmation
150
+ if valid?
151
+ self.password_reset_token = nil
152
+ end
153
+ save
154
+ end
155
+
156
+ def facebook_user?
157
+ !self.facebook_uid.blank?
158
+ end
159
+
160
+ ##
161
+ # Returns +true+ if the user is an admin.
162
+ #
163
+ def admin?
164
+ self.role == Admin
165
+ end
166
+
167
+ ##
168
+ # Returns the user's full name.
169
+ #
170
+ def name
171
+ "#{self.first_name} #{self.last_name}"
172
+ end
173
+
174
+ protected
175
+
176
+ def generate_hash(string)
177
+ Digest::SHA1.hexdigest(string)
178
+ end
179
+
180
+ def initialize_salt
181
+ if new_record?
182
+ self.salt = generate_hash("--#{Time.now.utc}--#{password}--#{rand}--")
183
+ end
184
+ end
185
+
186
+ def encrypt_password
187
+ return if password.blank?
188
+ self.encrypted_password = encrypt(password)
189
+ end
190
+
191
+ def encrypt(string)
192
+ generate_hash("--#{salt}--#{string}--")
193
+ end
194
+
195
+ def generate_confirmation_token
196
+ self.confirmation_token = encrypt("--#{Time.now.utc}--#{password}--#{rand}--")
197
+ end
198
+
199
+ def generate_password_reset_token
200
+ self.password_reset_token = encrypt("--#{Time.now.utc}--#{password}--#{rand}--")
201
+ end
202
+
203
+ def generate_remember_token
204
+ self.remember_token = encrypt("--#{Time.now.utc}--#{encrypted_password}--#{id}--#{rand}--")
205
+ end
206
+
207
+ # Always false. Override to allow other forms of authentication
208
+ # (username, facebook, etc).
209
+ # @return [Boolean] true if the email field be left blank for this user
210
+ def email_optional?
211
+ false
212
+ end
213
+
214
+ # True if the password has been set and the password is not being
215
+ # updated. Override to allow other forms of # authentication (username,
216
+ # facebook, etc).
217
+ # @return [Boolean] true if the password field can be left blank for this user
218
+ def password_optional?
219
+ facebook_user? || (encrypted_password.present? && password.blank?)
220
+ end
221
+
222
+ def password_required?
223
+ # warn "[DEPRECATION] password_required?: use !password_optional? instead"
224
+ !password_optional?
225
+ end
226
+
227
+ def send_welcome_email
228
+ if BlueLightSpecial.configuration.use_delayed_job
229
+ Delayed::Job.enqueue DeliverWelcomeJob.new(self.id)
230
+ else
231
+ if user = ::User.find_by_id(self.id)
232
+ BlueLightSpecialMailer.deliver_welcome(user)
233
+ end
234
+ end
235
+ end
236
+
237
+ def send_confirmation_email
238
+ BlueLightSpecialMailer.deliver_confirmation self
239
+ end
240
+
241
+ end
242
+
243
+ module ClassMethods
244
+ # Authenticate with email and password.
245
+ #
246
+ # @param [String, String] email and password
247
+ # @return [User, nil] authenticated user or nil
248
+ # @example
249
+ # User.authenticate("email@example.com", "password")
250
+ def authenticate(email, password)
251
+ return nil unless user = find_by_email(email)
252
+ return user if user.authenticated?(password)
253
+ end
254
+
255
+ def find_facebook_user(facebook_session, facebook_uid)
256
+ return nil unless BlueLightSpecial.configuration.use_facebook_connect && facebook_session && facebook_uid
257
+
258
+ begin
259
+ facebook_user = MiniFB::Session.new(BlueLightSpecial.configuration.facebook_api_key,
260
+ BlueLightSpecial.configuration.facebook_secret_key,
261
+ facebook_session, facebook_uid).user
262
+ rescue MiniFB::FaceBookError
263
+ facebook_user = nil
264
+ end
265
+ return nil unless facebook_user
266
+
267
+ user = ::User.find_by_facebook_uid(facebook_uid) || ::User.find_by_email(facebook_user['email']) || ::User.new
268
+ user.tap do |user|
269
+ user.facebook_uid = facebook_uid
270
+ user.email = facebook_user['email']
271
+ user.first_name = facebook_user['first_name']
272
+ user.last_name = facebook_user['last_name']
273
+ user.save
274
+ end
275
+ end
276
+ end
277
+
278
+ end
279
+ end
@@ -0,0 +1,7 @@
1
+ require 'blue_light_special/extensions/errors'
2
+ require 'blue_light_special/extensions/rescue'
3
+
4
+ require 'blue_light_special/configuration'
5
+ require 'blue_light_special/routes'
6
+ require 'blue_light_special/authentication'
7
+ require 'blue_light_special/user'
data/rails/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'delayed_job'
2
+ require 'mini_fb'
3
+ require 'mad_mimi_mailer'
4
+ require 'blue_light_special'
@@ -0,0 +1,244 @@
1
+ module BlueLightSpecial
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 BlueLightSpecial
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 BlueLightSpecial::Shoulda::Helpers
243
+ end
244
+ Test::Unit::TestCase.extend(BlueLightSpecial::Shoulda)