Do not permanently overwrite Parameters#[]

When stubbing the `ActionController::Parameters#[]` method, do not
permanently overwrite it. Restore the method after verifying simulating
the controller action.
This commit is contained in:
Damian Galarza 2014-04-06 11:18:12 -04:00 committed by Elliot Winkler
parent d8d510f4cc
commit 6065649f6c
2 changed files with 61 additions and 3 deletions

View File

@ -65,9 +65,13 @@ module Shoulda
def simulate_controller_action
ensure_action_and_verb_present!
stubbed_model_attributes
stub_model_attributes
context.send(verb, action)
begin
context.send(verb, action)
ensure
unstub_model_attributes
end
verify_permit_call
end
@ -84,17 +88,26 @@ module Shoulda
attributes & @model_attrs.shoulda_permitted_params
end
def stubbed_model_attributes
def stub_model_attributes
@model_attrs = self.class.stubbed_parameters_class.new(arbitrary_attributes)
local_model_attrs = @model_attrs
::ActionController::Parameters.class_eval do
alias_method :'shoulda_original_[]', :[]
define_method :[] do |*args|
local_model_attrs
end
end
end
def unstub_model_attributes
::ActionController::Parameters.class_eval do
alias_method :[], :'shoulda_original_[]'
undef_method :'shoulda_original_[]'
end
end
def ensure_action_and_verb_present!
if action.blank?
raise ActionNotDefinedError

View File

@ -102,6 +102,35 @@ describe Shoulda::Matchers::ActionController::StrongParametersMatcher do
expect { matcher.matches? }
.to raise_error(Shoulda::Matchers::ActionController::StrongParametersMatcher::VerbNotDefinedError)
end
context 'Stubbing ActionController::Parameters#[]' do
it "does not permanently stub []" do
controller_for_resource_with_strong_parameters(action: :create) do
params.require(:user).permit(:name)
end
described_class.new([:name]).in_context(self).for(:create).matches?
param = ActionController::Parameters.new(name: 'Ralph')[:name]
expect(param.singleton_class).not_to include(
Shoulda::Matchers::ActionController::StrongParametersMatcher::StubbedParameters
)
end
it 'prevents permanently overwriting [] on error' do
stub_controller_with_exception
begin
described_class.new([:name]).in_context(self).for(:create).matches?
rescue SimulatedError
end
param = ActionController::Parameters.new(name: 'Ralph')[:name]
expect(param.singleton_class).not_to include(
Shoulda::Matchers::ActionController::StrongParametersMatcher::StubbedParameters
)
end
end
end
describe "failure message" do
@ -157,4 +186,20 @@ describe Shoulda::Matchers::ActionController::StrongParametersMatcher do
end
end
end
def stub_controller_with_exception
controller = define_controller('Examples') do
def create
raise SimulatedError
end
end
setup_rails_controller_test(controller)
define_routes do
get 'examples', to: 'examples#create'
end
end
class SimulatedError < StandardError; end
end