karsthammer-validates_captcha 0.9.5a

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.
@@ -0,0 +1,12 @@
1
+ require 'active_support/test_case'
2
+
3
+ module ValidatesCaptcha #:nodoc:
4
+ class TestCase < ActiveSupport::TestCase #:nodoc:
5
+ def assert_greater_than(expected, size, message = '')
6
+ _wrap_assertion do
7
+ full_message = build_message(message, "<?> expected to be greater than <?>.", size, expected)
8
+ assert_block(full_message) { size > expected }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ module ValidatesCaptcha #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 9
5
+ TINY = 5
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'validates_captcha'
2
+
3
+ config.after_initialize do
4
+ ::ActiveRecord::Base.send :include, ValidatesCaptcha::ModelValidation
5
+ ::ActionController::Base.send :include, ValidatesCaptcha::ControllerValidation
6
+ ::ActionView::Base.send :include, ValidatesCaptcha::FormHelper
7
+ ::ActionView::Helpers::FormBuilder.send :include, ValidatesCaptcha::FormBuilder
8
+ end
9
+
10
+ module ::ValidatesCaptcha
11
+ class MiddlewareWrapper
12
+ RECOGNIZED_RESPONSE_STATUS_CODES = [200, 422].freeze
13
+
14
+ def initialize(app)
15
+ @app = app
16
+ end
17
+
18
+ def call(env)
19
+ result = ValidatesCaptcha.provider.call(env)
20
+
21
+ return @app.call(env) unless RECOGNIZED_RESPONSE_STATUS_CODES.include?(result.first)
22
+
23
+ result
24
+ end
25
+ end
26
+ end
27
+
28
+ config.middleware.use ::ValidatesCaptcha::MiddlewareWrapper
29
+
@@ -0,0 +1,33 @@
1
+ require 'validates_captcha'
2
+
3
+ namespace :validates_captcha do
4
+ desc "Create 3 static captcha images in RAILS_ROOT/public/images/captchas/, specify a different number with COUNT=n"
5
+ task :create_static_images => [:create_static_image_dir, :clear_static_image_dir] do
6
+ count = ENV['COUNT'] ? ENV['COUNT'].to_i : 3
7
+
8
+ count.times do
9
+ path, code = ValidatesCaptcha::Provider::StaticImage.create_image
10
+ puts "Created #{path} with code #{code}"
11
+ end
12
+ end
13
+
14
+ task :create_static_image_dir => :environment do
15
+ image_dir = ValidatesCaptcha::Provider::StaticImage.filesystem_dir
16
+
17
+ unless File.exist?(image_dir)
18
+ FileUtils.mkdir_p image_dir
19
+ puts "Created directory #{image_dir}"
20
+ end
21
+ end
22
+
23
+ task :clear_static_image_dir => :environment do
24
+ image_dir = ValidatesCaptcha::Provider::StaticImage.filesystem_dir
25
+ image_files = Dir[File.join(image_dir, '*')]
26
+
27
+ if image_files.any?
28
+ FileUtils.rm image_files
29
+ puts "Cleared directory #{image_dir}"
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,222 @@
1
+ require 'test_helper'
2
+ require 'action_controller'
3
+
4
+ ActionController::Routing::Routes.draw do |map|
5
+ map.connect ':controller/:action/:id'
6
+ end
7
+
8
+ class WidgetsController < ActionController::Base
9
+ include ValidatesCaptcha::ControllerValidation
10
+
11
+ validates_captcha :except => [:update, :save, :persist, :bingo]
12
+ validates_captcha_of :widgets, :only => :update
13
+ validates_captcha_of Widget, :only => [:save, :persist]
14
+
15
+ def create
16
+ begin
17
+ Widget.new.save!
18
+ rescue ActiveRecord::RecordInvalid
19
+ @invalid = true
20
+ end
21
+
22
+ render :nothing => true
23
+ end
24
+
25
+ def update
26
+ begin
27
+ Widget.new.save!
28
+ rescue ActiveRecord::RecordInvalid
29
+ @invalid = true
30
+ end
31
+
32
+ render :nothing => true
33
+ end
34
+
35
+ def save
36
+ begin
37
+ Widget.create! params['widget']
38
+ rescue ActiveRecord::RecordInvalid
39
+ @invalid = true
40
+ end
41
+
42
+ render :nothing => true
43
+ end
44
+
45
+ def store
46
+ begin
47
+ Widget.create! params['widget']
48
+ rescue ActiveRecord::RecordInvalid
49
+ @invalid = true
50
+ end
51
+
52
+ render :nothing => true
53
+ end
54
+
55
+ def persist
56
+ begin
57
+ Widget.create! params['widget']
58
+ rescue ActiveRecord::RecordInvalid
59
+ @invalid = true
60
+ end
61
+
62
+ render :nothing => true
63
+ end
64
+
65
+ def bingo
66
+ begin
67
+ Widget.new.save!
68
+ rescue ActiveRecord::RecordInvalid
69
+ @invalid = true
70
+ end
71
+
72
+ render :nothing => true
73
+ end
74
+ end
75
+
76
+ class ControllerValidationTest < ActionController::TestCase
77
+ tests WidgetsController
78
+
79
+ def with_dynamic_image_provider(&block)
80
+ old_provider = ValidatesCaptcha.provider
81
+ provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::DynamicImage.new
82
+ yield provider
83
+ ValidatesCaptcha.provider = old_provider
84
+ end
85
+
86
+ def with_static_image_provider(&block)
87
+ old_provider = ValidatesCaptcha.provider
88
+ provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::StaticImage.new
89
+ provider.instance_variable_set "@images", ["/path/to/#{provider.send(:encrypt, 'hello')}#{provider.send(:image_file_extension)}"]
90
+ yield provider
91
+ ValidatesCaptcha.provider = old_provider
92
+ end
93
+
94
+ def with_question_provider(&block)
95
+ old_provider = ValidatesCaptcha.provider
96
+ provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Question.new
97
+ yield provider
98
+ ValidatesCaptcha.provider = old_provider
99
+ end
100
+
101
+ test "defines a class level #validates_captcha method" do
102
+ assert_respond_to WidgetsController, :validates_captcha
103
+ end
104
+
105
+ test "defines a class level #validates_captcha_of method" do
106
+ assert_respond_to WidgetsController, :validates_captcha_of
107
+ end
108
+
109
+ test "calling #create method of controller should assign @invalid" do
110
+ post :create
111
+ assert_not_nil assigns(:invalid)
112
+ end
113
+
114
+ test "calling #update method of controller should assign @invalid" do
115
+ post :update
116
+ assert_not_nil assigns(:invalid)
117
+ end
118
+
119
+ test "calling #save method of controller should not assign @invalid" do
120
+ with_dynamic_image_provider do |provider|
121
+ challenge = provider.generate_challenge
122
+ solution = provider.send(:decrypt, challenge)
123
+
124
+ post :save, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
125
+ assert_nil assigns(:invalid)
126
+ end
127
+
128
+ with_static_image_provider do |provider|
129
+ challenge = provider.generate_challenge
130
+ solution = 'hello'
131
+
132
+ post :save, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
133
+ assert_nil assigns(:invalid)
134
+ end
135
+
136
+ with_question_provider do |provider|
137
+ challenge = provider.generate_challenge
138
+ solution = provider.send(:solve, challenge)
139
+
140
+ post :save, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
141
+ assert_nil assigns(:invalid)
142
+ end
143
+ end
144
+
145
+ test "calling #store method of controller should assign @invalid" do
146
+ with_dynamic_image_provider do |provider|
147
+ challenge = provider.generate_challenge
148
+ solution = provider.send(:decrypt, challenge).reverse
149
+
150
+ post :store, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
151
+ assert_not_nil assigns(:invalid)
152
+ end
153
+
154
+ with_static_image_provider do |provider|
155
+ challenge = provider.generate_challenge
156
+ solution = '---'
157
+
158
+ post :store, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
159
+ assert_not_nil assigns(:invalid)
160
+ end
161
+
162
+ with_question_provider do |provider|
163
+ challenge = provider.generate_challenge
164
+ solution = '---'
165
+
166
+ post :store, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
167
+ assert_not_nil assigns(:invalid)
168
+ end
169
+ end
170
+
171
+ test "calling #persist method of controller should assign @invalid" do
172
+ with_dynamic_image_provider do |provider|
173
+ challenge = provider.generate_challenge
174
+ solution = provider.send(:decrypt, challenge).reverse
175
+
176
+ post :persist, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
177
+ assert_not_nil assigns(:invalid)
178
+ end
179
+
180
+ with_static_image_provider do |provider|
181
+ challenge = provider.generate_challenge
182
+ solution = '---'
183
+
184
+ post :persist, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
185
+ assert_not_nil assigns(:invalid)
186
+ end
187
+
188
+ with_question_provider do |provider|
189
+ challenge = provider.generate_challenge
190
+ solution = '---'
191
+
192
+ post :persist, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
193
+ assert_not_nil assigns(:invalid)
194
+ end
195
+ end
196
+
197
+ test "calling #bingo method of controller should not assign @invalid" do
198
+ with_dynamic_image_provider do |provider|
199
+ challenge = provider.generate_challenge
200
+ solution = provider.send(:decrypt, challenge).reverse
201
+
202
+ post :bingo, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
203
+ assert_nil assigns(:invalid)
204
+ end
205
+
206
+ with_static_image_provider do |provider|
207
+ challenge = provider.generate_challenge
208
+ solution = '---'
209
+
210
+ post :bingo, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
211
+ assert_nil assigns(:invalid)
212
+ end
213
+
214
+ with_question_provider do |provider|
215
+ challenge = provider.generate_challenge
216
+ solution = '---'
217
+
218
+ post :bingo, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
219
+ assert_nil assigns(:invalid)
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ IG = ValidatesCaptcha::ImageGenerator::Simple
4
+
5
+ class ImageGeneratorTest < ValidatesCaptcha::TestCase
6
+ test "defines an instance level #generate method" do
7
+ assert_respond_to IG.new, :generate
8
+ end
9
+
10
+ test "instance level #generate method accepts an argument" do
11
+ assert_nothing_raised { IG.new.generate('abc') }
12
+ end
13
+
14
+ test "instance level #generate method returns a string" do
15
+ assert_kind_of String, IG.new.generate('abc')
16
+ end
17
+
18
+ test "defines an instance level #file_extension method" do
19
+ assert_respond_to IG.new, :file_extension
20
+ end
21
+
22
+ test "instance level #file_extension method returns a string" do
23
+ assert_kind_of String, IG.new.file_extension
24
+ end
25
+
26
+ test "defines an instance level #mime_type method" do
27
+ assert_respond_to IG.new, :mime_type
28
+ end
29
+
30
+ test "instance level #mime_type method returns a string" do
31
+ assert_kind_of String, IG.new.mime_type
32
+ end
33
+ end
34
+
@@ -0,0 +1,258 @@
1
+ require 'test_helper'
2
+
3
+ class ModelValidationTest < ValidatesCaptcha::TestCase
4
+ def with_dynamic_image_provider(&block)
5
+ old_provider = ValidatesCaptcha.provider
6
+ provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::DynamicImage.new
7
+ yield provider
8
+ ValidatesCaptcha.provider = old_provider
9
+ end
10
+
11
+ def with_static_image_provider(&block)
12
+ old_provider = ValidatesCaptcha.provider
13
+ provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::StaticImage.new
14
+ provider.instance_variable_set "@images", ["/path/to/#{provider.send(:encrypt, 'hello')}#{provider.send(:image_file_extension)}"]
15
+ yield provider
16
+ ValidatesCaptcha.provider = old_provider
17
+ end
18
+
19
+ def with_question_provider(&block)
20
+ old_provider = ValidatesCaptcha.provider
21
+ provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Question.new
22
+ yield provider
23
+ ValidatesCaptcha.provider = old_provider
24
+ end
25
+
26
+ test "defines an accessible attribute named +captcha_solution+" do
27
+ assert Widget.accessible_attributes.include?('captcha_solution')
28
+ end
29
+
30
+ test "defines an instance level #captcha_solution method" do
31
+ assert_respond_to Widget.new, :captcha_solution
32
+ end
33
+
34
+ test "defines a instance level #captcha_solution= method" do
35
+ assert_respond_to Widget.new, :captcha_solution=
36
+ end
37
+
38
+ test "assigned value to #captcha_solution= should equal return value of #captcha_solution" do
39
+ widget = Widget.new
40
+ widget.captcha_solution = 'abc123'
41
+
42
+ assert_equal 'abc123', widget.captcha_solution
43
+ end
44
+
45
+ test "defines an accessible attribute named +captcha_challenge+" do
46
+ assert Widget.accessible_attributes.include?('captcha_challenge')
47
+ end
48
+
49
+ test "defines an instance level #captcha_challenge method" do
50
+ assert_respond_to Widget.new, :captcha_challenge
51
+ end
52
+
53
+ test "defines an instance level #captcha_challenge= method" do
54
+ assert_respond_to Widget.new, :captcha_challenge=
55
+ end
56
+
57
+ test "value assigned to #captcha_challenge= should equal return value of #captcha_challenge" do
58
+ widget = Widget.new
59
+ widget.captcha_challenge = 'asdfghjk3456789'
60
+
61
+ assert_equal 'asdfghjk3456789', widget.captcha_challenge
62
+ end
63
+
64
+ test "defines #validate_captcha method callback of kind +validate+" do
65
+ assert Widget.validate_callback_chain.any? { |callback| callback.method == :validate_captcha && callback.kind == :validate }
66
+ end
67
+
68
+ test "defines a class level with_captcha_validation method" do
69
+ assert_respond_to Widget, :with_captcha_validation
70
+ end
71
+
72
+ test "not within a #with_captcha_validation block, calling valid? should return true if no captcha_solution is set" do
73
+ widget = Widget.new
74
+ widget.captcha_solution = nil
75
+
76
+ assert widget.valid?
77
+ end
78
+
79
+ test "not within a #with_captcha_validation block, calling valid? should return true if an empty captcha_solution is set" do
80
+ widget = Widget.new
81
+ widget.captcha_solution = ' '
82
+
83
+ assert widget.valid?
84
+ end
85
+
86
+ test "not within a #with_captcha_validation block, calling valid? should return true if an invalid captcha_solution is set" do
87
+ with_dynamic_image_provider do |provider|
88
+ widget = Widget.new
89
+ widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge).reverse
90
+
91
+ assert widget.valid?
92
+ end
93
+
94
+ with_static_image_provider do |provider|
95
+ widget = Widget.new
96
+ widget.captcha_solution = '---'
97
+
98
+ assert widget.valid?
99
+ end
100
+
101
+ with_question_provider do |provider|
102
+ widget = Widget.new
103
+ widget.captcha_solution = '---'
104
+
105
+ assert widget.valid?
106
+ end
107
+ end
108
+
109
+ test "not within a #with_captcha_validation block, calling valid? should return true if a valid captcha_solution is set" do
110
+ with_dynamic_image_provider do |provider|
111
+ widget = Widget.new
112
+ widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge)
113
+
114
+ assert widget.valid?
115
+ end
116
+
117
+ with_static_image_provider do |provider|
118
+ widget = Widget.new
119
+ widget.captcha_solution = 'hello'
120
+
121
+ assert widget.valid?
122
+ end
123
+
124
+ with_question_provider do |provider|
125
+ widget = Widget.new
126
+ widget.captcha_solution = provider.send(:solve, widget.captcha_challenge)
127
+
128
+ assert widget.valid?
129
+ end
130
+ end
131
+
132
+ test "within a #with_captcha_validation block, calling valid? should return false if no captcha_solution is set" do
133
+ Widget.with_captcha_validation do
134
+ widget = Widget.new
135
+ widget.captcha_solution = nil
136
+
137
+ assert !widget.valid?
138
+ assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
139
+ assert Array.wrap(widget.errors[:captcha_solution]).first.include?('blank')
140
+ end
141
+ end
142
+
143
+ test "within a #with_captcha_validation block, calling valid? should return false if an empty captcha_solution is set" do
144
+ Widget.with_captcha_validation do
145
+ widget = Widget.new
146
+ widget.captcha_solution = ' '
147
+
148
+ assert !widget.valid?
149
+ assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
150
+ assert Array.wrap(widget.errors[:captcha_solution]).first.include?('blank')
151
+ end
152
+ end
153
+
154
+ test "within a #with_captcha_validation block, calling valid? should return false if an invalid captcha_solution is set" do
155
+ with_dynamic_image_provider do |provider|
156
+ Widget.with_captcha_validation do
157
+ widget = Widget.new
158
+ widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge).reverse
159
+
160
+ assert !widget.valid?
161
+ assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
162
+ assert Array.wrap(widget.errors[:captcha_solution]).first.include?('invalid')
163
+ end
164
+ end
165
+
166
+ with_static_image_provider do |provider|
167
+ Widget.with_captcha_validation do
168
+ widget = Widget.new
169
+ widget.captcha_solution = '---'
170
+
171
+ assert !widget.valid?
172
+ assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
173
+ assert Array.wrap(widget.errors[:captcha_solution]).first.include?('invalid')
174
+ end
175
+ end
176
+
177
+ with_question_provider do |provider|
178
+ Widget.with_captcha_validation do
179
+ widget = Widget.new
180
+ widget.captcha_solution = '---'
181
+
182
+ assert !widget.valid?
183
+ assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
184
+ assert Array.wrap(widget.errors[:captcha_solution]).first.include?('invalid')
185
+ end
186
+ end
187
+ end
188
+
189
+ test "within a #with_captcha_validation block, calling valid? should return true if a valid captcha_solution is set" do
190
+ with_dynamic_image_provider do |provider|
191
+ Widget.with_captcha_validation do
192
+ widget = Widget.new
193
+ widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge)
194
+
195
+ assert widget.valid?
196
+ end
197
+ end
198
+
199
+ with_static_image_provider do |provider|
200
+ Widget.with_captcha_validation do
201
+ widget = Widget.new
202
+ widget.captcha_solution = 'hello'
203
+
204
+ assert widget.valid?
205
+ end
206
+ end
207
+
208
+ with_question_provider do |provider|
209
+ Widget.with_captcha_validation do
210
+ widget = Widget.new
211
+ widget.captcha_solution = provider.send(:solve, widget.captcha_challenge)
212
+
213
+ assert widget.valid?
214
+ end
215
+ end
216
+ end
217
+
218
+ test "with #with_captcha_validation block, calling valid? before and after the block should return true if valid? returned false within block" do
219
+ with_dynamic_image_provider do |provider|
220
+ widget = Widget.new
221
+ widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge).reverse
222
+
223
+ assert widget.valid?
224
+
225
+ Widget.with_captcha_validation do
226
+ assert !widget.valid?
227
+ end
228
+
229
+ assert widget.valid?
230
+ end
231
+
232
+ with_static_image_provider do |provider|
233
+ widget = Widget.new
234
+ widget.captcha_solution = '---'
235
+
236
+ assert widget.valid?
237
+
238
+ Widget.with_captcha_validation do
239
+ assert !widget.valid?
240
+ end
241
+
242
+ assert widget.valid?
243
+ end
244
+
245
+ with_question_provider do |provider|
246
+ widget = Widget.new
247
+ widget.captcha_solution = '---'
248
+
249
+ assert widget.valid?
250
+
251
+ Widget.with_captcha_validation do
252
+ assert !widget.valid?
253
+ end
254
+
255
+ assert widget.valid?
256
+ end
257
+ end
258
+ end