validates_captcha 0.9.2 → 0.9.3
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.
- data/CHANGELOG.rdoc +6 -1
- data/README.rdoc +85 -49
- data/lib/validates_captcha.rb +18 -113
- data/lib/validates_captcha/form_builder.rb +4 -4
- data/lib/validates_captcha/form_helper.rb +13 -25
- data/lib/validates_captcha/image_generator/simple.rb +7 -6
- data/lib/validates_captcha/model_validation.rb +9 -9
- data/lib/validates_captcha/provider/image.rb +244 -0
- data/lib/validates_captcha/provider/question.rb +110 -0
- data/lib/validates_captcha/reversible_encrypter/simple.rb +3 -2
- data/lib/validates_captcha/string_generator/simple.rb +3 -2
- data/lib/validates_captcha/version.rb +1 -1
- data/rails/init.rb +1 -1
- data/test/cases/controller_validation_test.rb +79 -22
- data/test/cases/{image_generator_test.rb → image_generator/simple_test.rb} +11 -10
- data/test/cases/model_validation_test.rb +131 -58
- data/test/cases/provider/image_test.rb +103 -0
- data/test/cases/provider/question_test.rb +41 -0
- data/test/cases/{reversible_encrypter_test.rb → reversible_encrypter/simple_test.rb} +3 -2
- data/test/cases/{string_generator_test.rb → string_generator/simple_test.rb} +1 -0
- data/test/cases/validates_captcha_test.rb +9 -116
- metadata +17 -14
- data/lib/validates_captcha/middleware/simple.rb +0 -108
- data/test/cases/middleware_test.rb +0 -71
@@ -10,7 +10,7 @@ module ValidatesCaptcha
|
|
10
10
|
#
|
11
11
|
# You can implement your own string generator by creating a
|
12
12
|
# class that conforms to the method definitions of the example below and
|
13
|
-
# assign an instance of it to ValidatesCaptcha#string_generator=.
|
13
|
+
# assign an instance of it to ValidatesCaptcha::Provider::Image#string_generator=.
|
14
14
|
#
|
15
15
|
# Example for a custom string generator:
|
16
16
|
#
|
@@ -22,7 +22,8 @@ module ValidatesCaptcha
|
|
22
22
|
# end
|
23
23
|
# end
|
24
24
|
#
|
25
|
-
# ValidatesCaptcha.string_generator = DictionaryGenerator.new
|
25
|
+
# ValidatesCaptcha::Provider::Image.string_generator = DictionaryGenerator.new
|
26
|
+
# ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
|
26
27
|
#
|
27
28
|
class Simple
|
28
29
|
@@alphabet = 'abdefghjkmnqrtABDEFGHJKLMNQRT234678923467892346789'
|
data/rails/init.rb
CHANGED
@@ -33,11 +33,8 @@ class WidgetsController < ActionController::Base
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def save
|
36
|
-
encrypted = ValidatesCaptcha.encrypt_captcha_code('take this')
|
37
|
-
decrypted = ValidatesCaptcha.decrypt_captcha_code(encrypted)
|
38
|
-
|
39
36
|
begin
|
40
|
-
Widget.create!
|
37
|
+
Widget.create! params['widget']
|
41
38
|
rescue ActiveRecord::RecordInvalid
|
42
39
|
@invalid = true
|
43
40
|
end
|
@@ -46,11 +43,8 @@ class WidgetsController < ActionController::Base
|
|
46
43
|
end
|
47
44
|
|
48
45
|
def store
|
49
|
-
encrypted = ValidatesCaptcha.encrypt_captcha_code('take this')
|
50
|
-
decrypted = ValidatesCaptcha.decrypt_captcha_code(encrypted) + 'ha!'
|
51
|
-
|
52
46
|
begin
|
53
|
-
Widget.create!
|
47
|
+
Widget.create! params['widget']
|
54
48
|
rescue ActiveRecord::RecordInvalid
|
55
49
|
@invalid = true
|
56
50
|
end
|
@@ -59,11 +53,8 @@ class WidgetsController < ActionController::Base
|
|
59
53
|
end
|
60
54
|
|
61
55
|
def persist
|
62
|
-
encrypted = ValidatesCaptcha.encrypt_captcha_code('take this')
|
63
|
-
decrypted = ValidatesCaptcha.decrypt_captcha_code(encrypted) + 'ha!'
|
64
|
-
|
65
56
|
begin
|
66
|
-
Widget.create!
|
57
|
+
Widget.create! params['widget']
|
67
58
|
rescue ActiveRecord::RecordInvalid
|
68
59
|
@invalid = true
|
69
60
|
end
|
@@ -85,6 +76,20 @@ end
|
|
85
76
|
class ControllerValidationTest < ActionController::TestCase
|
86
77
|
tests WidgetsController
|
87
78
|
|
79
|
+
def with_image_provider(&block)
|
80
|
+
old_provider = ValidatesCaptcha.provider
|
81
|
+
provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
|
82
|
+
yield provider
|
83
|
+
ValidatesCaptcha.provider = old_provider
|
84
|
+
end
|
85
|
+
|
86
|
+
def with_question_provider(&block)
|
87
|
+
old_provider = ValidatesCaptcha.provider
|
88
|
+
provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Question.new
|
89
|
+
yield provider
|
90
|
+
ValidatesCaptcha.provider = old_provider
|
91
|
+
end
|
92
|
+
|
88
93
|
test "defines a class level #validates_captcha method" do
|
89
94
|
assert_respond_to WidgetsController, :validates_captcha
|
90
95
|
end
|
@@ -104,22 +109,74 @@ class ControllerValidationTest < ActionController::TestCase
|
|
104
109
|
end
|
105
110
|
|
106
111
|
test "calling #save method of controller should not assign @invalid" do
|
107
|
-
|
108
|
-
|
112
|
+
with_image_provider do |provider|
|
113
|
+
challenge = provider.generate_challenge
|
114
|
+
solution = provider.send(:decrypt, challenge)
|
115
|
+
|
116
|
+
post :save, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
|
117
|
+
assert_nil assigns(:invalid)
|
118
|
+
end
|
119
|
+
|
120
|
+
with_question_provider do |provider|
|
121
|
+
challenge = provider.generate_challenge
|
122
|
+
solution = provider.send(:solve, challenge)
|
123
|
+
|
124
|
+
post :save, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
|
125
|
+
assert_nil assigns(:invalid)
|
126
|
+
end
|
109
127
|
end
|
110
128
|
|
111
|
-
test "calling #store method of controller should
|
112
|
-
|
113
|
-
|
129
|
+
test "calling #store method of controller should assign @invalid" do
|
130
|
+
with_image_provider do |provider|
|
131
|
+
challenge = provider.generate_challenge
|
132
|
+
solution = provider.send(:decrypt, challenge).reverse
|
133
|
+
|
134
|
+
post :store, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
|
135
|
+
assert_not_nil assigns(:invalid)
|
136
|
+
end
|
137
|
+
|
138
|
+
with_question_provider do |provider|
|
139
|
+
challenge = provider.generate_challenge
|
140
|
+
solution = '---'
|
141
|
+
|
142
|
+
post :store, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
|
143
|
+
assert_not_nil assigns(:invalid)
|
144
|
+
end
|
114
145
|
end
|
115
146
|
|
116
|
-
test "calling #persist method of controller should
|
117
|
-
|
118
|
-
|
147
|
+
test "calling #persist method of controller should assign @invalid" do
|
148
|
+
with_image_provider do |provider|
|
149
|
+
challenge = provider.generate_challenge
|
150
|
+
solution = provider.send(:decrypt, challenge).reverse
|
151
|
+
|
152
|
+
post :persist, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
|
153
|
+
assert_not_nil assigns(:invalid)
|
154
|
+
end
|
155
|
+
|
156
|
+
with_question_provider do |provider|
|
157
|
+
challenge = provider.generate_challenge
|
158
|
+
solution = '---'
|
159
|
+
|
160
|
+
post :persist, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
|
161
|
+
assert_not_nil assigns(:invalid)
|
162
|
+
end
|
119
163
|
end
|
120
164
|
|
121
165
|
test "calling #bingo method of controller should not assign @invalid" do
|
122
|
-
|
123
|
-
|
166
|
+
with_image_provider do |provider|
|
167
|
+
challenge = provider.generate_challenge
|
168
|
+
solution = provider.send(:decrypt, challenge).reverse
|
169
|
+
|
170
|
+
post :bingo, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
|
171
|
+
assert_nil assigns(:invalid)
|
172
|
+
end
|
173
|
+
|
174
|
+
with_question_provider do |provider|
|
175
|
+
challenge = provider.generate_challenge
|
176
|
+
solution = '---'
|
177
|
+
|
178
|
+
post :bingo, { 'widget' => { 'captcha_challenge' => challenge, 'captcha_solution' => solution } }
|
179
|
+
assert_nil assigns(:invalid)
|
180
|
+
end
|
124
181
|
end
|
125
182
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
|
2
|
+
|
3
3
|
IG = ValidatesCaptcha::ImageGenerator::Simple
|
4
|
-
|
4
|
+
|
5
5
|
class ImageGeneratorTest < ValidatesCaptcha::TestCase
|
6
6
|
test "defines an instance level #generate method" do
|
7
7
|
assert_respond_to IG.new, :generate
|
@@ -15,19 +15,20 @@ class ImageGeneratorTest < ValidatesCaptcha::TestCase
|
|
15
15
|
assert_kind_of String, IG.new.generate('abc')
|
16
16
|
end
|
17
17
|
|
18
|
-
test "defines an instance level #
|
19
|
-
assert_respond_to IG.new, :
|
18
|
+
test "defines an instance level #file_extension method" do
|
19
|
+
assert_respond_to IG.new, :file_extension
|
20
20
|
end
|
21
21
|
|
22
|
-
test "instance level #
|
23
|
-
assert_kind_of String, IG.new.
|
22
|
+
test "instance level #file_extension method returns a string" do
|
23
|
+
assert_kind_of String, IG.new.file_extension
|
24
24
|
end
|
25
25
|
|
26
|
-
test "defines an instance level #
|
27
|
-
assert_respond_to IG.new, :
|
26
|
+
test "defines an instance level #mime_type method" do
|
27
|
+
assert_respond_to IG.new, :mime_type
|
28
28
|
end
|
29
29
|
|
30
|
-
test "instance level #
|
31
|
-
assert_kind_of String, IG.new.
|
30
|
+
test "instance level #mime_type method returns a string" do
|
31
|
+
assert_kind_of String, IG.new.mime_type
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
@@ -1,42 +1,56 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class ModelValidationTest < ValidatesCaptcha::TestCase
|
4
|
-
|
5
|
-
|
4
|
+
def with_image_provider(&block)
|
5
|
+
old_provider = ValidatesCaptcha.provider
|
6
|
+
provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
|
7
|
+
yield provider
|
8
|
+
ValidatesCaptcha.provider = old_provider
|
6
9
|
end
|
7
10
|
|
8
|
-
|
9
|
-
|
11
|
+
def with_question_provider(&block)
|
12
|
+
old_provider = ValidatesCaptcha.provider
|
13
|
+
provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Question.new
|
14
|
+
yield provider
|
15
|
+
ValidatesCaptcha.provider = old_provider
|
10
16
|
end
|
11
17
|
|
12
|
-
test "defines
|
13
|
-
|
18
|
+
test "defines an accessible attribute named +captcha_solution+" do
|
19
|
+
assert Widget.accessible_attributes.include?('captcha_solution')
|
14
20
|
end
|
15
21
|
|
16
|
-
test "
|
22
|
+
test "defines an instance level #captcha_solution method" do
|
23
|
+
assert_respond_to Widget.new, :captcha_solution
|
24
|
+
end
|
25
|
+
|
26
|
+
test "defines a instance level #captcha_solution= method" do
|
27
|
+
assert_respond_to Widget.new, :captcha_solution=
|
28
|
+
end
|
29
|
+
|
30
|
+
test "assigned value to #captcha_solution= should equal return value of #captcha_solution" do
|
17
31
|
widget = Widget.new
|
18
|
-
widget.
|
32
|
+
widget.captcha_solution = 'abc123'
|
19
33
|
|
20
|
-
assert_equal 'abc123', widget.
|
34
|
+
assert_equal 'abc123', widget.captcha_solution
|
21
35
|
end
|
22
36
|
|
23
|
-
test "defines an accessible attribute named +
|
24
|
-
assert Widget.accessible_attributes.include?('
|
37
|
+
test "defines an accessible attribute named +captcha_challenge+" do
|
38
|
+
assert Widget.accessible_attributes.include?('captcha_challenge')
|
25
39
|
end
|
26
40
|
|
27
|
-
test "defines an instance level #
|
28
|
-
assert_respond_to Widget.new, :
|
41
|
+
test "defines an instance level #captcha_challenge method" do
|
42
|
+
assert_respond_to Widget.new, :captcha_challenge
|
29
43
|
end
|
30
44
|
|
31
|
-
test "defines an instance level #
|
32
|
-
assert_respond_to Widget.new, :
|
45
|
+
test "defines an instance level #captcha_challenge= method" do
|
46
|
+
assert_respond_to Widget.new, :captcha_challenge=
|
33
47
|
end
|
34
48
|
|
35
|
-
test "value assigned to #
|
49
|
+
test "value assigned to #captcha_challenge= should equal return value of #captcha_challenge" do
|
36
50
|
widget = Widget.new
|
37
|
-
widget.
|
51
|
+
widget.captcha_challenge = 'asdfghjk3456789'
|
38
52
|
|
39
|
-
assert_equal 'asdfghjk3456789', widget.
|
53
|
+
assert_equal 'asdfghjk3456789', widget.captcha_challenge
|
40
54
|
end
|
41
55
|
|
42
56
|
test "defines #validate_captcha method callback of kind +validate+" do
|
@@ -47,84 +61,143 @@ class ModelValidationTest < ValidatesCaptcha::TestCase
|
|
47
61
|
assert_respond_to Widget, :with_captcha_validation
|
48
62
|
end
|
49
63
|
|
50
|
-
test "not within a #with_captcha_validation block, calling valid? should return true if no
|
64
|
+
test "not within a #with_captcha_validation block, calling valid? should return true if no captcha_solution is set" do
|
51
65
|
widget = Widget.new
|
66
|
+
widget.captcha_solution = nil
|
52
67
|
|
53
68
|
assert widget.valid?
|
54
69
|
end
|
55
70
|
|
56
|
-
test "not within a #with_captcha_validation block, calling valid? should return true if an empty
|
71
|
+
test "not within a #with_captcha_validation block, calling valid? should return true if an empty captcha_solution is set" do
|
57
72
|
widget = Widget.new
|
58
|
-
widget.
|
73
|
+
widget.captcha_solution = ' '
|
59
74
|
|
60
75
|
assert widget.valid?
|
61
76
|
end
|
62
77
|
|
63
|
-
test "not within a #with_captcha_validation block, calling valid? should return true if an invalid
|
64
|
-
|
65
|
-
|
78
|
+
test "not within a #with_captcha_validation block, calling valid? should return true if an invalid captcha_solution is set" do
|
79
|
+
with_image_provider do |provider|
|
80
|
+
widget = Widget.new
|
81
|
+
widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge).reverse
|
82
|
+
|
83
|
+
assert widget.valid?
|
84
|
+
end
|
66
85
|
|
67
|
-
|
86
|
+
with_question_provider do |provider|
|
87
|
+
widget = Widget.new
|
88
|
+
widget.captcha_solution = '---'
|
89
|
+
|
90
|
+
assert widget.valid?
|
91
|
+
end
|
68
92
|
end
|
69
93
|
|
70
|
-
test "not within a #with_captcha_validation block, calling valid? should return true if a valid
|
71
|
-
|
72
|
-
|
94
|
+
test "not within a #with_captcha_validation block, calling valid? should return true if a valid captcha_solution is set" do
|
95
|
+
with_image_provider do |provider|
|
96
|
+
widget = Widget.new
|
97
|
+
widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge)
|
98
|
+
|
99
|
+
assert widget.valid?
|
100
|
+
end
|
73
101
|
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
test "within a #with_captcha_validation block, calling valid? should return false if no captcha is set" do
|
78
|
-
Widget.with_captcha_validation do
|
102
|
+
with_question_provider do |provider|
|
79
103
|
widget = Widget.new
|
104
|
+
widget.captcha_solution = provider.send(:solve, widget.captcha_challenge)
|
80
105
|
|
81
|
-
assert
|
82
|
-
assert_equal 1, Array.wrap(widget.errors[:captcha]).size
|
83
|
-
assert Array.wrap(widget.errors[:captcha]).first.include?('blank')
|
106
|
+
assert widget.valid?
|
84
107
|
end
|
85
108
|
end
|
86
109
|
|
87
|
-
test "within a #with_captcha_validation block, calling valid? should return false if
|
110
|
+
test "within a #with_captcha_validation block, calling valid? should return false if no captcha_solution is set" do
|
88
111
|
Widget.with_captcha_validation do
|
89
112
|
widget = Widget.new
|
90
|
-
widget.
|
113
|
+
widget.captcha_solution = nil
|
91
114
|
|
92
115
|
assert !widget.valid?
|
93
|
-
assert_equal 1, Array.wrap(widget.errors[:
|
94
|
-
assert Array.wrap(widget.errors[:
|
116
|
+
assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
|
117
|
+
assert Array.wrap(widget.errors[:captcha_solution]).first.include?('blank')
|
95
118
|
end
|
96
119
|
end
|
97
120
|
|
98
|
-
test "within a #with_captcha_validation block, calling valid? should return false if an
|
121
|
+
test "within a #with_captcha_validation block, calling valid? should return false if an empty captcha_solution is set" do
|
99
122
|
Widget.with_captcha_validation do
|
100
123
|
widget = Widget.new
|
101
|
-
widget.
|
124
|
+
widget.captcha_solution = ' '
|
102
125
|
|
103
126
|
assert !widget.valid?
|
104
|
-
assert_equal 1, Array.wrap(widget.errors[:
|
105
|
-
assert Array.wrap(widget.errors[:
|
127
|
+
assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
|
128
|
+
assert Array.wrap(widget.errors[:captcha_solution]).first.include?('blank')
|
106
129
|
end
|
107
130
|
end
|
108
131
|
|
109
|
-
test "within a #with_captcha_validation block, calling valid? should return
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
132
|
+
test "within a #with_captcha_validation block, calling valid? should return false if an invalid captcha_solution is set" do
|
133
|
+
with_image_provider do |provider|
|
134
|
+
Widget.with_captcha_validation do
|
135
|
+
widget = Widget.new
|
136
|
+
widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge).reverse
|
137
|
+
|
138
|
+
assert !widget.valid?
|
139
|
+
assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
|
140
|
+
assert Array.wrap(widget.errors[:captcha_solution]).first.include?('invalid')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
with_question_provider do |provider|
|
145
|
+
Widget.with_captcha_validation do
|
146
|
+
widget = Widget.new
|
147
|
+
widget.captcha_solution = '---'
|
148
|
+
|
149
|
+
assert !widget.valid?
|
150
|
+
assert_equal 1, Array.wrap(widget.errors[:captcha_solution]).size
|
151
|
+
assert Array.wrap(widget.errors[:captcha_solution]).first.include?('invalid')
|
152
|
+
end
|
115
153
|
end
|
116
154
|
end
|
117
155
|
|
118
|
-
test "
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
156
|
+
test "within a #with_captcha_validation block, calling valid? should return true if a valid captcha_solution is set" do
|
157
|
+
with_image_provider do |provider|
|
158
|
+
Widget.with_captcha_validation do
|
159
|
+
widget = Widget.new
|
160
|
+
widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge)
|
161
|
+
|
162
|
+
assert widget.valid?
|
163
|
+
end
|
164
|
+
end
|
123
165
|
|
124
|
-
|
125
|
-
|
166
|
+
with_question_provider do |provider|
|
167
|
+
Widget.with_captcha_validation do
|
168
|
+
widget = Widget.new
|
169
|
+
widget.captcha_solution = provider.send(:solve, widget.captcha_challenge)
|
170
|
+
|
171
|
+
assert widget.valid?
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
test "with #with_captcha_validation block, calling valid? before and after the block should return true if valid? returned false within block" do
|
177
|
+
with_image_provider do |provider|
|
178
|
+
widget = Widget.new
|
179
|
+
widget.captcha_solution = provider.send(:decrypt, widget.captcha_challenge).reverse
|
180
|
+
|
181
|
+
assert widget.valid?
|
182
|
+
|
183
|
+
Widget.with_captcha_validation do
|
184
|
+
assert !widget.valid?
|
185
|
+
end
|
186
|
+
|
187
|
+
assert widget.valid?
|
126
188
|
end
|
127
189
|
|
128
|
-
|
190
|
+
with_question_provider do |provider|
|
191
|
+
widget = Widget.new
|
192
|
+
widget.captcha_solution = '---'
|
193
|
+
|
194
|
+
assert widget.valid?
|
195
|
+
|
196
|
+
Widget.with_captcha_validation do
|
197
|
+
assert !widget.valid?
|
198
|
+
end
|
199
|
+
|
200
|
+
assert widget.valid?
|
201
|
+
end
|
129
202
|
end
|
130
203
|
end
|