require File.expand_path(File.dirname(__FILE__)+'/test_helper') describe 'Textcaptcha' do describe 'validations' do before(:each) do @note = Note.new @note.textcaptcha end it 'should validate an ActiveRecord object (with multiple correct answers)' do @note.textcaptcha_question.must_equal('1+1') @note.valid?.must_equal false @note.errors[:textcaptcha_answer].first.must_equal('is incorrect, try another question instead') @note.textcaptcha_answer = 'two' @note.valid?.must_equal true @note.errors[:textcaptcha_answer].must_be_empty @note.textcaptcha_answer = '2' @note.valid?.must_equal true @note.errors[:textcaptcha_answer].must_be_empty end it 'should strip whitespace and downcase answer' do @note.textcaptcha_answer = ' tWo ' @note.valid?.must_equal true @note.errors[:textcaptcha_answer].must_be_empty end it 'should always be valid when record has been saved' do @note.textcaptcha_answer = '2' @note.save! @note.textcaptcha @note.textcaptcha_answer = 'wrong answer' @note.new_record?.must_equal false @note.valid?.must_equal true @note.errors[:textcaptcha_answer].must_be_empty end it 'should always be valid when perform_textcaptcha? is false' do @note.turn_off_captcha = true @note.valid?.must_equal true @note.errors[:textcaptcha_answer].must_be_empty @note.save.must_equal true end it 'should validate a non ActiveRecord object' do @contact = Contact.new @contact.textcaptcha @contact.textcaptcha_question.must_equal('one+1') @contact.textcaptcha_answer = 'wrong' @contact.valid?.must_equal false @contact.textcaptcha_answer = 'two' @contact.valid?.must_equal true @contact.errors[:textcaptcha_answer].must_be_empty end end describe 'with fast expiry time' do before(:each) do @comment = FastComment.new end it 'should work' do @comment.textcaptcha @comment.textcaptcha_question.must_equal('1+1') @comment.textcaptcha_answer = 'two' sleep(0.01) @comment.valid?.must_equal false @comment.errors[:textcaptcha_answer].first.must_equal('was not submitted quickly enough, try another question instead') end end describe 'textcaptcha API' do it 'should generate a question from the service' do @review = Review.new body = "Something?f6f7fec07f372b7bd5eb196bbca0f3f4" stub_request(:get, %r{http://textcaptcha.com/api/}).and_return(:body => body) @review.textcaptcha @review.textcaptcha_question.wont_be_nil @review.textcaptcha_question.wont_equal('The green hat is what color?') find_in_cache(@review.textcaptcha_key).wont_be_nil @review.valid?.must_equal false @review.errors[:textcaptcha_answer].first.must_equal('is incorrect, try another question instead') end it 'should parse a single answer from XML response' do @review = Review.new question = 'If tomorrow is Saturday, what day is today?' body = "#{question}f6f7fec07f372b7bd5eb196bbca0f3f4" stub_request(:get, %r{http://textcaptcha.com/api/}).and_return(:body => body) @review.textcaptcha @review.textcaptcha_question.must_equal(question) find_in_cache(@review.textcaptcha_key).must_equal(['f6f7fec07f372b7bd5eb196bbca0f3f4']) end it 'should parse multiple answers from XML response' do @review = Review.new question = 'If tomorrow is Saturday, what day is today?' body = "#{question}123" stub_request(:get, %r{http://textcaptcha.com/api}).and_return(:body => body) @review.textcaptcha @review.textcaptcha_question.must_equal(question) find_in_cache(@review.textcaptcha_key).length.must_equal(3) end it 'should fallback to a user defined question when api returns nil' do @review = Review.new stub_request(:get, %r{http://textcaptcha.com/api}).and_return(:body => '') @review.textcaptcha @review.textcaptcha_question.must_equal('The green hat is what color?') find_in_cache(@review.textcaptcha_key).wont_be_nil end it 'should not generate any question or answer when no user defined questions set' do @comment = Comment.new stub_request(:get, %r{http://textcaptcha.com/api/}).to_raise(SocketError) @comment.textcaptcha assert_nil @comment.textcaptcha_question assert_nil @comment.textcaptcha_key end it 'should not generate any question or answer when user defined questions set incorrectly' do @comment = MovieReview.new stub_request(:get, %r{http://textcaptcha.com/api/}).to_raise(SocketError) @comment.textcaptcha assert_nil @comment.textcaptcha_question assert_nil @comment.textcaptcha_key end end describe 'configuration' do it 'should be configured with inline hash' do Review.textcaptcha_config.must_equal({ :api_key => '8u5ixtdnq9csc84cok0owswgo', :questions => [{ :question => 'The green hat is what color?', :answers => 'green' }]}) end it 'should be configured with textcaptcha.yml' do Widget.textcaptcha_config[:api_key].must_equal('6eh1co0j12mi2ogcoggkkok4o') Widget.textcaptcha_config[:questions].length.must_equal(10) end end describe 'with strong parameters' do it 'should work with accessible_attr widget ' do @widget = StrongAccessibleWidget.new @widget.textcaptcha @widget.textcaptcha_question.must_equal('1+1') @widget.valid?.must_equal false end it 'should work with protected_attr widget ' do @widget = StrongProtectedWidget.new @widget.textcaptcha @widget.textcaptcha_question.must_equal('1+1') @widget.valid?.must_equal false end end describe 'when missing config' do it 'should raise an error' do YAML.stub :load, -> { raise 'some bad things happened' } do error = assert_raises(ArgumentError) do class NoConfig include ActiveModel::Validations include ActiveModel::Conversion extend ActsAsTextcaptcha::Textcaptcha acts_as_textcaptcha end end error.message.must_match(/could not find any textcaptcha options/) end end end end