acts_as_textcaptcha 4.2.0 → 4.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rubocop.yml +1165 -0
  4. data/.simplecov +11 -0
  5. data/.travis.yml +30 -8
  6. data/Appraisals +9 -6
  7. data/CHANGELOG.md +94 -34
  8. data/CODE_OF_CONDUCT.md +54 -31
  9. data/CONTRIBUTING.md +14 -9
  10. data/Gemfile +2 -2
  11. data/LICENSE +165 -0
  12. data/PULL_REQUEST_TEMPLATE.md +16 -0
  13. data/README.md +206 -228
  14. data/Rakefile +26 -19
  15. data/acts_as_textcaptcha.gemspec +57 -41
  16. data/bin/console +2 -5
  17. data/bin/setup +7 -0
  18. data/gemfiles/rails_3.gemfile +1 -0
  19. data/gemfiles/rails_4.gemfile +2 -1
  20. data/gemfiles/rails_5.gemfile +2 -1
  21. data/gemfiles/rails_6.gemfile +8 -0
  22. data/lib/acts_as_textcaptcha.rb +9 -4
  23. data/lib/acts_as_textcaptcha/errors.rb +21 -0
  24. data/lib/acts_as_textcaptcha/framework/rails.rb +3 -1
  25. data/lib/acts_as_textcaptcha/railtie.rb +9 -0
  26. data/lib/acts_as_textcaptcha/tasks/textcaptcha.rake +17 -0
  27. data/lib/acts_as_textcaptcha/textcaptcha.rb +75 -72
  28. data/lib/acts_as_textcaptcha/textcaptcha_api.rb +39 -45
  29. data/lib/acts_as_textcaptcha/textcaptcha_cache.rb +12 -16
  30. data/lib/acts_as_textcaptcha/textcaptcha_config.rb +47 -0
  31. data/lib/acts_as_textcaptcha/textcaptcha_helper.rb +13 -14
  32. data/lib/acts_as_textcaptcha/version.rb +3 -1
  33. metadata +68 -46
  34. data/.coveralls.yml +0 -1
  35. data/LICENSE.txt +0 -21
  36. data/config/textcaptcha.yml +0 -34
  37. data/lib/tasks/textcaptcha.rake +0 -21
  38. data/test/schema.rb +0 -34
  39. data/test/test_helper.rb +0 -44
  40. data/test/test_models.rb +0 -69
  41. data/test/textcaptcha_api_test.rb +0 -46
  42. data/test/textcaptcha_cache_test.rb +0 -25
  43. data/test/textcaptcha_helper_test.rb +0 -68
  44. data/test/textcaptcha_test.rb +0 -198
