bot-away 1.2.0 → 2.0.0
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.
- data/.travis.yml +14 -0
- data/History.txt +20 -0
- data/README.md +198 -0
- data/Rakefile +14 -94
- data/bot-away.gemspec +20 -87
- data/gemfiles/Gemfile.rails-3.0.x +8 -0
- data/gemfiles/Gemfile.rails-3.0.x.lock +121 -0
- data/gemfiles/Gemfile.rails-3.1.x +8 -0
- data/gemfiles/Gemfile.rails-3.1.x.lock +133 -0
- data/lib/bot-away.rb +15 -13
- data/lib/bot-away/action_dispatch/params_parser.rb +22 -0
- data/lib/bot-away/action_view/helpers/instance_tag.rb +36 -12
- data/lib/bot-away/param_parser.rb +2 -2
- data/lib/bot-away/railtie.rb +10 -0
- data/lib/bot-away/test_case.rb +58 -0
- data/lib/bot-away/test_case/controller_test_case.rb +11 -0
- data/lib/bot-away/test_case/instance_tag_test_case.rb +15 -0
- data/lib/bot-away/test_case/matchers.rb +20 -0
- data/lib/bot-away/test_case/matchers/honeypot_matcher.rb +30 -0
- data/lib/bot-away/test_case/matchers/obfuscation_matcher.rb +30 -0
- data/lib/bot-away/test_case/mock_object.rb +16 -0
- data/lib/bot-away/version.rb +12 -0
- data/lib/locale/honeypots.yml +6 -0
- data/spec/controllers/basic_form_view_spec.rb +112 -0
- data/spec/controllers/{test_controller_spec.rb → tests_controller_spec.rb} +29 -80
- data/spec/integration/params_post_spec.rb +42 -0
- data/spec/lib/action_view/helpers/instance_tag_spec.rb +94 -0
- data/spec/{views/lib → lib/action_view}/param_parser_spec.rb +10 -10
- data/spec/spec_helper.rb +37 -105
- data/spec/test_rails_app/app/controllers/tests_controller.rb +11 -0
- data/spec/test_rails_app/app/models/post.rb +13 -0
- data/spec/test_rails_app/app/views/tests/basic_form.html.erb +5 -0
- data/spec/test_rails_app/app/views/tests/model_form.html.erb +12 -0
- data/spec/test_rails_app/config/locales/bot-away-overrides.yml +6 -0
- data/spec/views/form_builder_spec.rb +118 -0
- metadata +94 -137
- data/Manifest.txt +0 -23
- data/README.rdoc +0 -179
- data/VERSION +0 -1
- data/lib/bot-away/action_dispatch/request.rb +0 -20
- data/spec/rspec_version.rb +0 -19
- data/spec/support/honeypot_matcher.rb +0 -30
- data/spec/support/obfuscation_helper.rb +0 -123
- data/spec/support/obfuscation_matcher.rb +0 -28
- data/spec/support/rails/mock_logger.rb +0 -21
- data/spec/support/test_controller.rb +0 -28
- data/spec/support/views/test/index.html.erb +0 -4
- data/spec/support/views/test/model_form.html.erb +0 -6
- data/spec/views/lib/action_view/helpers/instance_tag_spec.rb +0 -75
- data/spec/views/lib/disabled_for_spec.rb +0 -101
- data/spec/views/lib/form_builder_spec.rb +0 -56
@@ -15,7 +15,6 @@ module BotAway
|
|
15
15
|
|
16
16
|
if authenticity_token
|
17
17
|
if catch(:bastard) { deobfuscate! } == :took_the_bait
|
18
|
-
#params.clear
|
19
18
|
# don't clear the controller or action keys, as Rails 3 needs them
|
20
19
|
params.keys.each { |key| params.delete(key) unless %w(controller action).include?(key) }
|
21
20
|
params[:suspected_bot] = true
|
@@ -35,7 +34,8 @@ module BotAway
|
|
35
34
|
deobfuscate!(value, object_name ? "#{object_name}[#{key}]" : key)
|
36
35
|
else
|
37
36
|
if object_name && !BotAway.excluded?(:object_name => object_name, :method_name => key)
|
38
|
-
|
37
|
+
spun_key = spinner.encode("#{object_name}[#{key}]")
|
38
|
+
if value.blank? && params.keys.include?(spun_key)
|
39
39
|
current[key] = params.delete(spun_key)
|
40
40
|
else
|
41
41
|
#puts "throwing on #{object_name}[#{key}] because its not blank" if !value.blank?
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails/engine'
|
2
|
+
require 'rails/version'
|
3
|
+
|
4
|
+
class BotAway::Railtie < Rails::Engine
|
5
|
+
if Rails::VERSION::MINOR == 0 # Rails 3.0.x
|
6
|
+
paths.config.locales = File.expand_path("../locale/honeypots.yml", File.dirname(__FILE__))
|
7
|
+
else
|
8
|
+
paths["config/locales"] = File.expand_path("../locale/honeypots.yml", File.dirname(__FILE__))
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module BotAway::TestCase
|
2
|
+
autoload :ControllerTestCase, 'bot-away/test_case/controller_test_case'
|
3
|
+
autoload :InstanceTagTestCase, 'bot-away/test_case/instance_tag_test_case'
|
4
|
+
autoload :MockObject, 'bot-away/test_case/mock_object'
|
5
|
+
autoload :Matchers, 'bot-away/test_case/matchers'
|
6
|
+
|
7
|
+
def builder
|
8
|
+
@builder ||= ActionView::Base.default_form_builder.new(object_name, mock_object, view, {}, proc {})
|
9
|
+
end
|
10
|
+
|
11
|
+
def enable_forgery_protection
|
12
|
+
# BotAway doesn't work without forgery protection, and RSpec-Rails 2 disables it.
|
13
|
+
# Lost way too many hours on this.
|
14
|
+
# Note: This has to happen in spec file because RSpec2 sets a before block, which runs
|
15
|
+
# after the ones set by config.
|
16
|
+
Rails.application.config.allow_forgery_protection = true
|
17
|
+
ActionController::Base.allow_forgery_protection = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def disable_forgery_protection
|
21
|
+
Rails.application.config.allow_forgery_protection = false
|
22
|
+
ActionController::Base.allow_forgery_protection = false
|
23
|
+
end
|
24
|
+
|
25
|
+
def mock_object
|
26
|
+
@mock_object ||= MockObject.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def obfuscated_id
|
30
|
+
"f51a02a636f507f1bd64722451b71297"
|
31
|
+
end
|
32
|
+
|
33
|
+
def obfuscated_name
|
34
|
+
"cd538a9170613d6dedbcc54a0aa24881"
|
35
|
+
end
|
36
|
+
|
37
|
+
def object_name
|
38
|
+
"object_name"
|
39
|
+
end
|
40
|
+
|
41
|
+
def method_name
|
42
|
+
"method_name"
|
43
|
+
end
|
44
|
+
|
45
|
+
def tag_id
|
46
|
+
"#{object_name}_#{method_name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def tag_name
|
50
|
+
"#{object_name}[#{method_name}]"
|
51
|
+
end
|
52
|
+
|
53
|
+
def dump
|
54
|
+
result = yield
|
55
|
+
puts result if ENV['DUMP']
|
56
|
+
result
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module BotAway::TestCase::ControllerTestCase
|
2
|
+
# note that this only matters for TEST requests; real ones use the params parser.
|
3
|
+
module ::ActionController::TestCase::Behavior
|
4
|
+
def process_with_deobfuscation(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
|
5
|
+
parameters = BotAway::ParamParser.new(request.ip, (parameters || {}).with_indifferent_access).params
|
6
|
+
process_without_deobfuscation(action, parameters, session, flash, http_method)
|
7
|
+
end
|
8
|
+
|
9
|
+
alias_method_chain :process, :deobfuscation
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module BotAway::TestCase::InstanceTagTestCase
|
2
|
+
def self.included(base)
|
3
|
+
base.module_eval do
|
4
|
+
include RSpec::Rails::ViewExampleGroup
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def mock_object
|
9
|
+
@mock_object ||= BotAway::TestCase::MockObject.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_instance_tag
|
13
|
+
@default_instance_tag ||= ActionView::Helpers::InstanceTag.new("object_name", "method_name", view, mock_object)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module BotAway::TestCase::Matchers
|
2
|
+
autoload :ObfuscationMatcher, 'bot-away/test_case/matchers/obfuscation_matcher'
|
3
|
+
autoload :HoneypotMatcher, 'bot-away/test_case/matchers/honeypot_matcher'
|
4
|
+
|
5
|
+
def be_obfuscated_as(obfuscated_name, obfuscated_id)
|
6
|
+
ObfuscationMatcher.new(obfuscated_name, obfuscated_id)
|
7
|
+
end
|
8
|
+
|
9
|
+
def include_honeypot_called(tag_name, tag_id)
|
10
|
+
HoneypotMatcher.new(tag_name, tag_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
def be_obfuscated
|
14
|
+
be_obfuscated_as obfuscated_name, obfuscated_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def include_honeypot
|
18
|
+
include_honeypot_called tag_name, tag_id
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class BotAway::TestCase::Matchers::HoneypotMatcher
|
2
|
+
attr_reader :tag_name, :tag_id
|
3
|
+
|
4
|
+
def initialize(tag_name, tag_id)
|
5
|
+
@tag_name, @tag_id = tag_name, tag_id
|
6
|
+
end
|
7
|
+
|
8
|
+
def matches?(target)
|
9
|
+
target = target.call if target.kind_of?(Proc)
|
10
|
+
@target = target
|
11
|
+
match(:id, tag_id) && match(:name, tag_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def match(key, value, suffix = nil)
|
15
|
+
@rx = /#{key}=['"]#{Regexp::escape value}["']/
|
16
|
+
@target[@rx]
|
17
|
+
end
|
18
|
+
|
19
|
+
def description
|
20
|
+
"include a honeypot named '#{tag_name}' with id '#{tag_id}'"
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure_message
|
24
|
+
"expected #{@target.inspect}\n to match #{@rx.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def negative_failure_message
|
28
|
+
"expected #{@target.inspect}\n to not match #{@rx.inspect}"
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class BotAway::TestCase::Matchers::ObfuscationMatcher
|
2
|
+
attr_reader :obfuscated_name, :obfuscated_id
|
3
|
+
|
4
|
+
def initialize(obfuscated_name, obfuscated_id)
|
5
|
+
@obfuscated_id, @obfuscated_name = obfuscated_id, obfuscated_name
|
6
|
+
end
|
7
|
+
|
8
|
+
def matches?(target)
|
9
|
+
target = target.call if target.kind_of?(Proc)
|
10
|
+
@target = target
|
11
|
+
match(:id, obfuscated_id) && match(:name, obfuscated_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def match(key, value)
|
15
|
+
@rx = /#{key}=['"]#{Regexp::escape value}["']/
|
16
|
+
@target[@rx]
|
17
|
+
end
|
18
|
+
|
19
|
+
def description
|
20
|
+
"be obfuscated as '#{obfuscated_name}' with id '#{obfuscated_id}'"
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure_message
|
24
|
+
"expected #{@target.inspect}\n to match #{@rx.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def negative_failure_message
|
28
|
+
"expected #{@target.inspect}\n to not match #{@rx.inspect}"
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# For all intents and purposes this is a view spec, but because rspec mocks up the controller
|
4
|
+
# in view specs (and rightly so!), we need to technically run it as a controller spec in order
|
5
|
+
# to invoke a real controller first.
|
6
|
+
describe TestsController do
|
7
|
+
include BotAway::TestCase::ControllerTestCase
|
8
|
+
render_views
|
9
|
+
before { enable_forgery_protection }
|
10
|
+
|
11
|
+
let(:params) { { :controller => 'tests', :action => 'basic_form' } }
|
12
|
+
|
13
|
+
it "should use forgery protection" do # sanity check
|
14
|
+
subject.send(:protect_against_forgery?).should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
shared_examples_for "enabled" do
|
18
|
+
it "returns false when queried for disablement" do
|
19
|
+
BotAway.should_not be_disabled_for(params)
|
20
|
+
BotAway.should_not be_excluded(params)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "obfuscates the elements" do
|
24
|
+
get 'basic_form'
|
25
|
+
response.body.should =~ /id="c89ca970ba19a4174d332aa8cfbd0c42"/ # user_login
|
26
|
+
response.body.should =~ /id="f41749ab8ef9d2358cfd170fd9af2f5e"/ # user_password
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
shared_examples_for "disabled" do
|
31
|
+
it "returns true when queried for disablement" do
|
32
|
+
# ..."disablement"?
|
33
|
+
BotAway.should be_disabled_for(params)
|
34
|
+
BotAway.should be_excluded(params)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "does not obfuscate the elements" do
|
38
|
+
get 'basic_form'
|
39
|
+
response.body.should_not =~ /id="c89ca970ba19a4174d332aa8cfbd0c42"/ # user_login
|
40
|
+
response.body.should_not =~ /id="f41749ab8ef9d2358cfd170fd9af2f5e"/ # user_password
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with bot-away disabled for only this view" do
|
45
|
+
before { BotAway.disabled_for({:controller => 'tests', :action => 'basic_form'}) }
|
46
|
+
it_should_behave_like "disabled"
|
47
|
+
end
|
48
|
+
|
49
|
+
context "with bot-away enabled for all views" do
|
50
|
+
it_should_behave_like "enabled"
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
context "with matching controller name" do
|
58
|
+
context "and no action" do
|
59
|
+
before { BotAway.disabled_for :controller => 'tests' }
|
60
|
+
it_should_behave_like "disabled"
|
61
|
+
end
|
62
|
+
|
63
|
+
context "and matching action" do
|
64
|
+
before { BotAway.disabled_for :controller => 'tests', :action => 'basic_form' }
|
65
|
+
it_should_behave_like "disabled"
|
66
|
+
end
|
67
|
+
|
68
|
+
context "and not matching action" do
|
69
|
+
before { BotAway.disabled_for :controller => 'tests', :action => 'create' }
|
70
|
+
it_should_behave_like "enabled"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "with not matching controller name" do
|
75
|
+
context "and no action" do
|
76
|
+
before { BotAway.disabled_for :controller => 'users' }
|
77
|
+
it_should_behave_like "enabled"
|
78
|
+
end
|
79
|
+
|
80
|
+
context "and matching action" do
|
81
|
+
before { BotAway.disabled_for :controller => 'users', :action => 'basic_form' }
|
82
|
+
it_should_behave_like "enabled"
|
83
|
+
end
|
84
|
+
|
85
|
+
context "and not matching action" do
|
86
|
+
before { BotAway.disabled_for :controller => 'users', :action => 'create' }
|
87
|
+
it_should_behave_like "enabled"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "with no controller name" do
|
92
|
+
context "and matching action" do
|
93
|
+
before { BotAway.disabled_for :action => 'basic_form' }
|
94
|
+
it_should_behave_like "disabled"
|
95
|
+
end
|
96
|
+
|
97
|
+
context "and not matching action" do
|
98
|
+
before { BotAway.disabled_for :action => 'create' }
|
99
|
+
it_should_behave_like "enabled"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "with matching mode" do
|
104
|
+
before { BotAway.disabled_for :mode => ENV['RAILS_ENV'] }
|
105
|
+
it_should_behave_like "disabled"
|
106
|
+
end
|
107
|
+
|
108
|
+
context "with not matching mode" do
|
109
|
+
before { BotAway.disabled_for :mode => "this_is_not_#{ENV['RAILS_ENV']}" }
|
110
|
+
it_should_behave_like "enabled"
|
111
|
+
end
|
112
|
+
end
|
@@ -1,88 +1,42 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
# rails 2
|
6
|
-
|
7
|
-
def setup_default_controller
|
8
|
-
@request = ActionController::TestRequest.new
|
9
|
-
# can the authenticity token so that we can predict the generated element names
|
10
|
-
@request.session[:_csrf_token] = 'aVjGViz+pIphXt2pxrWfXgRXShOI0KXOILR23yw0WBo='
|
11
|
-
@request.remote_addr = '208.77.188.166' # example.com
|
12
|
-
@response = ActionController::TestResponse.new
|
13
|
-
@controller = TestController.new
|
14
|
-
|
15
|
-
@controller.request = @request
|
16
|
-
@controller.params = {}
|
17
|
-
@controller.send(:initialize_current_url)
|
18
|
-
@controller
|
19
|
-
end
|
20
|
-
|
21
|
-
include ActionController::TestProcess
|
22
|
-
|
23
|
-
def controller
|
24
|
-
@controller
|
25
|
-
end
|
26
|
-
else
|
27
|
-
# rails 3
|
28
|
-
def setup_default_controller
|
29
|
-
@controller.request.session[:_csrf_token] = 'aVjGViz+pIphXt2pxrWfXgRXShOI0KXOILR23yw0WBo='
|
30
|
-
@controller.request.remote_addr = '208.77.188.166'
|
31
|
-
|
32
|
-
@controller
|
33
|
-
end
|
34
|
-
|
35
|
-
#extend ActiveSupport::Concern
|
36
|
-
#include ActionController::TestCase::Behavior
|
37
|
-
delegate :session, :to => :controller
|
38
|
-
end
|
39
|
-
|
40
|
-
def prepare!(action = 'index', method = 'get')
|
41
|
-
controller
|
42
|
-
send(method, action)
|
43
|
-
if RAILS_VERSION < "3.0"
|
44
|
-
if @response.template.instance_variable_get("@exception")
|
45
|
-
raise @response.template.instance_variable_get("@exception")
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
before(:each) { setup_default_controller }
|
3
|
+
describe TestsController do
|
4
|
+
include BotAway::TestCase::ControllerTestCase
|
51
5
|
|
52
|
-
|
53
|
-
|
54
|
-
|
6
|
+
before do
|
7
|
+
disable_forgery_protection
|
8
|
+
request.session[:_csrf_token] = 'aVjGViz+pIphXt2pxrWfXgRXShOI0KXOILR23yw0WBo='
|
9
|
+
request.remote_addr = '208.77.188.166'
|
55
10
|
end
|
56
|
-
|
57
11
|
|
58
12
|
context "with a model" do
|
13
|
+
render_views
|
14
|
+
|
59
15
|
context "with forgery protection" do
|
60
|
-
before
|
61
|
-
|
62
|
-
|
16
|
+
before do
|
17
|
+
enable_forgery_protection
|
18
|
+
get 'model_form'
|
63
19
|
end
|
64
20
|
|
65
21
|
it "should work?" do
|
66
|
-
|
22
|
+
response.body.should =~ /<select/
|
67
23
|
end
|
68
24
|
end
|
69
25
|
|
70
26
|
context "without forgery protection" do
|
71
|
-
before
|
72
|
-
|
27
|
+
before do
|
28
|
+
get 'model_form'
|
73
29
|
end
|
74
30
|
|
75
31
|
it "should work?" do
|
76
|
-
|
32
|
+
response.body.should =~ /<select/
|
77
33
|
end
|
78
34
|
end
|
79
35
|
end
|
80
36
|
|
81
37
|
context "with forgery protection" do
|
82
|
-
before
|
83
|
-
|
84
|
-
prepare! if RAILS_VERSION < "3.0"
|
85
|
-
end
|
38
|
+
before { enable_forgery_protection }
|
39
|
+
|
86
40
|
#"object_name_method_name" name="object_name[method_name]" size="30" type="text" value="" /></div>
|
87
41
|
#<input id="e21372563297c728093bf74c3cb6b96c" name="a0844d45bf150668ff1d86a6eb491969" size="30" type="text" value="method_value" />
|
88
42
|
|
@@ -92,12 +46,12 @@ describe TestController do
|
|
92
46
|
'842d8d1c80014ce9f3d974614338605c' => 'some_value'
|
93
47
|
}
|
94
48
|
post 'proc_form', form
|
95
|
-
#puts
|
49
|
+
#puts response.body
|
96
50
|
controller.params[:object_name].should == { 'method_name' => 'some_value' }
|
97
51
|
end
|
98
52
|
|
99
53
|
context "after processing valid obfuscated post" do
|
100
|
-
before
|
54
|
+
before do
|
101
55
|
post 'proc_form', { 'authenticity_token' => '1234',
|
102
56
|
'object_name' => { 'method_name' => '' },
|
103
57
|
'842d8d1c80014ce9f3d974614338605c' => 'some_value'
|
@@ -152,36 +106,31 @@ describe TestController do
|
|
152
106
|
controller.request.remote_addr = '127.0.0.1'
|
153
107
|
post 'proc_form', form
|
154
108
|
# puts controller.params.inspect
|
155
|
-
controller.params.should == { 'action' => 'proc_form', 'controller' => '
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
109
|
+
controller.params.should == { 'action' => 'proc_form', 'controller' => 'tests',
|
110
|
+
'authenticity_token' => 'yPgTAsngzpBO8k1v83RGH26sTrQYD50Ou2oiMT4r/iw=',
|
111
|
+
'user_session' => {
|
112
|
+
'login' => 'admin',
|
113
|
+
'password' => 'pwpwpw',
|
114
|
+
'remember_me' => '1'
|
115
|
+
},
|
116
|
+
'commit' => 'Log In'
|
163
117
|
}
|
164
118
|
end
|
165
119
|
end
|
166
120
|
|
167
121
|
context "without forgery protection" do
|
168
|
-
before :each do
|
169
|
-
prepare! if RAILS_VERSION < "3.0"
|
170
|
-
end
|
171
|
-
|
172
122
|
it "processes non-obfuscated form post" do
|
173
123
|
form = { #'authenticity_token' => '1234',
|
174
124
|
'object_name' => { 'method_name' => 'test' }
|
175
125
|
}
|
176
126
|
post 'proc_form', form
|
177
|
-
# puts
|
127
|
+
# puts response.body
|
178
128
|
controller.params.should_not == { 'suspected_bot' => true }
|
179
129
|
controller.params[:object_name].should == { 'method_name' => 'test' }
|
180
130
|
end
|
181
131
|
|
182
132
|
it "produces non-obfuscated form elements" do
|
183
|
-
|
184
|
-
@response.body.should_not match(/<\/div><input/)
|
133
|
+
response.body.should_not match(/<\/div><input/)
|
185
134
|
end
|
186
135
|
end
|
187
136
|
end
|