merb-recaptcha 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +46 -0
  3. data/Rakefile +77 -0
  4. data/TODO +1 -0
  5. data/lib/merb-recaptcha.rb +29 -0
  6. data/lib/merb-recaptcha/constants.rb +7 -0
  7. data/lib/merb-recaptcha/controller_mixin.rb +46 -0
  8. data/lib/merb-recaptcha/exceptions.rb +30 -0
  9. data/lib/merb-recaptcha/merbtasks.rb +0 -0
  10. data/lib/merb-recaptcha/view_helpers.rb +117 -0
  11. data/merb-recaptcha.gemspec +44 -0
  12. data/spec/fixture/app/controllers/application.rb +2 -0
  13. data/spec/fixture/app/controllers/exceptions.rb +13 -0
  14. data/spec/fixture/app/controllers/recaptcha.rb +29 -0
  15. data/spec/fixture/app/helpers/global_helpers.rb +5 -0
  16. data/spec/fixture/app/helpers/recaptcha_helpers.rb +4 -0
  17. data/spec/fixture/app/views/exceptions/not_acceptable.html.erb +63 -0
  18. data/spec/fixture/app/views/exceptions/not_found.html.erb +47 -0
  19. data/spec/fixture/app/views/layout/application.html.erb +10 -0
  20. data/spec/fixture/app/views/recaptcha/ajax.html.erb +2 -0
  21. data/spec/fixture/app/views/recaptcha/ajax_with_callback.html.erb +2 -0
  22. data/spec/fixture/app/views/recaptcha/ajax_with_jquery.html.erb +2 -0
  23. data/spec/fixture/app/views/recaptcha/ajax_with_options.html.erb +2 -0
  24. data/spec/fixture/app/views/recaptcha/noajax_with_noscript.html.erb +1 -0
  25. data/spec/fixture/app/views/recaptcha/noajax_with_options.html.erb +1 -0
  26. data/spec/fixture/app/views/recaptcha/noajax_without_noscript.html.erb +1 -0
  27. data/spec/recaptcha_ajax_spec.rb +39 -0
  28. data/spec/recaptcha_ajax_with_callback_spec.rb +35 -0
  29. data/spec/recaptcha_ajax_with_jquery_spec.rb +39 -0
  30. data/spec/recaptcha_ajax_with_options_spec.rb +35 -0
  31. data/spec/recaptcha_noajax_with_noscript_spec.rb +59 -0
  32. data/spec/recaptcha_noajax_with_options_spec.rb +39 -0
  33. data/spec/recaptcha_noajax_without_noscript_spec.rb +39 -0
  34. data/spec/recaptcha_valid_spec.rb +125 -0
  35. data/spec/spec_helper.rb +46 -0
  36. metadata +130 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Anton Ageev
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,46 @@
1
+ = merb-recaptcha
2
+
3
+ == About
4
+
5
+ Merb-recaptcha is plugin for Merb web-framework. It provides view and controller helpers for Recaptcha service.
6
+
7
+ == Installation
8
+
9
+ Install gem from github.com:
10
+ gem install antage-merb-recaptcha --source=http://gems.github.com
11
+
12
+ Add following line in <tt>config/dependencies.rb</tt> of your web application:
13
+ dependency "antage-merb-recaptcha", "~> 1.0.0", :require_as => "merb-recaptcha"
14
+
15
+ Sign up at Recaptcha and get public and private keys. Add keys in <tt>config/init.rb</tt>:
16
+ Merb::BootLoader.after_app_loads do
17
+ Merb::Plugins.config[:merb_recaptcha][:public_key] = "... here your public key ..."
18
+ Merb::Plugins.config[:merb_recaptcha][:private_key] = "... here your private key ..."
19
+ end
20
+
21
+ == Usage
22
+
23
+ Just add helper in your form:
24
+ <%= form_for @users, :action => resource(:users), :method => :post do %>
25
+ .....
26
+ <%= recaptcha_tags %>
27
+ <%= submit "Send" %>
28
+ <% end %>
29
+
30
+ And then check captcha in controller:
31
+ class Users < Application
32
+ ......
33
+ def create(user)
34
+ @user = User.new(user)
35
+ if (captcha_correct = recaptcha_valid?) && @user.save
36
+ redirect resource(@user)
37
+ else
38
+ unless captcha_correct
39
+ @user.valid?
40
+ @user.errors.add(:general, "Captcha code is incorrect")
41
+ end
42
+ end
43
+ render :new
44
+ end
45
+ ......
46
+ end
@@ -0,0 +1,77 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/clean'
5
+
6
+ require 'spec/rake/spectask'
7
+
8
+ require 'merb-core'
9
+ require 'merb-core/tasks/merb'
10
+
11
+ GEM_NAME = "merb-recaptcha"
12
+ GEM_VERSION = "1.0.3"
13
+ EMAIL = "antage@gmail.com"
14
+ HOMEPAGE = "http://github.com/antage/merb-recaptcha/"
15
+ SUMMARY = "Merb plugin that provides helpers for recaptcha.net service"
16
+
17
+ spec = Gem::Specification.new do |s|
18
+ s.rubyforge_project = 'merb-recaptcha'
19
+ s.name = GEM_NAME
20
+ s.version = GEM_VERSION
21
+ s.platform = Gem::Platform::RUBY
22
+ s.authors = ["Anton Ageev", "Michael Johnston"]
23
+ s.has_rdoc = true
24
+ s.extra_rdoc_files = [ "README.rdoc", "LICENSE" ]
25
+ s.rdoc_options << "--main" << "README.rdoc"
26
+ s.summary = SUMMARY
27
+ s.description = s.summary
28
+ s.email = EMAIL
29
+ s.homepage = HOMEPAGE
30
+ s.require_path = 'lib'
31
+ s.files = %w(LICENSE README.rdoc Rakefile TODO merb-recaptcha.gemspec) + Dir["lib/**/*"].select { |f| File.file?(f) }
32
+ s.test_files = %w(spec/spec_helper.rb) + Dir["spec/*_spec.rb"] + Dir["spec/fixture/app/**/*"].select { |f| File.file?(f) }
33
+
34
+ s.add_runtime_dependency "merb-core", ">= 1.0.0"
35
+ s.add_runtime_dependency "builder", "~> 2.0"
36
+ s.add_development_dependency "rspec", ">= 1.1.0"
37
+ s.add_development_dependency "mocha", ">= 0.9.3"
38
+ end
39
+
40
+ Rake::GemPackageTask.new(spec) do |pkg|
41
+ pkg.gem_spec = spec
42
+ end
43
+
44
+ desc "install the plugin as a gem"
45
+ task :install do
46
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
47
+ end
48
+
49
+ desc "Uninstall the gem"
50
+ task :uninstall do
51
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
52
+ end
53
+
54
+ desc "Create a gemspec file"
55
+ task :gemspec do
56
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
57
+ file.puts spec.to_ruby
58
+ end
59
+ end
60
+
61
+ Rake::RDocTask.new do |rdoc|
62
+ files = ["README.rdoc", "LICENSE", "lib/**/*.rb"]
63
+ rdoc.rdoc_files.add(files)
64
+ rdoc.main = "README.rdoc"
65
+ rdoc.title = "merb-recaptcha docs"
66
+ rdoc.rdoc_dir = "doc"
67
+ rdoc.options << "--line-numbers" << "--inline-source"
68
+ end
69
+
70
+ Spec::Rake::SpecTask.new(:spec) do |t|
71
+ t.spec_opts << '--format' << 'specdoc' << '--colour'
72
+ t.spec_opts << '--loadby' << 'random'
73
+ t.spec_files = Pathname.glob(ENV['FILES'] || 'spec/**/*_spec.rb')
74
+ t.rcov = false
75
+ end
76
+
77
+ task :default => :spec
data/TODO ADDED
@@ -0,0 +1 @@
1
+ TODO:
@@ -0,0 +1,29 @@
1
+ # make sure we're running inside Merb
2
+ if defined?(Merb::Plugins)
3
+
4
+ # Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
5
+ Merb::Plugins.config[:merb_recaptcha] = {
6
+ :public_key => "",
7
+ :private_key => ""
8
+ }
9
+
10
+ Merb::BootLoader.before_app_loads do
11
+ # require code that must be loaded before the application
12
+ require 'merb-recaptcha/constants.rb'
13
+ require 'merb-recaptcha/view_helpers.rb'
14
+ require 'merb-recaptcha/exceptions.rb'
15
+ require 'merb-recaptcha/controller_mixin.rb'
16
+ module Merb::GlobalHelpers # :nodoc:
17
+ include Merb::Helpers::Recaptcha
18
+ end
19
+ class Merb::Controller # :nodoc:
20
+ include Merb::RecaptchaMixin
21
+ end
22
+ end
23
+
24
+ Merb::BootLoader.after_app_loads do
25
+ # code that can be required after the application loads
26
+ end
27
+
28
+ Merb::Plugins.add_rakefiles "merb-recaptcha/merbtasks"
29
+ end
@@ -0,0 +1,7 @@
1
+ module Merb
2
+ module Recaptcha
3
+ API_SERVER = "http://api.recaptcha.net"
4
+ API_SECURE_SERVER = "https://api-secure.recaptcha.net"
5
+ API_VERIFY_SERVER = "http://api-verify.recaptcha.net"
6
+ end
7
+ end
@@ -0,0 +1,46 @@
1
+ require 'net/http'
2
+
3
+ module Merb # :nodoc:
4
+ module RecaptchaMixin
5
+
6
+ # This method checks challenge and response data via Recaptcha API server.
7
+ # * It will return true, if filled captcha response is correct.
8
+ # * It will return false, if captcha is incorrect.
9
+ # * It will raise exception, if Recaptcha API server returns error.
10
+ #
11
+ def recaptcha_valid?
12
+ return true if (Merb.testing? && !Merb::RecaptchaMixin.const_defined?(:DO_NOT_IGNORE_RECAPTCHA_IN_TESTING_ENV))
13
+ begin
14
+ response = Net::HTTP.post_form(URI.parse("#{Merb::Recaptcha::API_VERIFY_SERVER}/verify"), {
15
+ :privatekey => Merb::Plugins.config[:merb_recaptcha][:private_key],
16
+ :remoteip => request.remote_ip,
17
+ :challenge => params[:recaptcha_challenge_field],
18
+ :response => params[:recaptcha_response_field]
19
+ })
20
+ rescue Exception => e
21
+ if Merb.env?(:production) || ENV['OFFLINE']
22
+ Merb.logger.error("when trying to connect to recaptcha, got #{e.message}")
23
+ return true;
24
+ else
25
+ raise
26
+ end
27
+ end
28
+ answer, error = response.body.split.map { |s| s.chomp }
29
+ if answer == "true"
30
+ true
31
+ else
32
+ Merb.logger.fatal("recaptcha error: #{error} for #{request.remote_ip}")
33
+ case error
34
+ when "incorrect-captcha-sol" then false
35
+ when "invalid-site-public-key" then raise Merb::Recaptcha::InvalidSitePublicKey
36
+ when "invalid-site-private-key" then raise Merb::Recaptcha::InvalidSitePrivateKey
37
+ when "invalid-request-cookie" then raise Merb::Recaptcha::InvalidRequestCookie
38
+ when "verify-params-incorrect" then raise Merb::Recaptcha::VerifyParamsIncorrect
39
+ when "invalid-referrer" then raise Merb::Recaptcha::InvalidReferrer
40
+ else
41
+ raise Merb::Recaptcha::GenericError
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ module Merb # :nodoc:
2
+ module Recaptcha
3
+ class GenericError < RuntimeError; end
4
+
5
+ # We weren't able to verify the public key.
6
+ # Possible solutions:
7
+ #
8
+ # * Did you swap the public and private key? It is important to use the correct one
9
+ # * Did you make sure to copy the entire key, with all hyphens and underscores, but without any spaces? The key should be exactly 40 letters long.
10
+ #
11
+ class InvalidSitePublicKey < GenericError; end
12
+
13
+ # We weren't able to verify the private key.
14
+ # Possible solutions:
15
+ #
16
+ # * Did you swap the public and private key? It is important to use the correct one
17
+ # * Did you make sure to copy the entire key, with all hyphens and underscores, but without any spaces? The key should be exactly 40 letters long.
18
+ #
19
+ class InvalidSitePrivateKey < GenericError; end
20
+
21
+ # The challenge parameter of the verify script was incorrect.
22
+ class InvalidRequestCookie < GenericError; end
23
+
24
+ # The parameters to /verify were incorrect, make sure you are passing all the required parameters.
25
+ class VerifyParamsIncorrect < GenericError; end
26
+
27
+ # reCAPTCHA API keys are tied to a specific domain name for security reasons.
28
+ class InvalidReferrer < GenericError; end
29
+ end
30
+ end
File without changes
@@ -0,0 +1,117 @@
1
+ require 'builder'
2
+
3
+ module Merb # :nodoc:
4
+ module Helpers # :nodoc:
5
+ module Recaptcha
6
+
7
+ # Display recaptcha widget in various ways.
8
+ #
9
+ # * Display in-place:
10
+ # <%= recaptcha_tags :ajax => false, :noscript => false %>
11
+ #
12
+ # * Display in-place with <noscript></noscript> block:
13
+ # <%= recaptcha_tags :ajax => false, :noscript => true, :iframe_height => 100, :iframe_width => 100 %>
14
+ #
15
+ # * Dynamically create Recaptcha widget:
16
+ # <%= recaptcha_tags :ajax => true, :element_id => "recaptcha_place" %>
17
+ # <div id="recaptcha_place"></div>
18
+ # The above code bind javascript code on onload event:
19
+ # <script type="text/javascript">
20
+ # ....
21
+ # window.onload = function() { Recaptcha.create(....); }
22
+ # ....
23
+ # </script>
24
+ # If you use jQuery, you could use special value for :ajax parameter:
25
+ # <%= recaptcha_tags :ajax => :jquery %>
26
+ # <div id="recpatcha"></div>
27
+ # This code generates following:
28
+ # <script type="text/javascript">
29
+ # ....
30
+ # $(document).ready(function() { Recaptcha.create(....); });
31
+ # ....
32
+ # </script>
33
+ # You can specified callback function that will be invoked after widget has been created:
34
+ # <%= recaptcha_tags :ajax => true, :callback => "Recaptcha.focus_response_field" %>
35
+ # <div id="recaptcha"></div>
36
+ # This code will set focus on response field of created widget.
37
+ #
38
+ # For both displaying ways, you can customize widget:
39
+ # <%= recaptcha_tags :theme => "clean", :tabindex => 2 %>
40
+ # More detailed description of customizing options is at http://recaptcha.net/apidocs/captcha/client.html
41
+ #
42
+ # Default values of options:
43
+ # * :ajax => false
44
+ # * :element_id => "recaptcha"
45
+ # * :callback => nil
46
+ # * :noscript => false
47
+ # * :iframe_height => 300
48
+ # * :iframe_width => 500
49
+ #
50
+ def recaptcha_tags(options = {})
51
+ public_key = Merb::Plugins.config[:merb_recaptcha][:public_key]
52
+
53
+ ajax = options.delete(:ajax) || false # boolean or :jquery
54
+ element_id = options.delete(:element_id) || "recaptcha" # string, html element id, only if ajax == true
55
+ callback = options.delete(:callback) # string, javascript function name, only if ajax == true
56
+ noscript = options.delete(:noscript) || false # boolean
57
+ iframe_height = options.delete(:iframe_height) || 300 # integer, only if noscript == true
58
+ iframe_width = options.delete(:iframe_width) || 500 # integer, only if noscript == true
59
+
60
+ api_url = if request.ssl?
61
+ Merb::Recaptcha::API_SECURE_SERVER
62
+ else
63
+ Merb::Recaptcha::API_SERVER
64
+ end
65
+
66
+ result = ""
67
+ xhtml = Builder::XmlMarkup.new(:target => result, :indent => 2)
68
+ if ajax
69
+ xhtml.script(:type => "text/javascript", :src => "#{api_url}/js/recaptcha_ajax.js") {}
70
+ xhtml.script(:type => "text/javascript") do |js|
71
+ options_and_callback = callback.nil? ? options : options.merge(:callback => callback)
72
+ js << "//<![CDATA[\n"
73
+ js << "var options = #{hash_to_json(options_and_callback)};\n"
74
+ if ajax == :jquery
75
+ js << "$(document).ready(function() { Recaptcha.create('#{public_key}', document.getElementById('#{element_id}'), options); });\n"
76
+ else
77
+ js << "window.onload = function() { Recaptcha.create('#{public_key}', document.getElementById('#{element_id}'), options); };\n"
78
+ end
79
+ js << "//]]>\n"
80
+ end
81
+ else
82
+ unless options.empty?
83
+ xhtml.script(:type => "text/javascript") do |js|
84
+ js << "//<![CDATA[\n"
85
+ js << "var RecaptchaOptions = #{hash_to_json(options)};\n"
86
+ js << "//]]>\n"
87
+ end
88
+ end
89
+ xhtml.script(:type => "text/javascript", :src => "#{api_url}/challenge?k=#{public_key}") {}
90
+ if noscript
91
+ xhtml.noscript do
92
+ xhtml.iframe(:src => "#{api_url}/noscript?k=#{public_key}", :height => iframe_height, :width => iframe_width, :frameborder => 0) {}
93
+ xhtml.br
94
+ xhtml.textarea(:name => "recaptcha_challenge_field", :rows => 3, :cols => 40) {}
95
+ xhtml.input :name => "recaptcha_response_field", :type => "hidden", :value => "manual_challenge"
96
+ end
97
+ end
98
+ end
99
+ result
100
+ end
101
+
102
+ private
103
+
104
+ def hash_to_json(hash)
105
+ result = "{"
106
+ result << hash.map do |k, v|
107
+ if ! v.is_a?(String) || k.to_s == "callback"
108
+ "\"#{k}\": #{v}"
109
+ else
110
+ "\"#{k}\": \"#{v}\""
111
+ end
112
+ end.join(", ")
113
+ result << "}"
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,44 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{merb-recaptcha}
5
+ s.version = "1.0.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Anton Ageev", "Michael Johnston"]
9
+ s.date = %q{2009-05-29}
10
+ s.description = %q{Merb plugin that provides helpers for recaptcha.net service}
11
+ s.email = %q{antage@gmail.com}
12
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
13
+ s.files = ["LICENSE", "README.rdoc", "Rakefile", "TODO", "merb-recaptcha.gemspec", "lib/merb-recaptcha/merbtasks.rb", "lib/merb-recaptcha/constants.rb", "lib/merb-recaptcha/exceptions.rb", "lib/merb-recaptcha/view_helpers.rb", "lib/merb-recaptcha/controller_mixin.rb", "lib/merb-recaptcha.rb", "spec/spec_helper.rb", "spec/recaptcha_ajax_with_callback_spec.rb", "spec/recaptcha_noajax_with_noscript_spec.rb", "spec/recaptcha_noajax_with_options_spec.rb", "spec/recaptcha_ajax_spec.rb", "spec/recaptcha_ajax_with_jquery_spec.rb", "spec/recaptcha_ajax_with_options_spec.rb", "spec/recaptcha_noajax_without_noscript_spec.rb", "spec/recaptcha_valid_spec.rb", "spec/fixture/app/views/layout/application.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_callback.html.erb", "spec/fixture/app/views/recaptcha/noajax_with_noscript.html.erb", "spec/fixture/app/views/recaptcha/ajax.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_jquery.html.erb", "spec/fixture/app/views/recaptcha/noajax_with_options.html.erb", "spec/fixture/app/views/recaptcha/noajax_without_noscript.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_options.html.erb", "spec/fixture/app/views/exceptions/not_acceptable.html.erb", "spec/fixture/app/views/exceptions/not_found.html.erb", "spec/fixture/app/controllers/exceptions.rb", "spec/fixture/app/controllers/application.rb", "spec/fixture/app/controllers/recaptcha.rb", "spec/fixture/app/helpers/recaptcha_helpers.rb", "spec/fixture/app/helpers/global_helpers.rb"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/antage/merb-recaptcha/}
16
+ s.rdoc_options = ["--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{merb-recaptcha}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Merb plugin that provides helpers for recaptcha.net service}
21
+ s.test_files = ["spec/spec_helper.rb", "spec/recaptcha_ajax_with_callback_spec.rb", "spec/recaptcha_noajax_with_noscript_spec.rb", "spec/recaptcha_noajax_with_options_spec.rb", "spec/recaptcha_ajax_spec.rb", "spec/recaptcha_ajax_with_jquery_spec.rb", "spec/recaptcha_ajax_with_options_spec.rb", "spec/recaptcha_noajax_without_noscript_spec.rb", "spec/recaptcha_valid_spec.rb", "spec/fixture/app/views/layout/application.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_callback.html.erb", "spec/fixture/app/views/recaptcha/noajax_with_noscript.html.erb", "spec/fixture/app/views/recaptcha/ajax.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_jquery.html.erb", "spec/fixture/app/views/recaptcha/noajax_with_options.html.erb", "spec/fixture/app/views/recaptcha/noajax_without_noscript.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_options.html.erb", "spec/fixture/app/views/exceptions/not_acceptable.html.erb", "spec/fixture/app/views/exceptions/not_found.html.erb", "spec/fixture/app/controllers/exceptions.rb", "spec/fixture/app/controllers/application.rb", "spec/fixture/app/controllers/recaptcha.rb", "spec/fixture/app/helpers/recaptcha_helpers.rb", "spec/fixture/app/helpers/global_helpers.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<merb-core>, [">= 1.0.0"])
29
+ s.add_runtime_dependency(%q<builder>, ["~> 2.0"])
30
+ s.add_development_dependency(%q<rspec>, [">= 1.1.0"])
31
+ s.add_development_dependency(%q<mocha>, [">= 0.9.3"])
32
+ else
33
+ s.add_dependency(%q<merb-core>, [">= 1.0.0"])
34
+ s.add_dependency(%q<builder>, ["~> 2.0"])
35
+ s.add_dependency(%q<rspec>, [">= 1.1.0"])
36
+ s.add_dependency(%q<mocha>, [">= 0.9.3"])
37
+ end
38
+ else
39
+ s.add_dependency(%q<merb-core>, [">= 1.0.0"])
40
+ s.add_dependency(%q<builder>, ["~> 2.0"])
41
+ s.add_dependency(%q<rspec>, [">= 1.1.0"])
42
+ s.add_dependency(%q<mocha>, [">= 0.9.3"])
43
+ end
44
+ end
@@ -0,0 +1,2 @@
1
+ class Application < Merb::Controller
2
+ end
@@ -0,0 +1,13 @@
1
+ class Exceptions < Merb::Controller
2
+
3
+ # handle NotFound exceptions (404)
4
+ def not_found
5
+ render :format => :html
6
+ end
7
+
8
+ # handle NotAcceptable exceptions (406)
9
+ def not_acceptable
10
+ render :format => :html
11
+ end
12
+
13
+ end
@@ -0,0 +1,29 @@
1
+ class Recaptcha < Application
2
+ def ajax
3
+ render
4
+ end
5
+
6
+ def ajax_with_jquery
7
+ render
8
+ end
9
+
10
+ def ajax_with_callback
11
+ render
12
+ end
13
+
14
+ def ajax_with_options
15
+ render
16
+ end
17
+
18
+ def noajax_without_noscript
19
+ render
20
+ end
21
+
22
+ def noajax_with_noscript
23
+ render
24
+ end
25
+
26
+ def noajax_with_options
27
+ render
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ module Merb
2
+ module GlobalHelpers
3
+ # helpers defined here available to all views.
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Merb
2
+ module RecaptchaHelper
3
+ end
4
+ end
@@ -0,0 +1,63 @@
1
+ <div id="container">
2
+ <div id="header-container">
3
+ <img src="/images/merb.jpg" />
4
+ <!-- <h1>Mongrel + Erb</h1> -->
5
+ <h2>pocket rocket web framework</h2>
6
+ <hr />
7
+ </div>
8
+
9
+ <div id="left-container">
10
+ <h3>Exception:</h3>
11
+ <p><%= request.exceptions.first.message %></p>
12
+ </div>
13
+
14
+ <div id="main-container">
15
+ <h3>Why am I seeing this page?</h3>
16
+ <p>Merb couldn't find an appropriate content_type to return,
17
+ based on what you said was available via provides() and
18
+ what the client requested.</p>
19
+
20
+ <h3>How to add a mime-type</h3>
21
+ <pre><code>
22
+ Merb.add_mime_type :pdf, :to_pdf, %w[application/pdf], &quot;Content-Encoding&quot; =&gt; &quot;gzip&quot;
23
+ </code></pre>
24
+ <h3>What this means is:</h3>
25
+ <ul>
26
+ <li>Add a mime-type for :pdf</li>
27
+ <li>Register the method for converting objects to PDF as <code>#to_pdf</code>.</li>
28
+ <li>Register the incoming mime-type "Accept" header as <code>application/pdf</code>.</li>
29
+ <li>Specify a new header for PDF types so it will set <code>Content-Encoding</code> to gzip.</li>
30
+ </ul>
31
+
32
+ <h3>You can then do:</h3>
33
+ <pre><code>
34
+ class Foo &lt; Application
35
+ provides :pdf
36
+ end
37
+ </code></pre>
38
+
39
+ <h3>Where can I find help?</h3>
40
+ <p>If you have any questions or if you can't figure something out, please take a
41
+ look at our <a href="http://merbivore.com/"> project page</a>,
42
+ feel free to come chat at irc.freenode.net, channel #merb,
43
+ or post to <a href="http://groups.google.com/group/merb">merb mailing list</a>
44
+ on Google Groups.</p>
45
+
46
+ <h3>What if I've found a bug?</h3>
47
+ <p>If you want to file a bug or make your own contribution to Merb,
48
+ feel free to register and create a ticket at our
49
+ <a href="http://merb.lighthouseapp.com/">project development page</a>
50
+ on Lighthouse.</p>
51
+
52
+ <h3>How do I edit this page?</h3>
53
+ <p>You can change what people see when this happens by editing <tt>app/views/exceptions/not_acceptable.html.erb</tt>.</p>
54
+
55
+ </div>
56
+
57
+ <div id="footer-container">
58
+ <hr />
59
+ <div class="left"></div>
60
+ <div class="right">&copy; 2008 the merb dev team</div>
61
+ <p>&nbsp;</p>
62
+ </div>
63
+ </div>
@@ -0,0 +1,47 @@
1
+ <div id="container">
2
+ <div id="header-container">
3
+ <img src="/images/merb.jpg" />
4
+ <!-- <h1>Mongrel + Erb</h1> -->
5
+ <h2>pocket rocket web framework</h2>
6
+ <hr />
7
+ </div>
8
+
9
+ <div id="left-container">
10
+ <h3>Exception:</h3>
11
+ <p><%= request.exceptions.first.message %></p>
12
+ </div>
13
+
14
+ <div id="main-container">
15
+ <h3>Welcome to Merb!</h3>
16
+ <p>Merb is a light-weight MVC framework written in Ruby. We hope you enjoy it.</p>
17
+
18
+ <h3>Where can I find help?</h3>
19
+ <p>If you have any questions or if you can't figure something out, please take a
20
+ look at our <a href="http://merbivore.com/"> project page</a>,
21
+ feel free to come chat at irc.freenode.net, channel #merb,
22
+ or post to <a href="http://groups.google.com/group/merb">merb mailing list</a>
23
+ on Google Groups.</p>
24
+
25
+ <h3>What if I've found a bug?</h3>
26
+ <p>If you want to file a bug or make your own contribution to Merb,
27
+ feel free to register and create a ticket at our
28
+ <a href="http://merb.lighthouseapp.com/">project development page</a>
29
+ on Lighthouse.</p>
30
+
31
+ <h3>How do I edit this page?</h3>
32
+ <p>You're seeing this page because you need to edit the following files:
33
+ <ul>
34
+ <li>config/router.rb <strong><em>(recommended)</em></strong></li>
35
+ <li>app/views/exceptions/not_found.html.erb <strong><em>(recommended)</em></strong></li>
36
+ <li>app/views/layout/application.html.erb <strong><em>(change this layout)</em></strong></li>
37
+ </ul>
38
+ </p>
39
+ </div>
40
+
41
+ <div id="footer-container">
42
+ <hr />
43
+ <div class="left"></div>
44
+ <div class="right">&copy; 2008 the merb dev team</div>
45
+ <p>&nbsp;</p>
46
+ </div>
47
+ </div>
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
3
+ <head>
4
+ <title>Fresh Merb App</title>
5
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
6
+ </head>
7
+ <body>
8
+ <%= catch_content :for_layout %>
9
+ </body>
10
+ </html>
@@ -0,0 +1,2 @@
1
+ <%= recaptcha_tags :ajax => true, :element_id => "recaptcha_without_callback" %>
2
+ <div id="recaptcha_without_callback"></div>
@@ -0,0 +1,2 @@
1
+ <%= recaptcha_tags :ajax => true, :element_id => "recaptcha_with_callback", :callback => "test_callback" %>
2
+ <div id="recaptcha_with_callback"></div>
@@ -0,0 +1,2 @@
1
+ <%= recaptcha_tags :ajax => :jquery, :element_id => "recaptcha_without_callback" %>
2
+ <div id="recaptcha_without_callback"></div>
@@ -0,0 +1,2 @@
1
+ <%= recaptcha_tags :ajax => true, :element_id => "recaptcha_without_callback", :theme => "clean", :tabindex => 2 %>
2
+ <div id="recaptcha_without_callback"></div>
@@ -0,0 +1 @@
1
+ <%= recaptcha_tags :ajax => false, :noscript => true, :iframe_height => 250, :iframe_width => 250 %>
@@ -0,0 +1 @@
1
+ <%= recaptcha_tags :ajax => false, :noscript => false, :theme => "clean", :tabindex => 2 %>
@@ -0,0 +1 @@
1
+ <%= recaptcha_tags :ajax => false, :noscript => false %>
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Recaptcha#ajax" do
4
+ describe "HTTP" do
5
+ before(:each) do
6
+ @response = dispatch_to(Recaptcha, "ajax")
7
+ end
8
+
9
+ it "should load script from api url" do
10
+ @response.should have_xpath("//script[@src='http://api.recaptcha.net/js/recaptcha_ajax.js']")
11
+ end
12
+
13
+ it "should invoke Recaptcha.create using onload event" do
14
+ @response.should have_xpath("//script[contains(., 'window.onload = function() { Recaptcha.create')]")
15
+ end
16
+
17
+ it "should send element_id ('recaptcha_without_callback')" do
18
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and contains(., \"getElementById('recaptcha_without_callback')\")]")
19
+ end
20
+
21
+ it "should create empty options array" do
22
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and contains(., 'var options = {};')]")
23
+ end
24
+
25
+ it_should_behave_like "ajax recaptcha"
26
+ end
27
+
28
+ describe "HTTPS" do
29
+ before(:each) do
30
+ @response = dispatch_to(Recaptcha, "ajax", {}, { "HTTPS" => "on" })
31
+ end
32
+
33
+ it "should load script from secure api url" do
34
+ @response.should have_xpath("//script[@src='https://api-secure.recaptcha.net/js/recaptcha_ajax.js']")
35
+ end
36
+
37
+ it_should_behave_like "ajax recaptcha"
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Recaptcha#ajax_with_callback" do
4
+ describe "HTTP" do
5
+ before(:each) do
6
+ @response = dispatch_to(Recaptcha, "ajax_with_callback")
7
+ end
8
+
9
+ it "should load script from api url" do
10
+ @response.should have_xpath("//script[@src='http://api.recaptcha.net/js/recaptcha_ajax.js']")
11
+ end
12
+
13
+ it "should send element_id ('recaptcha_with_callback')" do
14
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and contains(., \"getElementById('recaptcha_with_callback')\")]")
15
+ end
16
+
17
+ it "should create options array containing callback value ('test_callback')" do
18
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and contains(., 'var options = {\"callback\": test_callback};')]")
19
+ end
20
+
21
+ it_should_behave_like "ajax recaptcha"
22
+ end
23
+
24
+ describe "HTTPS" do
25
+ before(:each) do
26
+ @response = dispatch_to(Recaptcha, "ajax_with_callback", {}, { "HTTPS" => "on" })
27
+ end
28
+
29
+ it "should load script from secure api url" do
30
+ @response.should have_xpath("//script[@src='https://api-secure.recaptcha.net/js/recaptcha_ajax.js']")
31
+ end
32
+
33
+ it_should_behave_like "ajax recaptcha"
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Recaptcha#ajax_with_jquery" do
4
+ describe "HTTP" do
5
+ before(:each) do
6
+ @response = dispatch_to(Recaptcha, "ajax_with_jquery")
7
+ end
8
+
9
+ it "should load script from api url" do
10
+ @response.should have_xpath("//script[@src='http://api.recaptcha.net/js/recaptcha_ajax.js']")
11
+ end
12
+
13
+ it "should invoke Recaptcha.create using onload event" do
14
+ @response.should have_xpath("//script[contains(., '$(document).ready(function() { Recaptcha.create')]")
15
+ end
16
+
17
+ it "should send element_id ('recaptcha_without_callback')" do
18
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and contains(., \"getElementById('recaptcha_without_callback')\")]")
19
+ end
20
+
21
+ it "should create empty options array" do
22
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and contains(., 'var options = {};')]")
23
+ end
24
+
25
+ it_should_behave_like "ajax recaptcha"
26
+ end
27
+
28
+ describe "HTTPS" do
29
+ before(:each) do
30
+ @response = dispatch_to(Recaptcha, "ajax_with_jquery", {}, { "HTTPS" => "on" })
31
+ end
32
+
33
+ it "should load script from secure api url" do
34
+ @response.should have_xpath("//script[@src='https://api-secure.recaptcha.net/js/recaptcha_ajax.js']")
35
+ end
36
+
37
+ it_should_behave_like "ajax recaptcha"
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Recaptcha#ajax_with_options" do
4
+ describe "HTTP" do
5
+ before(:each) do
6
+ @response = dispatch_to(Recaptcha, "ajax_with_options")
7
+ end
8
+
9
+ it "should load script from api url" do
10
+ @response.should have_xpath("//script[@src='http://api.recaptcha.net/js/recaptcha_ajax.js']")
11
+ end
12
+
13
+ it "should send element_id ('recaptcha_without_callback')" do
14
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and contains(., \"getElementById('recaptcha_without_callback')\")]")
15
+ end
16
+
17
+ it "should create options array containing custom options (theme = 'clean', tabindex = 2)" do
18
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and (contains(., 'var options = {\"theme\": \"clean\", \"tabindex\": 2};') or contains(., 'var options = {\"tabindex\": 2, \"theme\": \"clean\"};'))]")
19
+ end
20
+
21
+ it_should_behave_like "ajax recaptcha"
22
+ end
23
+
24
+ describe "HTTPS" do
25
+ before(:each) do
26
+ @response = dispatch_to(Recaptcha, "ajax_with_options", {}, { "HTTPS" => "on" })
27
+ end
28
+
29
+ it "should load script from secure api url" do
30
+ @response.should have_xpath("//script[@src='https://api-secure.recaptcha.net/js/recaptcha_ajax.js']")
31
+ end
32
+
33
+ it_should_behave_like "ajax recaptcha"
34
+ end
35
+ end
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Recaptcha#noajax_with_noscript" do
4
+ describe "HTTP" do
5
+ before(:each) do
6
+ @response = dispatch_to(Recaptcha, "noajax_with_noscript")
7
+ end
8
+
9
+ it "should load script from api url" do
10
+ @response.should have_xpath("//script[@src='http://api.recaptcha.net/challenge?k=#{Merb::Plugins.config[:merb_recaptcha][:public_key]}']")
11
+ end
12
+
13
+ it "should not send private key to anything" do
14
+ @response.should_not have_xpath("//*[contains(., '#{Merb::Plugins.config[:merb_recaptcha][:private_key]}')]")
15
+ end
16
+
17
+ it "should not have RecaptchaOptions array initialization" do
18
+ @response.should_not have_xpath("//script[contains(., 'var RecaptchaOptions')]")
19
+ end
20
+
21
+ it "should have noscript element" do
22
+ @response.should have_xpath("//noscript")
23
+ end
24
+
25
+ it "should have iframe in noscript element" do
26
+ @response.should have_xpath("//noscript/iframe")
27
+ end
28
+
29
+ it "should have iframe with specified height and width (250x250)" do
30
+ @response.should have_xpath("//noscript/iframe[@height=250 and @width=250]")
31
+ end
32
+
33
+ it "should have br element in noscript element" do
34
+ @response.should have_xpath("//noscript/br")
35
+ end
36
+
37
+ it "should have textarea in noscript element" do
38
+ @response.should have_xpath("//noscript/textarea[@name='recaptcha_challenge_field']")
39
+ end
40
+
41
+ it "should have hidden input element in noscript element" do
42
+ @response.should have_xpath("//noscript/input[@name='recaptcha_response_field' and @type='hidden' and @value='manual_challenge']")
43
+ end
44
+ end
45
+
46
+ describe "HTTPS" do
47
+ before(:each) do
48
+ @response = dispatch_to(Recaptcha, "noajax_with_noscript", {}, { "HTTPS" => "on" })
49
+ end
50
+
51
+ it "should load script from secure api url" do
52
+ @response.should have_xpath("//script[@src='https://api-secure.recaptcha.net/challenge?k=#{Merb::Plugins.config[:merb_recaptcha][:public_key]}']")
53
+ end
54
+
55
+ it "should not send private key to anything" do
56
+ @response.should_not have_xpath("//*[contains(., '#{Merb::Plugins.config[:merb_recaptcha][:private_key]}')]")
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Recaptcha#noajax_with_options" do
4
+ describe "HTTP" do
5
+ before(:each) do
6
+ @response = dispatch_to(Recaptcha, "noajax_with_options")
7
+ end
8
+
9
+ it "should load script from api url" do
10
+ @response.should have_xpath("//script[@src='http://api.recaptcha.net/challenge?k=#{Merb::Plugins.config[:merb_recaptcha][:public_key]}']")
11
+ end
12
+
13
+ it "should not send private key to anything" do
14
+ @response.should_not have_xpath("//*[contains(., '#{Merb::Plugins.config[:merb_recaptcha][:private_key]}')]")
15
+ end
16
+
17
+ it "should not have noscript element" do
18
+ @response.should_not have_xpath("//noscript")
19
+ end
20
+
21
+ it "should have RecaptchaOptions array intialization (theme = 'clean', tabindex = 2)" do
22
+ @response.should have_xpath("//script[contains(., 'var RecaptchaOptions = {\"theme\": \"clean\", \"tabindex\": 2};') or contains(., 'var RecaptchaOptions = {\"tabindex\": 2, \"theme\": \"clean\"};')]")
23
+ end
24
+ end
25
+
26
+ describe "HTTPS" do
27
+ before(:each) do
28
+ @response = dispatch_to(Recaptcha, "noajax_with_options", {}, { "HTTPS" => "on" })
29
+ end
30
+
31
+ it "should load script from secure api url" do
32
+ @response.should have_xpath("//script[@src='https://api-secure.recaptcha.net/challenge?k=#{Merb::Plugins.config[:merb_recaptcha][:public_key]}']")
33
+ end
34
+
35
+ it "should not send private key to anything" do
36
+ @response.should_not have_xpath("//*[contains(., '#{Merb::Plugins.config[:merb_recaptcha][:private_key]}')]")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Recaptcha#noajax_without_noscript" do
4
+ describe "HTTP" do
5
+ before(:each) do
6
+ @response = dispatch_to(Recaptcha, "noajax_without_noscript")
7
+ end
8
+
9
+ it "should load script from api url" do
10
+ @response.should have_xpath("//script[@src='http://api.recaptcha.net/challenge?k=#{Merb::Plugins.config[:merb_recaptcha][:public_key]}']")
11
+ end
12
+
13
+ it "should not send private key to anything" do
14
+ @response.should_not have_xpath("//*[contains(., '#{Merb::Plugins.config[:merb_recaptcha][:private_key]}')]")
15
+ end
16
+
17
+ it "should not have noscript element" do
18
+ @response.should_not have_xpath("//noscript")
19
+ end
20
+
21
+ it "should not have RecaptchaOptions array initialization" do
22
+ @response.should_not have_xpath("//script[contains(., 'var RecaptchaOptions')]")
23
+ end
24
+ end
25
+
26
+ describe "HTTPS" do
27
+ before(:each) do
28
+ @response = dispatch_to(Recaptcha, "noajax_without_noscript", {}, { "HTTPS" => "on" })
29
+ end
30
+
31
+ it "should load script from secure api url" do
32
+ @response.should have_xpath("//script[@src='https://api-secure.recaptcha.net/challenge?k=#{Merb::Plugins.config[:merb_recaptcha][:public_key]}']")
33
+ end
34
+
35
+ it "should not send private key to anything" do
36
+ @response.should_not have_xpath("//*[contains(., '#{Merb::Plugins.config[:merb_recaptcha][:private_key]}')]")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,125 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ class FakeController < Merb::Controller
4
+ def check_recaptcha
5
+ return recaptcha_valid?.to_s
6
+ end
7
+ end
8
+
9
+ describe "FakeController#check_recaptcha" do
10
+ def do_request(ssl = false)
11
+ @response = dispatch_to(FakeController, :check_recaptcha, { :recaptcha_challenge_field => "blabla", :recaptcha_response_field => "blabla" }, { "HTTPS" => ssl ? "on" : "off" })
12
+ end
13
+
14
+ def stub_response(body)
15
+ Net::HTTP.stubs(:post_form).returns stub("Net::HTTPResponse", :body => body)
16
+ end
17
+
18
+ describe "with non-SSL request" do
19
+ it "should use non-ssl API server" do
20
+ cond = proc { |*args| args.first.is_a?(URI::HTTP) && args.first.scheme == "http" && args.first.host == "api-verify.recaptcha.net" }
21
+ Net::HTTP.expects(:post_form).with(&cond).returns(stub("Net::HTTPResponse", :body => "true"))
22
+ do_request(false)
23
+ end
24
+ end
25
+
26
+ describe "with SSL request" do
27
+ it "should use non-ssl API server" do
28
+ cond = proc { |*args| args.first.is_a?(URI::HTTP) && args.first.scheme == "http" && args.first.host == "api-verify.recaptcha.net" }
29
+ Net::HTTP.expects(:post_form).with(&cond).returns(stub("Net::HTTPResponse", :body => "true"))
30
+ do_request(true)
31
+ end
32
+ end
33
+
34
+ describe "with correct response" do
35
+ before(:each) do
36
+ stub_response("true\n")
37
+ end
38
+
39
+ it "should render 'true'" do
40
+ do_request
41
+ @response.should have_selector("*:contains('true')")
42
+ end
43
+
44
+ it "should not raise any exception" do
45
+ lambda { do_request }.should_not raise_error
46
+ end
47
+ end
48
+
49
+ describe "with incorrect response" do
50
+ before(:each) do
51
+ stub_response("false\nincorrect-captcha-sol\n")
52
+ end
53
+
54
+ it "should render 'false'" do
55
+ do_request
56
+ @response.should have_selector("*:contains('false')")
57
+ end
58
+
59
+ it "should not raise any exception" do
60
+ lambda { do_request }.should_not raise_error
61
+ end
62
+ end
63
+
64
+ describe "with incorrect public key" do
65
+ before(:each) do
66
+ stub_response("false\ninvalid-site-public-key\n")
67
+ end
68
+
69
+ it "should raise Merb::Recaptcha::InvalidSitePublicKey" do
70
+ lambda { do_request }.should raise_error(Merb::Recaptcha::InvalidSitePublicKey)
71
+ end
72
+ end
73
+
74
+ describe "with incorrect private key" do
75
+ before(:each) do
76
+ stub_response("false\ninvalid-site-private-key\n")
77
+ end
78
+
79
+ it "should raise Merb::Recaptcha::InvalidSitePrivateKey" do
80
+ lambda { do_request }.should raise_error(Merb::Recaptcha::InvalidSitePrivateKey)
81
+ end
82
+ end
83
+
84
+ describe "with invalid request cookie" do
85
+ before(:each) do
86
+ stub_response("false\ninvalid-request-cookie\n")
87
+ end
88
+
89
+ it "should raise Merb::Recaptcha::InvalidRequestCookie" do
90
+ lambda { do_request }.should raise_error(Merb::Recaptcha::InvalidRequestCookie)
91
+ end
92
+ end
93
+
94
+ describe "with verify parameters incorrect" do
95
+ before(:each) do
96
+ stub_response("false\nverify-params-incorrect\n")
97
+ end
98
+
99
+ it "should raise Merb::Recaptcha::VerifyParamsIncorrect" do
100
+ lambda { do_request }.should raise_error(Merb::Recaptcha::VerifyParamsIncorrect)
101
+ end
102
+ end
103
+
104
+ describe "with invalid referrer" do
105
+ before(:each) do
106
+ stub_response("false\ninvalid-referrer\n")
107
+ end
108
+
109
+ it "should raise Merb::Recaptcha::IvalidReferrer" do
110
+ lambda { do_request }.should raise_error(Merb::Recaptcha::InvalidReferrer)
111
+ end
112
+ end
113
+
114
+ describe "when can't connect to recaptcha" do
115
+ before(:each) do
116
+ Net::HTTP.stubs(:post_form).times(2).raises(Exception, "can't connect to recaptcha")
117
+ end
118
+
119
+ it "should pass through if env var OFFLINE is set" do
120
+ lambda { do_request }.should raise_error(Exception)
121
+ ENV['OFFLINE'] = '1'
122
+ lambda { do_request }.should_not raise_error
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'merb-core'
4
+
5
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
6
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'merb-recaptcha')
7
+
8
+ default_options = {
9
+ :testing => true,
10
+ :adapter => 'runner',
11
+ :merb_root => File.dirname(__FILE__) / 'fixture',
12
+ :log_stream => STDOUT
13
+ }
14
+ options = default_options.merge($START_OPTIONS || {})
15
+
16
+ Merb.disable(:initfile)
17
+ Merb::BootLoader.after_app_loads do
18
+ Merb::Plugins.config[:merb_recaptcha][:public_key] = "QAAAAAA--public-key--AAAAAAQ"
19
+ Merb::Plugins.config[:merb_recaptcha][:private_key] = "QAAAAAA--private-key--AAAAAAAQ"
20
+
21
+ Merb::Router.prepare { default_routes }
22
+ Merb::RecaptchaMixin.const_set(:DO_NOT_IGNORE_RECAPTCHA_IN_TESTING_ENV, true)
23
+ end
24
+ Merb.start_environment(options)
25
+
26
+ Spec::Runner.configure do |config|
27
+ config.include Merb::Test::ViewHelper
28
+ config.include Merb::Test::RouteHelper
29
+ config.include Merb::Test::ControllerHelper
30
+
31
+ config.mock_with :mocha
32
+ end
33
+
34
+ describe "ajax recaptcha", :shared => true do
35
+ it "should invoke Recaptcha.create" do
36
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create')]")
37
+ end
38
+
39
+ it "should send public key to Recaptcha.create" do
40
+ @response.should have_xpath("//script[contains(., 'Recaptcha.create') and contains(., '#{Merb::Plugins.config[:merb_recaptcha][:public_key]}')]")
41
+ end
42
+
43
+ it "should not send private key to anything" do
44
+ @response.should_not have_xpath("//*[contains(., '#{Merb::Plugins.config[:merb_recaptcha][:private_key]}')]")
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: merb-recaptcha
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Anton Ageev
8
+ - Michael Johnston
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-10-08 00:00:00 +04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: merb-core
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.0.0
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: builder
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: "2.0"
35
+ version:
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ type: :development
39
+ version_requirement:
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 1.1.0
45
+ version:
46
+ - !ruby/object:Gem::Dependency
47
+ name: mocha
48
+ type: :development
49
+ version_requirement:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.3
55
+ version:
56
+ description: Merb plugin that provides helpers for recaptcha.net service
57
+ email: antage@gmail.com
58
+ executables: []
59
+
60
+ extensions: []
61
+
62
+ extra_rdoc_files:
63
+ - README.rdoc
64
+ - LICENSE
65
+ files:
66
+ - LICENSE
67
+ - README.rdoc
68
+ - Rakefile
69
+ - TODO
70
+ - merb-recaptcha.gemspec
71
+ - lib/merb-recaptcha/merbtasks.rb
72
+ - lib/merb-recaptcha/constants.rb
73
+ - lib/merb-recaptcha/exceptions.rb
74
+ - lib/merb-recaptcha/view_helpers.rb
75
+ - lib/merb-recaptcha/controller_mixin.rb
76
+ - lib/merb-recaptcha.rb
77
+ has_rdoc: true
78
+ homepage: http://github.com/antage/merb-recaptcha/
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options:
83
+ - --main
84
+ - README.rdoc
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ version:
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ requirements: []
100
+
101
+ rubyforge_project: merb-recaptcha
102
+ rubygems_version: 1.3.5
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Merb plugin that provides helpers for recaptcha.net service
106
+ test_files:
107
+ - spec/spec_helper.rb
108
+ - spec/recaptcha_ajax_with_callback_spec.rb
109
+ - spec/recaptcha_noajax_with_noscript_spec.rb
110
+ - spec/recaptcha_noajax_with_options_spec.rb
111
+ - spec/recaptcha_ajax_spec.rb
112
+ - spec/recaptcha_ajax_with_jquery_spec.rb
113
+ - spec/recaptcha_ajax_with_options_spec.rb
114
+ - spec/recaptcha_noajax_without_noscript_spec.rb
115
+ - spec/recaptcha_valid_spec.rb
116
+ - spec/fixture/app/views/layout/application.html.erb
117
+ - spec/fixture/app/views/recaptcha/ajax_with_callback.html.erb
118
+ - spec/fixture/app/views/recaptcha/noajax_with_noscript.html.erb
119
+ - spec/fixture/app/views/recaptcha/ajax.html.erb
120
+ - spec/fixture/app/views/recaptcha/ajax_with_jquery.html.erb
121
+ - spec/fixture/app/views/recaptcha/noajax_with_options.html.erb
122
+ - spec/fixture/app/views/recaptcha/noajax_without_noscript.html.erb
123
+ - spec/fixture/app/views/recaptcha/ajax_with_options.html.erb
124
+ - spec/fixture/app/views/exceptions/not_acceptable.html.erb
125
+ - spec/fixture/app/views/exceptions/not_found.html.erb
126
+ - spec/fixture/app/controllers/exceptions.rb
127
+ - spec/fixture/app/controllers/application.rb
128
+ - spec/fixture/app/controllers/recaptcha.rb
129
+ - spec/fixture/app/helpers/recaptcha_helpers.rb
130
+ - spec/fixture/app/helpers/global_helpers.rb