acts_as_textcaptcha 4.3.0 → 4.4.1
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.simplecov +9 -0
- data/.travis.yml +13 -4
- data/Appraisals +1 -1
- data/CHANGELOG.md +68 -34
- data/CODE_OF_CONDUCT.md +54 -30
- data/CONTRIBUTING.md +14 -9
- data/Gemfile +0 -2
- data/LICENSE +165 -0
- data/README.md +194 -223
- data/Rakefile +21 -13
- data/acts_as_textcaptcha.gemspec +52 -32
- data/bin/console +2 -5
- data/bin/setup +7 -0
- data/gemfiles/rails_3.gemfile +1 -1
- data/gemfiles/rails_4.gemfile +1 -1
- data/gemfiles/rails_5.gemfile +2 -2
- data/lib/acts_as_textcaptcha.rb +3 -1
- data/lib/acts_as_textcaptcha/errors.rb +19 -0
- data/lib/acts_as_textcaptcha/textcaptcha.rb +91 -84
- data/lib/acts_as_textcaptcha/textcaptcha_api.rb +39 -44
- data/lib/acts_as_textcaptcha/textcaptcha_cache.rb +12 -15
- data/{config/textcaptcha.yml → lib/acts_as_textcaptcha/textcaptcha_config.rb} +16 -4
- data/lib/acts_as_textcaptcha/textcaptcha_helper.rb +14 -14
- data/lib/acts_as_textcaptcha/version.rb +1 -1
- data/lib/tasks/textcaptcha.rake +9 -14
- metadata +64 -31
- data/.coveralls.yml +0 -1
- data/LICENSE.txt +0 -21
- data/test/schema.rb +0 -34
- data/test/test_helper.rb +0 -28
- data/test/test_models.rb +0 -69
- data/test/textcaptcha_api_test.rb +0 -46
- data/test/textcaptcha_cache_test.rb +0 -25
- data/test/textcaptcha_helper_test.rb +0 -68
- data/test/textcaptcha_test.rb +0 -198
@@ -1,46 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)+'/test_helper')
|
2
|
-
|
3
|
-
describe 'TextcaptchaApi' do
|
4
|
-
|
5
|
-
describe 'with a valid xml response' do
|
6
|
-
|
7
|
-
before(:each) do
|
8
|
-
body = "<captcha><question>1+1?</question><answer>1</answer><answer>2</answer><answer>3</answer></captcha>"
|
9
|
-
stub_request(:get, "http://textcaptcha.com/api/abc").to_return(:body => body)
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'should fetch and parse an answer from the service' do
|
13
|
-
result = ActsAsTextcaptcha::TextcaptchaApi.fetch('abc')
|
14
|
-
result[0].must_equal '1+1?'
|
15
|
-
result[1].must_equal ['1', '2', '3']
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should allow http options to be set' do
|
19
|
-
result = ActsAsTextcaptcha::TextcaptchaApi.fetch('abc', { :http_read_timeout => 30,
|
20
|
-
:http_open_timeout => 5 })
|
21
|
-
result.length.must_equal 2
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should return nil when Net::HTTP errors occur' do
|
26
|
-
[
|
27
|
-
SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
|
28
|
-
Errno::EHOSTUNREACH, EOFError, Errno::ECONNREFUSED, Errno::ETIMEDOUT,
|
29
|
-
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
|
30
|
-
URI::InvalidURIError
|
31
|
-
].each do |error|
|
32
|
-
stub_request(:get, "http://textcaptcha.com/api/xyz").to_raise(error)
|
33
|
-
assert_nil ActsAsTextcaptcha::TextcaptchaApi.fetch('xyz')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should return nil when body cannot be parsed as XML' do
|
38
|
-
stub_request(:get, "http://textcaptcha.com/api/jibber").to_return(:body => 'here be gibberish')
|
39
|
-
assert_nil ActsAsTextcaptcha::TextcaptchaApi.fetch('jibber')
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should return nil when body is empty' do
|
43
|
-
stub_request(:get, "http://textcaptcha.com/api/empty").to_return(:body => '')
|
44
|
-
assert_nil ActsAsTextcaptcha::TextcaptchaApi.fetch('empty')
|
45
|
-
end
|
46
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)+'/test_helper')
|
2
|
-
|
3
|
-
describe 'TextcaptchaCache' do
|
4
|
-
|
5
|
-
before(:each) do
|
6
|
-
@cache = ActsAsTextcaptcha::TextcaptchaCache.new
|
7
|
-
@cache.write('mykey', [1,2,3])
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'should write to the cache' do
|
11
|
-
@cache.write('my-new-key', 'abc')
|
12
|
-
@cache.read('my-new-key').must_equal 'abc'
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should read from the cache' do
|
16
|
-
@cache.read('mykey').must_equal [1,2,3]
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should delete from the cache' do
|
20
|
-
@cache.read('mykey').must_equal [1,2,3]
|
21
|
-
@cache.delete('mykey')
|
22
|
-
|
23
|
-
assert_nil @cache.read('mykey')
|
24
|
-
end
|
25
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)+'/test_helper')
|
2
|
-
require 'action_controller'
|
3
|
-
require 'action_view'
|
4
|
-
|
5
|
-
class NotesController < ActionController::Base; end
|
6
|
-
|
7
|
-
class Template < ActionView::Base
|
8
|
-
def protect_against_forgery?; false; end
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
|
-
describe 'TextcaptchaHelper' do
|
13
|
-
|
14
|
-
before(:each) do
|
15
|
-
@controller = NotesController.new
|
16
|
-
@note = Note.new
|
17
|
-
@note.textcaptcha
|
18
|
-
end
|
19
|
-
|
20
|
-
def render_template(assigns = { :note => @note })
|
21
|
-
template = <<-ERB
|
22
|
-
<%= form_for(@note, :url => '/') do |f| %>
|
23
|
-
<%= textcaptcha_fields(f) do %>
|
24
|
-
<div class="field textcaptcha">
|
25
|
-
<%= f.label :textcaptcha_answer, @note.textcaptcha_question %><br/>
|
26
|
-
<%= f.text_field :textcaptcha_answer, :value => '' %>
|
27
|
-
</div>
|
28
|
-
<% end %>
|
29
|
-
<% end %>
|
30
|
-
ERB
|
31
|
-
|
32
|
-
Template.new([], assigns, @controller).render(:inline => template)
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'should render question and answer fields, with hidden textcaptcha_key field' do
|
36
|
-
html = render_template
|
37
|
-
|
38
|
-
assert_match(/\<label for\=\"note_textcaptcha_answer\"\>1\+1\<\/label\>/, html)
|
39
|
-
assert_match(/\<input(.*)name\=\"note\[textcaptcha_answer\]\"(.*)\/\>/, html)
|
40
|
-
assert_match(/\<input(.*)name\=\"note\[textcaptcha_key\]\"(.*)\/\>/, html)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'should render hidden answer and textcaptcha_key when only answer is present' do
|
44
|
-
@note.textcaptcha_question = nil
|
45
|
-
@note.textcaptcha_answer = 2
|
46
|
-
html = render_template
|
47
|
-
|
48
|
-
refute_match(/\<label for\=\"note_textcaptcha_answer\"\>1\+1\<\/label\>/, html)
|
49
|
-
assert_match(/\<input(.*)name\=\"note\[textcaptcha_answer\]\"(.*)\/\>/, html)
|
50
|
-
assert_match(/\<input(.*)name\=\"note\[textcaptcha_key\]\"(.*)\/\>/, html)
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should not render any question or answer when perform_textcaptcha? is false' do
|
54
|
-
@note.turn_off_captcha = true
|
55
|
-
html = render_template
|
56
|
-
|
57
|
-
refute_match(/note_textcaptcha_answer/, html)
|
58
|
-
refute_match(/note_textcaptcha_key/, html)
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should not render any question or answer when textcaptcha_key is missing' do
|
62
|
-
@note.textcaptcha_key = nil
|
63
|
-
html = render_template
|
64
|
-
|
65
|
-
refute_match(/note_textcaptcha_answer/, html)
|
66
|
-
refute_match(/note_textcaptcha_key/, html)
|
67
|
-
end
|
68
|
-
end
|
data/test/textcaptcha_test.rb
DELETED
@@ -1,198 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)+'/test_helper')
|
2
|
-
|
3
|
-
describe 'Textcaptcha' do
|
4
|
-
|
5
|
-
describe 'validations' do
|
6
|
-
|
7
|
-
before(:each) do
|
8
|
-
@note = Note.new
|
9
|
-
@note.textcaptcha
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'should validate an ActiveRecord object (with multiple correct answers)' do
|
13
|
-
@note.textcaptcha_question.must_equal('1+1')
|
14
|
-
@note.valid?.must_equal false
|
15
|
-
@note.errors[:textcaptcha_answer].first.must_equal('is incorrect, try another question instead')
|
16
|
-
|
17
|
-
@note.textcaptcha_answer = 'two'
|
18
|
-
@note.valid?.must_equal true
|
19
|
-
@note.errors[:textcaptcha_answer].must_be_empty
|
20
|
-
|
21
|
-
@note.textcaptcha_answer = '2'
|
22
|
-
@note.valid?.must_equal true
|
23
|
-
@note.errors[:textcaptcha_answer].must_be_empty
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'should strip whitespace and downcase answer' do
|
27
|
-
@note.textcaptcha_answer = ' tWo '
|
28
|
-
@note.valid?.must_equal true
|
29
|
-
@note.errors[:textcaptcha_answer].must_be_empty
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'should always be valid when record has been saved' do
|
33
|
-
@note.textcaptcha_answer = '2'
|
34
|
-
@note.save!
|
35
|
-
@note.textcaptcha
|
36
|
-
|
37
|
-
@note.textcaptcha_answer = 'wrong answer'
|
38
|
-
@note.new_record?.must_equal false
|
39
|
-
@note.valid?.must_equal true
|
40
|
-
@note.errors[:textcaptcha_answer].must_be_empty
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'should always be valid when perform_textcaptcha? is false' do
|
44
|
-
@note.turn_off_captcha = true
|
45
|
-
@note.valid?.must_equal true
|
46
|
-
@note.errors[:textcaptcha_answer].must_be_empty
|
47
|
-
|
48
|
-
@note.save.must_equal true
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'should validate a non ActiveRecord object' do
|
52
|
-
@contact = Contact.new
|
53
|
-
@contact.textcaptcha
|
54
|
-
|
55
|
-
@contact.textcaptcha_question.must_equal('one+1')
|
56
|
-
@contact.textcaptcha_answer = 'wrong'
|
57
|
-
@contact.valid?.must_equal false
|
58
|
-
|
59
|
-
@contact.textcaptcha_answer = 'two'
|
60
|
-
@contact.valid?.must_equal true
|
61
|
-
@contact.errors[:textcaptcha_answer].must_be_empty
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe 'with fast expiry time' do
|
66
|
-
|
67
|
-
before(:each) do
|
68
|
-
@comment = FastComment.new
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'should work' do
|
72
|
-
@comment.textcaptcha
|
73
|
-
@comment.textcaptcha_question.must_equal('1+1')
|
74
|
-
@comment.textcaptcha_answer = 'two'
|
75
|
-
sleep(0.01)
|
76
|
-
|
77
|
-
@comment.valid?.must_equal false
|
78
|
-
@comment.errors[:textcaptcha_answer].first.must_equal('was not submitted quickly enough, try another question instead')
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
describe 'textcaptcha API' do
|
83
|
-
|
84
|
-
it 'should generate a question from the service' do
|
85
|
-
@review = Review.new
|
86
|
-
body = "<captcha><question>Something?</question><answer>f6f7fec07f372b7bd5eb196bbca0f3f4</answer></captcha>"
|
87
|
-
stub_request(:get, %r{http://textcaptcha.com/api/}).and_return(:body => body)
|
88
|
-
|
89
|
-
@review.textcaptcha
|
90
|
-
@review.textcaptcha_question.wont_be_nil
|
91
|
-
@review.textcaptcha_question.wont_equal('The green hat is what color?')
|
92
|
-
|
93
|
-
find_in_cache(@review.textcaptcha_key).wont_be_nil
|
94
|
-
|
95
|
-
@review.valid?.must_equal false
|
96
|
-
@review.errors[:textcaptcha_answer].first.must_equal('is incorrect, try another question instead')
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'should parse a single answer from XML response' do
|
100
|
-
@review = Review.new
|
101
|
-
question = 'If tomorrow is Saturday, what day is today?'
|
102
|
-
body = "<captcha><question>#{question}</question><answer>f6f7fec07f372b7bd5eb196bbca0f3f4</answer></captcha>"
|
103
|
-
stub_request(:get, %r{http://textcaptcha.com/api/}).and_return(:body => body)
|
104
|
-
|
105
|
-
@review.textcaptcha
|
106
|
-
@review.textcaptcha_question.must_equal(question)
|
107
|
-
find_in_cache(@review.textcaptcha_key).must_equal(['f6f7fec07f372b7bd5eb196bbca0f3f4'])
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'should parse multiple answers from XML response' do
|
111
|
-
@review = Review.new
|
112
|
-
question = 'If tomorrow is Saturday, what day is today?'
|
113
|
-
body = "<captcha><question>#{question}</question><answer>1</answer><answer>2</answer><answer>3</answer></captcha>"
|
114
|
-
stub_request(:get, %r{http://textcaptcha.com/api}).and_return(:body => body)
|
115
|
-
|
116
|
-
@review.textcaptcha
|
117
|
-
@review.textcaptcha_question.must_equal(question)
|
118
|
-
find_in_cache(@review.textcaptcha_key).length.must_equal(3)
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'should fallback to a user defined question when api returns nil' do
|
122
|
-
@review = Review.new
|
123
|
-
stub_request(:get, %r{http://textcaptcha.com/api}).and_return(:body => '')
|
124
|
-
@review.textcaptcha
|
125
|
-
@review.textcaptcha_question.must_equal('The green hat is what color?')
|
126
|
-
find_in_cache(@review.textcaptcha_key).wont_be_nil
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'should not generate any question or answer when no user defined questions set' do
|
130
|
-
@comment = Comment.new
|
131
|
-
|
132
|
-
stub_request(:get, %r{http://textcaptcha.com/api/}).to_raise(SocketError)
|
133
|
-
@comment.textcaptcha
|
134
|
-
assert_nil @comment.textcaptcha_question
|
135
|
-
assert_nil @comment.textcaptcha_key
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'should not generate any question or answer when user defined questions set incorrectly' do
|
139
|
-
@comment = MovieReview.new
|
140
|
-
|
141
|
-
stub_request(:get, %r{http://textcaptcha.com/api/}).to_raise(SocketError)
|
142
|
-
@comment.textcaptcha
|
143
|
-
assert_nil @comment.textcaptcha_question
|
144
|
-
assert_nil @comment.textcaptcha_key
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
describe 'configuration' do
|
149
|
-
|
150
|
-
it 'should be configured with inline hash' do
|
151
|
-
Review.textcaptcha_config.must_equal({ :api_key => '8u5ixtdnq9csc84cok0owswgo',
|
152
|
-
:questions => [{ :question => 'The green hat is what color?', :answers => 'green' }]})
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'should be configured with textcaptcha.yml' do
|
156
|
-
Widget.textcaptcha_config[:api_key].must_equal('6eh1co0j12mi2ogcoggkkok4o')
|
157
|
-
Widget.textcaptcha_config[:questions].length.must_equal(10)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
describe 'with strong parameters' do
|
162
|
-
|
163
|
-
it 'should work with accessible_attr widget ' do
|
164
|
-
@widget = StrongAccessibleWidget.new
|
165
|
-
|
166
|
-
@widget.textcaptcha
|
167
|
-
@widget.textcaptcha_question.must_equal('1+1')
|
168
|
-
@widget.valid?.must_equal false
|
169
|
-
end
|
170
|
-
|
171
|
-
it 'should work with protected_attr widget ' do
|
172
|
-
@widget = StrongProtectedWidget.new
|
173
|
-
|
174
|
-
@widget.textcaptcha
|
175
|
-
@widget.textcaptcha_question.must_equal('1+1')
|
176
|
-
@widget.valid?.must_equal false
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
describe 'when missing config' do
|
181
|
-
|
182
|
-
it 'should raise an error' do
|
183
|
-
YAML.stub :load, -> { raise 'some bad things happened' } do
|
184
|
-
|
185
|
-
error = assert_raises(ArgumentError) do
|
186
|
-
class NoConfig
|
187
|
-
include ActiveModel::Validations
|
188
|
-
include ActiveModel::Conversion
|
189
|
-
extend ActsAsTextcaptcha::Textcaptcha
|
190
|
-
acts_as_textcaptcha
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
error.message.must_match(/could not find any textcaptcha options/)
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|