Shoulda-matchers: should permit failing after rails upgrade for rails 5.1.0

Created on 17 May 2017  路  9Comments  路  Source: thoughtbot/shoulda-matchers

Hi there,

I have below code for should permit spec.

it do should permit(:email).for(:create, params: { customer: valid_attributes }).on(:customer) end

Above code was working with rails 5.0.2 and now i am getting the below error.

ArgumentError: unknown keyword: customer

Regards,
Hare

Most helpful comment

FWIW, updating permit_matcher.rb to wrap request_params with a params keyword fixes the issue.

i.e. in line 253:

          Doublespeak.with_doubles_activated do
            context.__send__(verb, action, params: request_params)
          end

All 9 comments

@Hareramrai Can you provide a backtrace?

I'm having the same issue.

(byebug)           expect(subject).to permit(:name).for(:create, params: params)
*** ArgumentError Exception: unknown keyword: trip

nil
(byebug) bt
--> #0  block (5 levels) in block (5 levels) in <top (required)> at /data/rails-ftc-bms/spec/controllers/v1/trips_controller_spec.rb:142
    捅-- #1  BasicObject.instance_exec(*args) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:254
    #2  block in RSpec::Core::Example.block in run(example_group_instance#RSpec::ExampleGroups::V1TripsController::AuthenticatedUser::POSTCreate::StrongParameters, reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:254
    #3  block in RSpec::Core::Example.block in with_around_and_singleton_context_hooks at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:500
    #4  block in RSpec::Core::Example.block in with_around_example_hooks at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:457
    #5  block in RSpec::Core::Hooks::HookCollections.block in run(position#Symbol, scope#Symbol, example_or_group#RSpec::Core::Example) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:464
    #6  block in RSpec::Core::Hooks::HookCollections.block in run_around_example_hooks_for(example#RSpec::Core::Example) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:604
    #7  RSpec::Core::Example::Procsy.call(*args#Array, &block#NilClass) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:342
    #8  block (2 levels) in block (2 levels) in <module:ControllerExampleGroup> at /data/rails-ftc-bms/vendor/bundle/gems/rspec-rails-3.6.0/lib/rspec/rails/example/controller_example_group.rb:191
    捅-- #9  BasicObject.instance_exec(*args) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:447
    #10 RSpec::Core::Example.instance_exec(*args#Array, &block#Proc) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:447
    #11 RSpec::Core::Hooks::AroundHook.execute_with(example#RSpec::Core::Example, procsy#RSpec::Core::Example::Procsy) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:375
    #12 block (2 levels) in RSpec::Core::Hooks::HookCollections.block (2 levels) in run_around_example_hooks_for(example#RSpec::Core::Example) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:606
    #13 RSpec::Core::Example::Procsy.call(*args#Array, &block#NilClass) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:342
    #14 block (2 levels) in block (2 levels) in <module:MinitestLifecycleAdapter> at /data/rails-ftc-bms/vendor/bundle/gems/rspec-rails-3.6.0/lib/rspec/rails/adapters.rb:127
    捅-- #15 BasicObject.instance_exec(*args) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:447
    #16 RSpec::Core::Example.instance_exec(*args#Array, &block#Proc) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:447
    #17 RSpec::Core::Hooks::AroundHook.execute_with(example#RSpec::Core::Example, procsy#RSpec::Core::Example::Procsy) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:375
    #18 block (2 levels) in RSpec::Core::Hooks::HookCollections.block (2 levels) in run_around_example_hooks_for(example#RSpec::Core::Example) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:606
    #19 RSpec::Core::Example::Procsy.call(*args#Array, &block#NilClass) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:342
    #20 RSpec::Core::Hooks::HookCollections.run_around_example_hooks_for(example#RSpec::Core::Example) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:607
    #21 RSpec::Core::Hooks::HookCollections.run(position#Symbol, scope#Symbol, example_or_group#RSpec::Core::Example) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb:464
    #22 RSpec::Core::Example.with_around_example_hooks at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:457
    #23 RSpec::Core::Example.with_around_and_singleton_context_hooks at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:500
    #24 RSpec::Core::Example.run(example_group_instance#RSpec::ExampleGroups::V1TripsController::AuthenticatedUser::POSTCreate::StrongParameters, reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:251
    #25 block in #<Class:RSpec::Core::ExampleGroup>.block in run_examples(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:627
    捅-- #26 Array.map at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:623
    #27 #<Class:RSpec::Core::ExampleGroup>.run_examples(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:623
    #28 #<Class:RSpec::Core::ExampleGroup>.run(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:589
    #29 block in #<Class:RSpec::Core::ExampleGroup>.block in run(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    捅-- #30 Array.map at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    #31 #<Class:RSpec::Core::ExampleGroup>.run(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    #32 block in #<Class:RSpec::Core::ExampleGroup>.block in run(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    捅-- #33 Array.map at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    #34 #<Class:RSpec::Core::ExampleGroup>.run(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    #35 block in #<Class:RSpec::Core::ExampleGroup>.block in run(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    捅-- #36 Array.map at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    #37 #<Class:RSpec::Core::ExampleGroup>.run(reporter#RSpec::Core::Reporter) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb:590
    #38 block (3 levels) in RSpec::Core::Runner.block (3 levels) in run_specs(example_groups#Array) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:118
    捅-- #39 Array.map at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:118
    #40 block (2 levels) in RSpec::Core::Runner.block (2 levels) in run_specs(example_groups#Array) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:118
    #41 RSpec::Core::Configuration.with_suite_hooks at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/configuration.rb:1894
    #42 block in RSpec::Core::Runner.block in run_specs(example_groups#Array) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:113
    #43 RSpec::Core::Reporter.report(expected_example_count#Integer) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/reporter.rb:79
    #44 RSpec::Core::Runner.run_specs(example_groups#Array) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:112
    #45 RSpec::Core::Runner.run(err#IO, out#IO) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:87
    #46 #<Class:RSpec::Core::Runner>.run(args#Array, err#IO, out#IO) at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:71
    #47 #<Class:RSpec::Core::Runner>.invoke at /data/rails-ftc-bms/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:45
    #48 Zeus::Rails.test(argv#Array) at /data/rails-ftc-bms/vendor/bundle/gems/zeus-0.15.12/lib/zeus/rails.rb:207
    #49 block in #<Class:Zeus>.block in command(identifier#Symbol, sock#UNIXSocket) at /data/rails-ftc-bms/vendor/bundle/gems/zeus-0.15.12/lib/zeus.rb:155
    捅-- #50 Kernel.fork at /data/rails-ftc-bms/vendor/bundle/gems/zeus-0.15.12/lib/zeus.rb:142
    #51 #<Class:Zeus>.command(identifier#Symbol, sock#UNIXSocket) at /data/rails-ftc-bms/vendor/bundle/gems/zeus-0.15.12/lib/zeus.rb:142
    #52 #<Class:Zeus>.go(identifier#Symbol) at /data/rails-ftc-bms/vendor/bundle/gems/zeus-0.15.12/lib/zeus.rb:50
    #53 <main> at /data/rails-ftc-bms/-e:1

