1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
# frozen_string_literal: true
RSpec.describe FaradayMiddleware::ParseJson, type: :response do
context 'no type matching' do
it "doesn't change nil body" do
expect(process(nil).body).to be_nil
end
it 'nullifies empty body' do
expect(process('').body).to be_nil
end
it 'parses json body' do
response = process('{"a":1}')
expect(response.body).to eq('a' => 1)
expect(response.env[:raw_body]).to be_nil
end
end
context 'with preserving raw' do
let(:options) { { preserve_raw: true } }
it 'parses json body' do
response = process('{"a":1}')
expect(response.body).to eq('a' => 1)
expect(response.env[:raw_body]).to eq('{"a":1}')
end
it 'can opt out of preserving raw' do
response = process('{"a":1}', nil, preserve_raw: false)
expect(response.env[:raw_body]).to be_nil
end
end
context 'with regexp type matching' do
let(:options) { { content_type: /\bjson$/ } }
it 'parses json body of correct type' do
response = process('{"a":1}', 'application/x-json')
expect(response.body).to eq('a' => 1)
end
it 'ignores json body of incorrect type' do
response = process('{"a":1}', 'text/json-xml')
expect(response.body).to eq('{"a":1}')
end
end
context 'with array type matching' do
let(:options) { { content_type: %w[a/b c/d] } }
it 'parses json body of correct type' do
expect(process('{"a":1}', 'a/b').body).to be_a(Hash)
expect(process('{"a":1}', 'c/d').body).to be_a(Hash)
end
it 'ignores json body of incorrect type' do
expect(process('{"a":1}', 'a/d').body).not_to be_a(Hash)
end
end
it 'chokes on invalid json' do
expect { process('{!') }.to raise_error(Faraday::ParsingError)
end
it 'includes the response on the ParsingError instance' do
begin
process('{') { |env| env[:response] = Faraday::Response.new }
raise 'Parsing should have failed.'
rescue Faraday::ParsingError => e
expect(e.response).to be_a(Faraday::Response)
end
end
context 'with mime type fix' do
let(:middleware) do
app = described_class::MimeTypeFix.new(lambda { |env|
Faraday::Response.new(env)
}, content_type: %r{^text/})
described_class.new(app, content_type: 'application/json')
end
it 'ignores completely incompatible type' do
response = process('{"a":1}', 'application/xml')
expect(response.body).to eq('{"a":1}')
end
it 'ignores compatible type with bad data' do
response = process('var a = 1', 'text/javascript')
expect(response.body).to eq('var a = 1')
expect(response['content-type']).to eq('text/javascript')
end
it 'corrects compatible type and data' do
response = process('{"a":1}', 'text/javascript')
expect(response.body).to be_a(Hash)
expect(response['content-type']).to eq('application/json')
end
it 'corrects compatible type even when data starts with whitespace' do
response = process(%( \r\n\t{"a":1}), 'text/javascript')
expect(response.body).to be_a(Hash)
expect(response['content-type']).to eq('application/json')
end
end
context 'HEAD responses' do
it "nullifies the body if it's only one space" do
response = process(' ')
expect(response.body).to be_nil
end
it "nullifies the body if it's two spaces" do
response = process(' ')
expect(response.body).to be_nil
end
end
context 'JSON options' do
let(:body) { '{"a": 1}' }
let(:result) { { a: 1 } }
let(:options) do
{
parser_options: {
symbolize_names: true
}
}
end
it 'passes relevant options to JSON parse' do
expect(::JSON).to receive(:parse)
.with(body, options[:parser_options])
.and_return(result)
response = process(body)
expect(response.body).to eq(result)
end
end
end
|