merb-recaptcha 1.0.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.
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