FWIW, updating permit_matcher.rb to wrap request_params with a params keyword fixes the issue.

i.e. in line 253:

          Doublespeak.with_doubles_activated do
            context.__send__(verb, action, params: request_params)
          end

This is throwing a deprecation warning in 5.0.3 as well.

Monkey patch with https://github.com/thoughtbot/shoulda-matchers/issues/1018#issuecomment-303796064 for those who want it while waiting for a fix to get released.

# spec/support/shoulda-matchers.rb

require 'shoulda-matchers'

module ShouldaMatcherFixes
  # https://github.com/thoughtbot/shoulda-matchers/blob/master/lib/shoulda/matchers/action_controller/permit_matcher.rb
  module PermitMatcher
    # Monkey patch for Rails 5
    #
    # Original: https://github.com/thoughtbot/shoulda-matchers/blob/44c0198830921650af3b4a56f5d72aaae2168480/lib/shoulda/matchers/action_controller/permit_matcher.rb#L246-L257
    # Fix taken from: https://github.com/thoughtbot/shoulda-matchers/issues/1018#issuecomment-303796064
    #
    # @todo Put some type of check here so that the fix does not come out
    #   and we are stuck with this still kicking around.
    def matches?(controller)
      @controller = controller
      ensure_action_and_verb_present!

      parameters_double_registry.register

      Shoulda::Matchers::Doublespeak.with_doubles_activated do
        # context.__send__(verb, action, request_params)
        context.__send__(verb, action, params: request_params)
      end

      unpermitted_parameter_names.empty?
    end
  end
end

Shoulda::Matchers::ActionController::PermitMatcher.prepend ShouldaMatcherFixes::PermitMatcher

@mcmire Assume you would take a pull request against the https://github.com/thoughtbot/shoulda-matchers/tree/rails-5 branch for this fix? I can do so if that is right place to submit this fix to.

@mdeering Yes, rails-5 is the right branch for Rails 5.x fixes.

Hey all! This appears to be... different in 3.1.2 with Rails 5.0.4. The deprecation warning is now being thrown from the spec itself, instead of deep inside the Shoulda gem.

I was able to get the deprecation warning to go away by adding another params key. This syntax looks odd, but it works. I can see it will maybe change at some point in the future.

describe 'strong params' do
  let(:deliverable_params) {
    {
      id: deliverable.id,
      deliverable: {
        asset_type_id: asset_type.id
      }
    }
  }

  it do
    expect(subject).to permit(
      :asset_type_id
    ).for(:update, params: { params: deliverable_params }).on(:deliverable)
  end
end

Thanks to everyone for your hard work on this gem, I definitely appreciate it.

It looks like #989 will address this issue. I'll merge it into the rails-5 branch once we have the tests working, but in any case, I'm going to close this to reduce duplication.

Was this page helpful?
0 / 5 - 0 ratings