# frozen_string_literal: true require 'spec_helper' require 'drillbit/middleware/parameter_parser' module Drillbit module Middleware describe ParameterParser do let(:app) { ->(_env) { [200, {}, 'response'] } } it 'converts JSON API compliant dasherized query params to underscored' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'QUERY_STRING' => 'hello-there=bob-jones&' \ 'nice-to-meet=you-bob&' \ 'hows-the-weather=today-bob', } _status, headers, _response = middleware.call(request) expect(headers['QUERY_STRING']).to eql 'hello_there=bob-jones&' \ 'nice_to_meet=you-bob&' \ 'hows_the_weather=today-bob' end it 'does not touch query params with no dashes' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'QUERY_STRING' => 'hello_there=bob-jones', } _status, headers, _response = middleware.call(request) expect(headers['QUERY_STRING']).to eql 'hello_there=bob-jones' end it 'can handle weirdly formatted query string parameters' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'QUERY_STRING' => 'hello-there=bob-jones&' \ 'nice-to-meet=you-bob&=', } _status, headers, _response = middleware.call(request) expect(headers['QUERY_STRING']).to eql 'hello_there=bob-jones&' \ 'nice_to_meet=you-bob&=' end it 'can handle query string parameters with no values' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'QUERY_STRING' => 'hello-there&nice-to-meet=you-bob&=', } _status, headers, _response = middleware.call(request) expect(headers['QUERY_STRING']).to eql 'hello_there&nice_to_meet=you-bob&=' end it 'can handle query string parameters with parameter name' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'QUERY_STRING' => 'hello-there=bob-jones&=you-bob&nice-to-meet=you-bob&=', } _status, headers, _response = middleware.call(request) expect(headers['QUERY_STRING']).to eql 'hello_there=bob-jones&' \ '=you-bob&' \ 'nice_to_meet=you-bob&=' end it 'converts JSON API compliant dasherized request params to underscored' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'CONTENT_LENGTH' => '1', 'CONTENT_TYPE' => 'application/json', 'RACK_INPUT' => <<-HEREDOC { "single": "word", "double-word": "double double", "triple": { "trippple-tripple": "mcdipple", "quad": { "another-level": "whoa inception" } }, "quint": [ { "quint-it-quit": "mc-dipple" }, { "quint-it-quit": "big-maccle" } ] } HEREDOC } _status, headers, _response = middleware.call(request) expect(JSON.load(headers['RACK_INPUT'])).to eql( 'single' => 'word', 'double_word' => 'double double', 'triple' => { 'trippple_tripple' => 'mcdipple', 'quad' => { 'another_level' => 'whoa inception', }, }, 'quint' => [ { 'quint_it_quit' => 'mc-dipple', }, { 'quint_it_quit' => 'big-maccle', }, ], ) end it 'does not convert to JSON if the content type is not JSON' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'CONTENT_LENGTH' => '1', 'CONTENT_TYPE' => 'not_j_s_o_n', 'RACK_INPUT' => 'This is not JSON', } _status, headers, _response = middleware.call(request) expect(headers['RACK_INPUT']).to eql 'This is not JSON' end it 'does not convert to JSON if there is no content' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'CONTENT_LENGTH' => '0', 'CONTENT_TYPE' => 'application/json', 'RACK_INPUT' => 'empty', } _status, headers, _response = middleware.call(request) expect(headers['RACK_INPUT']).to eql 'empty' end it 'can handle incorrectly formatted JSON' do app = ->(env) { [200, env, 'response'] } middleware = ParameterParser.new(app) request = { 'CONTENT_LENGTH' => '1', 'CONTENT_TYPE' => 'application/json', 'RACK_INPUT' => 'something blah', } status, headers, response = middleware.call(request) expect(status).to eql 400 expect(headers).to eql({}) expect(JSON.load(response[0])).to include( 'errors' => [ { 'id' => match(/[a-z0-9\-]+/), 'links' => { 'about' => nil, 'documentation' => nil, }, 'status' => 400, 'code' => 'errors.invalid_request_body', 'title' => 'Invalid Request Body', 'detail' => 'The information you attempted to send in the ' \ 'request cannot be parsed as a valid JSON document.', 'source' => { 'request_body' => 'something blah', }, }, ], ) end end end end