@@ -1 +0,0 @@
1
- service_name: travis-ci
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2016 Matthew Hutchinson
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
@@ -1,34 +0,0 @@
1
- development: &common_settings
2
- api_key: PASTE_YOUR_TEXTCAPCHA_API_KEY_HERE # grab one from http://textcaptcha.com/api
3
- http_read_timeout: 60 # Optional seconds to wait for one block to be read from http://textcaptcha.com/api
4
- # http_open_timeout: 10 # Optional seconds to wait for the connection to open
5
- # cache_expiry_minutes: 10 # Optional minutes for captcha answers to persist in the cache (default 10 minutes)
6
-
7
- questions:
8
- - question: 'Is ice hot or cold?'
9
- answers: 'cold'
10
- - question: 'what color is an orange?'
11
- answers: 'orange'
12
- - question: 'what is two plus 3?'
13
- answers: '5,five'
14
- - question: 'what is 5 times two?'
15
- answers: '10,ten'
16
- - question: 'How many colors in the list, green, brown, foot and blue?'
17
- answers: '3,three'
18
- - question: 'what is Georges name?'
19
- answers: 'george'
20
- - question: '11 minus 1?'
21
- answers: '10,ten'
22
- - question: 'is boiling water hot or cold?'
23
- answers: 'hot'
24
- - question: 'what color is my blue shirt today?'
25
- answers: 'blue'
26
- - question: 'what is 16 plus 4?'
27
- answers: '20,twenty'
28
-
29
- test:
30
- <<: *common_settings
31
- api_key: 6eh1co0j12mi2ogcoggkkok4o
32
-
33
- production:
34
- <<: *common_settings
@@ -1,21 +0,0 @@
1
- namespace :textcaptcha do
2
-
3
- desc "Creates a template config file in config/textcaptcha.yml"
4
- task :config do
5
- src = File.join(File.dirname(__FILE__), '../..', 'config', 'textcaptcha.yml')
6
- dest = File.join(Rails.root, 'config', 'textcaptcha.yml')
7
- if File.exist?(dest)
8
- puts "\nOoops, a textcaptcha config file at #{dest} already exists ... aborting.\n\n"
9
- else
10
- config = ''
11
- f = File.open(src, 'r')
12
- f.each_line { |line| config += line }
13
- config.gsub!(/ api_key:(.*)# for gem test purposes only$/, " api_key: PASTE_YOUR_TEXTCAPCHA_API_KEY_HERE")
14
-
15
- f = File.new(dest, 'w')
16
- f.write(config)
17
- f.close
18
- puts "\ntextcaptcha.yml generated at #{dest}\nNOTE: edit this file and add your textcaptcha api key, grab one from http://textcaptcha.com/api\n\n"
19
- end
20
- end
21
- end
@@ -1,34 +0,0 @@
1
- ActiveRecord::Schema.define(:version => 0) do
2
-
3
- create_table :widgets, :force => true do |t|
4
- t.string :name
5
- end
6
-
7
- create_table :comments, :force => true do |t|
8
- t.string :name
9
- end
10
-
11
- create_table :fast_comments, :force => true do |t|
12
- t.string :name
13
- end
14
-
15
- create_table :reviews, :force => true do |t|
16
- t.string :name
17
- end
18
-
19
- create_table :movie_reviews, :force => true do |t|
20
- t.string :name
21
- end
22
-
23
- create_table :notes, :force => true do |t|
24
- t.string :name
25
- end
26
-
27
- create_table :strong_protected_widgets, :force => true do |t|
28
- t.string :name
29
- end
30
-
31
- create_table :strong_accessible_widgets, :force => true do |t|
32
- t.string :name
33
- end
34
- end
@@ -1,44 +0,0 @@
1
- $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)+'./../lib/acts_as_textcaptcha'))
2
-
3
- ENV['RAILS_ENV'] = 'test'
4
-
5
- # ensure tmp dir exists
6
- FileUtils.mkdir_p './tmp'
7
-
8
- # confgure test coverage reporting
9
- if ENV['COVERAGE']
10
- require 'simplecov'
11
- SimpleCov.start do
12
- add_filter '/test/'
13
- add_filter '/vendor/'
14
- end
15
- SimpleCov.at_exit do
16
- SimpleCov.result.format!
17
- `open ./coverage/index.html` if RUBY_PLATFORM =~ /darwin/
18
- end
19
- elsif ENV['TRAVIS']
20
- require 'coveralls'
21
- Coveralls.wear!
22
- end
23
-
24
- require 'minitest/autorun'
25
- require 'webmock/minitest'
26
- require 'rails/all'
27
- require 'acts_as_textcaptcha'
28
- require './test/test_models'
29
-
30
- # load and initialize test db schema
31
- ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'tmp/acts_as_textcaptcha_test.sqlite3.db')
32
- load(File.dirname(__FILE__) + "/schema.rb")
33
-
34
- # initialize the Rails cache (use a basic memory store in tests)
35
- if Rails.version >= '4'
36
- Rails.cache = ActiveSupport::Cache::MemoryStore.new
37
- else
38
- RAILS_CACHE = ActiveSupport::Cache::MemoryStore.new
39
- end
40
-
41
- # additional helper methods for use in tests
42
- def find_in_cache(key)
43
- Rails.cache.read("#{ActsAsTextcaptcha::TextcaptchaCache::CACHE_KEY_PREFIX}#{key}")
44
- end
@@ -1,69 +0,0 @@
1
- # models for use in tests
2
- class ApplicationRecord < ActiveRecord::Base
3
- self.abstract_class = true
4
- end
5
-
6
- class Widget < ApplicationRecord
7
- # uses textcaptcha.yml file for configuration
8
- acts_as_textcaptcha
9
- end
10
-
11
- class Comment < ApplicationRecord
12
- # inline options (symbol keys) with api_key only
13
- acts_as_textcaptcha :api_key => '8u5ixtdnq9csc84cok0owswgo'
14
- end
15
-
16
- class FastComment < ApplicationRecord
17
- # inline options with super fast (0.006 seconds) cache expiry time
18
- acts_as_textcaptcha :cache_expiry_minutes => '0.0001',
19
- :questions => [{ :question => '1+1', :answers => '2,two' }]
20
- end
21
-
22
- class Review < ApplicationRecord
23
- # inline options with all possible options
24
- acts_as_textcaptcha :api_key => '8u5ixtdnq9csc84cok0owswgo',
25
- :questions => [{ :question => 'The green hat is what color?', :answers => 'green' }]
26
- end
27
-
28
- class MovieReview < ApplicationRecord
29
- # inline options with all possible options
30
- acts_as_textcaptcha 'api_key' => '8u5ixtdnq9csc84cok0owswgo',
31
- 'questions' => [{ 'Question' => 'The green hat is what color?', 'answers' => nil }]
32
- end
33
-
34
- class Note < ApplicationRecord
35
- # inline options (string keys) with user defined questions only (no textcaptcha service)
36
- acts_as_textcaptcha 'questions' => [{ 'question' => '1+1', 'answers' => '2,two' }]
37
-
38
- # allows toggling perform_textcaptcha on/off (default on)
39
- attr_accessor :turn_off_captcha
40
-
41
- def perform_textcaptcha?
42
- super && !turn_off_captcha
43
- end
44
- end
45
-
46
- class Contact
47
- # non active record object (symbol keys), no API used
48
- include ActiveModel::Validations
49
- include ActiveModel::Conversion
50
- extend ActsAsTextcaptcha::Textcaptcha
51
- acts_as_textcaptcha :questions => [{ :question => 'one+1', :answers => "2,two,апельсин" }]
52
- end
53
-
54
- class StrongAccessibleWidget < ApplicationRecord
55
-
56
- # stub out attr_accessbile interface for testing
57
- def self.accessible_attributes(role = :default); end
58
- def self.attr_accessible(*args); end
59
-
60
- acts_as_textcaptcha 'questions' => [{ 'question' => '1+1', 'answers' => '2,two' }]
61
- end
62
-
63
- class StrongProtectedWidget < StrongAccessibleWidget
64
-
65
- # stub out attr_protected interface for testing
66
- def self.attr_protected(*args); end
67
-
68
- acts_as_textcaptcha 'questions' => [{ 'question' => '1+1', 'answers' => '2,two' }]
69
- end
@@ -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
@@ -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