karsthammer-validates_captcha 0.9.5a

Sign up to get free protection for your applications and to get access to all the features.
@@ -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