diff --git a/lib/faraday/response/json.rb b/lib/faraday/response/json.rb index eaae6bc2..71a57edb 100644 --- a/lib/faraday/response/json.rb +++ b/lib/faraday/response/json.rb @@ -60,7 +60,8 @@ def process_parser_options @decoder_options = if @decoder_options.is_a?(Array) && @decoder_options.size >= 2 @decoder_options.slice(0, 2) - elsif @decoder_options.respond_to?(:load) + elsif @decoder_options&.respond_to?(:load) # rubocop:disable Lint/RedundantSafeNavigation + # In some versions of Rails, `nil` responds to `load` - hence the safe navigation check above [@decoder_options, :load] else [::JSON, :parse] diff --git a/spec/faraday/response/json_spec.rb b/spec/faraday/response/json_spec.rb index 6108c5fd..e6cbda39 100644 --- a/spec/faraday/response/json_spec.rb +++ b/spec/faraday/response/json_spec.rb @@ -184,6 +184,23 @@ def process(body, content_type = 'application/json', options = {}) response = process(body) expect(response.body).to eq(result) end + + it 'passes relevant options to JSON parse even when nil responds to :load' do + original_allow_message_expectations_on_nil = RSpec::Mocks.configuration.allow_message_expectations_on_nil + RSpec::Mocks.configuration.allow_message_expectations_on_nil = true + allow(nil).to receive(:respond_to?) + .with(:load) + .and_return(true) + + expect(JSON).to receive(:parse) + .with(body, { symbolize_names: true }) + .and_return(result) + + response = process(body) + expect(response.body).to eq(result) + ensure + RSpec::Mocks.configuration.allow_message_expectations_on_nil = original_allow_message_expectations_on_nil + end end end end