diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e6c0a74183..59c57de543 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,9 +33,6 @@ jobs: - ruby: '2.7' gemfile: gemfiles/multi_xml.gemfile specs: 'spec/integration/multi_xml' - - ruby: '2.7' - gemfile: gemfiles/rack_2_0.gemfile - specs: 'spec/integration/rack_2_0' - ruby: '2.7' gemfile: gemfiles/rack_3_0.gemfile specs: 'spec/integration/rack_3_0' diff --git a/CHANGELOG.md b/CHANGELOG.md index 963ad514aa..08fb4e266e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ * [#2425](https://github.com/ruby-grape/grape/pull/2425): Replace `{}` with `Rack::Header` or `Rack::Utils::HeaderHash` - [@dhruvCW](https://github.com/dhruvCW). * [#2430](https://github.com/ruby-grape/grape/pull/2430): Isolate extensions within specific gemfile - [@ericproulx](https://github.com/ericproulx). * [#2431](https://github.com/ruby-grape/grape/pull/2431): Drop appraisals in favor of eval_gemfile - [@ericproulx](https://github.com/ericproulx). +* [#2435](https://github.com/ruby-grape/grape/pull/2435): Use rack constants - [@ericproulx](https://github.com/ericproulx). * Your contribution here. #### Fixes diff --git a/benchmark/large_model.rb b/benchmark/large_model.rb index 272fc93d13..27dc9a3574 100644 --- a/benchmark/large_model.rb +++ b/benchmark/large_model.rb @@ -233,7 +233,7 @@ def self.vrp_request_schedule(this) puts Grape::VERSION options = { - method: 'POST', + method: Rack::POST, params: JSON.parse(File.read('benchmark/resource/vrp_example.json')) } diff --git a/benchmark/nested_params.rb b/benchmark/nested_params.rb index f7cf0798ce..35916f9202 100644 --- a/benchmark/nested_params.rb +++ b/benchmark/nested_params.rb @@ -21,7 +21,7 @@ class API < Grape::API end options = { - method: 'POST', + method: Rack::POST, params: { address: { street: 'Alexis Pl.', diff --git a/benchmark/remounting.rb b/benchmark/remounting.rb index e174cda753..8b3de34fd2 100644 --- a/benchmark/remounting.rb +++ b/benchmark/remounting.rb @@ -28,7 +28,7 @@ class CommentAPI < Grape::API mount VotingApi end -env = Rack::MockRequest.env_for('/votes', method: 'GET') +env = Rack::MockRequest.env_for('/votes', method: Rack::GET) Benchmark.memory do |api| calls = 1000 diff --git a/benchmark/simple.rb b/benchmark/simple.rb index 053c333519..133050ae22 100644 --- a/benchmark/simple.rb +++ b/benchmark/simple.rb @@ -13,7 +13,7 @@ class API < Grape::API end options = { - method: 'GET' + method: Rack::GET } env = Rack::MockRequest.env_for('/api/v1', options) diff --git a/docker-compose.yml b/docker-compose.yml index a86e58625f..2b293708b1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,5 +15,3 @@ services: volumes: - .:/var/grape - gems:/usr/local/bundle - environment: - GEMFILE: multi_xml diff --git a/lib/grape/api/instance.rb b/lib/grape/api/instance.rb index c0c6ba2fd5..8047b4e256 100644 --- a/lib/grape/api/instance.rb +++ b/lib/grape/api/instance.rb @@ -160,9 +160,13 @@ def initialize # Handle a request. See Rack documentation for what `env` is. def call(env) - result = @router.call(env) - result[1].delete(Grape::Http::Headers::X_CASCADE) unless cascade? - result + status, headers, response = @router.call(env) + unless cascade? + headers = Grape::Util::Header.new.merge(headers) + headers.delete(Grape::Http::Headers::X_CASCADE) + end + + [status, headers, response] end # Some requests may return a HTTP 404 error if grape cannot find a matching @@ -201,11 +205,11 @@ def add_head_not_allowed_methods_and_options_methods allowed_methods = config[:methods].dup - allowed_methods |= [Grape::Http::Headers::HEAD] if !self.class.namespace_inheritable(:do_not_route_head) && allowed_methods.include?(Grape::Http::Headers::GET) + allowed_methods |= [Rack::HEAD] if !self.class.namespace_inheritable(:do_not_route_head) && allowed_methods.include?(Rack::GET) - allow_header = (self.class.namespace_inheritable(:do_not_route_options) ? allowed_methods : [Grape::Http::Headers::OPTIONS] | allowed_methods) + allow_header = (self.class.namespace_inheritable(:do_not_route_options) ? allowed_methods : [Rack::OPTIONS] | allowed_methods) - config[:endpoint].options[:options_route_enabled] = true unless self.class.namespace_inheritable(:do_not_route_options) || allowed_methods.include?(Grape::Http::Headers::OPTIONS) + config[:endpoint].options[:options_route_enabled] = true unless self.class.namespace_inheritable(:do_not_route_options) || allowed_methods.include?(Rack::OPTIONS) attributes = config.merge(allowed_methods: allowed_methods, allow_header: allow_header) generate_not_allowed_method(config[:pattern], **attributes) diff --git a/lib/grape/dsl/inside_route.rb b/lib/grape/dsl/inside_route.rb index d93546061f..9326400932 100644 --- a/lib/grape/dsl/inside_route.rb +++ b/lib/grape/dsl/inside_route.rb @@ -200,7 +200,7 @@ def redirect(url, permanent: false, body: nil, **_options) if permanent status 301 body_message ||= "This resource has been moved permanently to #{url}." - elsif env[Grape::Http::Headers::HTTP_VERSION] == 'HTTP/1.1' && request.request_method.to_s.upcase != Grape::Http::Headers::GET + elsif http_version == 'HTTP/1.1' && !request.get? status 303 body_message ||= "An alternate resource is located at #{url}." else @@ -226,10 +226,9 @@ def status(status = nil) when nil return @status if instance_variable_defined?(:@status) && @status - case request.request_method.to_s.upcase - when Grape::Http::Headers::POST + if request.post? 201 - when Grape::Http::Headers::DELETE + elsif request.delete? if instance_variable_defined?(:@body) && @body.present? 200 else @@ -351,7 +350,7 @@ def stream(value = nil) return if value.nil? && @stream.nil? header Rack::CONTENT_LENGTH, nil - header Grape::Http::Headers::TRANSFER_ENCODING, nil + header Rack::TRANSFER_ENCODING, nil header Rack::CACHE_CONTROL, 'no-cache' # Skips ETag generation (reading the response up front) if value.is_a?(String) file_body = Grape::ServeStream::FileBody.new(value) @@ -458,6 +457,10 @@ def entity_representation_for(entity_class, object, options) embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION) entity_class.represent(object, **embeds.merge(options)) end + + def http_version + env['HTTP_VERSION'] || env[Rack::SERVER_PROTOCOL] + end end end end diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index a729216bb2..7ec07792de 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -151,7 +151,7 @@ def mount_in(router) reset_routes! routes.each do |route| methods = [route.request_method] - methods << Grape::Http::Headers::HEAD if !namespace_inheritable(:do_not_route_head) && route.request_method == Grape::Http::Headers::GET + methods << Rack::HEAD if !namespace_inheritable(:do_not_route_head) && route.request_method == Rack::GET methods.each do |method| route = Grape::Router::Route.new(method, route.origin, **route.attributes.to_h) unless route.request_method == method router.append(route.apply(self)) @@ -401,7 +401,7 @@ def validations def options? options[:options_route_enabled] && - env[Grape::Http::Headers::REQUEST_METHOD] == Grape::Http::Headers::OPTIONS + env[Rack::REQUEST_METHOD] == Rack::OPTIONS end def method_missing(name, *_args) diff --git a/lib/grape/env.rb b/lib/grape/env.rb index a6023bcc1e..09392fd2d4 100644 --- a/lib/grape/env.rb +++ b/lib/grape/env.rb @@ -11,11 +11,6 @@ module Env API_VENDOR = 'api.vendor' API_FORMAT = 'api.format' - RACK_INPUT = 'rack.input' - RACK_REQUEST_QUERY_HASH = 'rack.request.query_hash' - RACK_REQUEST_FORM_HASH = 'rack.request.form_hash' - RACK_REQUEST_FORM_INPUT = 'rack.request.form_input' - GRAPE_REQUEST = 'grape.request' GRAPE_REQUEST_HEADERS = 'grape.request.headers' GRAPE_REQUEST_PARAMS = 'grape.request.params' diff --git a/lib/grape/http/headers.rb b/lib/grape/http/headers.rb index ae0989a3b3..d1d995c579 100644 --- a/lib/grape/http/headers.rb +++ b/lib/grape/http/headers.rb @@ -3,44 +3,25 @@ module Grape module Http module Headers - # https://github.com/rack/rack/blob/master/lib/rack.rb - HTTP_VERSION = 'HTTP_VERSION' - PATH_INFO = 'PATH_INFO' - REQUEST_METHOD = 'REQUEST_METHOD' - QUERY_STRING = 'QUERY_STRING' - - def self.lowercase? - Rack::CONTENT_TYPE == 'content-type' - end - - if lowercase? - ALLOW = 'allow' - LOCATION = 'location' - TRANSFER_ENCODING = 'transfer-encoding' - X_CASCADE = 'x-cascade' - else - ALLOW = 'Allow' - LOCATION = 'Location' - TRANSFER_ENCODING = 'Transfer-Encoding' - X_CASCADE = 'X-Cascade' - end - - GET = 'GET' - POST = 'POST' - PUT = 'PUT' - PATCH = 'PATCH' - DELETE = 'DELETE' - HEAD = 'HEAD' - OPTIONS = 'OPTIONS' - - SUPPORTED_METHODS = [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS].freeze - SUPPORTED_METHODS_WITHOUT_OPTIONS = Grape::Util::Lazy::Object.new { [GET, POST, PUT, PATCH, DELETE, HEAD].freeze } - - HTTP_ACCEPT_VERSION = 'HTTP_ACCEPT_VERSION' + HTTP_ACCEPT_VERSION = 'HTTP_ACCEPT_VERSION' + HTTP_ACCEPT = 'HTTP_ACCEPT' HTTP_TRANSFER_ENCODING = 'HTTP_TRANSFER_ENCODING' - HTTP_ACCEPT = 'HTTP_ACCEPT' - FORMAT = 'format' + ALLOW = 'Allow' + LOCATION = 'Location' + X_CASCADE = 'X-Cascade' + + SUPPORTED_METHODS = [ + Rack::GET, + Rack::POST, + Rack::PUT, + Rack::PATCH, + Rack::DELETE, + Rack::HEAD, + Rack::OPTIONS + ].freeze + + SUPPORTED_METHODS_WITHOUT_OPTIONS = (SUPPORTED_METHODS - [Rack::OPTIONS]).freeze HTTP_HEADERS = Grape::Util::Lazy::Object.new do common_http_headers = %w[ diff --git a/lib/grape/middleware/error.rb b/lib/grape/middleware/error.rb index dedb4cd586..b1fc02767f 100644 --- a/lib/grape/middleware/error.rb +++ b/lib/grape/middleware/error.rb @@ -40,7 +40,7 @@ def call!(env) def rack_response(status, headers, message) message = Rack::Utils.escape_html(message) if headers[Rack::CONTENT_TYPE] == TEXT_HTML - Rack::Response.new(Array.wrap(message), Rack::Utils.status_code(status), headers) + Rack::Response.new(Array.wrap(message), Rack::Utils.status_code(status), Grape::Util::Header.new.merge(headers)) end def format_message(message, backtrace, original_exception = nil) diff --git a/lib/grape/middleware/formatter.rb b/lib/grape/middleware/formatter.rb index 2f0f7f0dfa..a199ce9819 100644 --- a/lib/grape/middleware/formatter.rb +++ b/lib/grape/middleware/formatter.rb @@ -4,6 +4,7 @@ module Grape module Middleware class Formatter < Base CHUNKED = 'chunked' + FORMAT = 'format' def default_options { @@ -80,7 +81,7 @@ def read_body_input !request.parseable_data? && (request.content_length.to_i.positive? || request.env[Grape::Http::Headers::HTTP_TRANSFER_ENCODING] == CHUNKED) - return unless (input = env[Grape::Env::RACK_INPUT]) + return unless (input = env[Rack::RACK_INPUT]) input.rewind body = env[Grape::Env::API_REQUEST_INPUT] = input.read @@ -101,12 +102,12 @@ def read_rack_input(body) begin body = (env[Grape::Env::API_REQUEST_BODY] = parser.call(body, env)) if body.is_a?(Hash) - env[Grape::Env::RACK_REQUEST_FORM_HASH] = if env.key?(Grape::Env::RACK_REQUEST_FORM_HASH) - env[Grape::Env::RACK_REQUEST_FORM_HASH].merge(body) - else - body - end - env[Grape::Env::RACK_REQUEST_FORM_INPUT] = env[Grape::Env::RACK_INPUT] + env[Rack::RACK_REQUEST_FORM_HASH] = if env.key?(Rack::RACK_REQUEST_FORM_HASH) + env[Rack::RACK_REQUEST_FORM_HASH].merge(body) + else + body + end + env[Rack::RACK_REQUEST_FORM_INPUT] = env[Rack::RACK_INPUT] end rescue Grape::Exceptions::Base => e raise e @@ -139,7 +140,7 @@ def format_from_extension end def format_from_params - fmt = Rack::Utils.parse_nested_query(env[Grape::Http::Headers::QUERY_STRING])[Grape::Http::Headers::FORMAT] + fmt = Rack::Utils.parse_nested_query(env[Rack::QUERY_STRING])[FORMAT] # avoid symbol memory leak on an unknown format return fmt.to_sym if content_type_for(fmt) diff --git a/lib/grape/middleware/globals.rb b/lib/grape/middleware/globals.rb index 10d5029dcc..81fa9b1f6f 100644 --- a/lib/grape/middleware/globals.rb +++ b/lib/grape/middleware/globals.rb @@ -7,7 +7,7 @@ def before request = Grape::Request.new(@env, build_params_with: @options[:build_params_with]) @env[Grape::Env::GRAPE_REQUEST] = request @env[Grape::Env::GRAPE_REQUEST_HEADERS] = request.headers - @env[Grape::Env::GRAPE_REQUEST_PARAMS] = request.params if @env[Grape::Env::RACK_INPUT] + @env[Grape::Env::GRAPE_REQUEST_PARAMS] = request.params if @env[Rack::RACK_INPUT] end end end diff --git a/lib/grape/middleware/versioner/param.rb b/lib/grape/middleware/versioner/param.rb index 69b1d0f48f..d12690c155 100644 --- a/lib/grape/middleware/versioner/param.rb +++ b/lib/grape/middleware/versioner/param.rb @@ -28,12 +28,12 @@ def default_options end def before - potential_version = Rack::Utils.parse_nested_query(env[Grape::Http::Headers::QUERY_STRING])[paramkey] + potential_version = Rack::Utils.parse_nested_query(env[Rack::QUERY_STRING])[paramkey] return if potential_version.nil? throw :error, status: 404, message: '404 API Version Not Found', headers: { Grape::Http::Headers::X_CASCADE => 'pass' } if options[:versions] && !options[:versions].find { |v| v.to_s == potential_version } env[Grape::Env::API_VERSION] = potential_version - env[Grape::Env::RACK_REQUEST_QUERY_HASH].delete(paramkey) if env.key? Grape::Env::RACK_REQUEST_QUERY_HASH + env[Rack::RACK_REQUEST_QUERY_HASH].delete(paramkey) if env.key? Rack::RACK_REQUEST_QUERY_HASH end private diff --git a/lib/grape/middleware/versioner/path.rb b/lib/grape/middleware/versioner/path.rb index d6c3e90dda..24fc9010a9 100644 --- a/lib/grape/middleware/versioner/path.rb +++ b/lib/grape/middleware/versioner/path.rb @@ -24,7 +24,7 @@ def default_options end def before - path = env[Grape::Http::Headers::PATH_INFO].dup + path = env[Rack::PATH_INFO].dup path.sub!(mount_path, '') if mounted_path?(path) if prefix && path.index(prefix) == 0 # rubocop:disable all diff --git a/lib/grape/router.rb b/lib/grape/router.rb index 7d9dd85641..cbed9d87d2 100644 --- a/lib/grape/router.rb +++ b/lib/grape/router.rb @@ -96,7 +96,7 @@ def transaction(env) # If last_neighbor_route exists and request method is OPTIONS, # return response by using #call_with_allow_headers. - return call_with_allow_headers(env, last_neighbor_route) if last_neighbor_route && method == Grape::Http::Headers::OPTIONS && !cascade + return call_with_allow_headers(env, last_neighbor_route) if last_neighbor_route && method == Rack::OPTIONS && !cascade route = match?(input, '*') @@ -123,8 +123,8 @@ def make_routing_args(default_args, route, input) end def extract_input_and_method(env) - input = string_for(env[Grape::Http::Headers::PATH_INFO]) - method = env[Grape::Http::Headers::REQUEST_METHOD] + input = string_for(env[Rack::PATH_INFO]) + method = env[Rack::REQUEST_METHOD] [input, method] end diff --git a/spec/grape/api/custom_validations_spec.rb b/spec/grape/api/custom_validations_spec.rb index 558da7576d..936971a957 100644 --- a/spec/grape/api/custom_validations_spec.rb +++ b/spec/grape/api/custom_validations_spec.rb @@ -71,7 +71,7 @@ def validate_param!(attr_name, params) let(:in_body_validator) do Class.new(Grape::Validations::Validators::PresenceValidator) do def validate(request) - validate!(request.env['api.request.body']) + validate!(request.env[Grape::Env::API_REQUEST_BODY]) end end end diff --git a/spec/grape/api/defines_boolean_in_params_spec.rb b/spec/grape/api/defines_boolean_in_params_spec.rb index 6d35049cfb..e885eff0de 100644 --- a/spec/grape/api/defines_boolean_in_params_spec.rb +++ b/spec/grape/api/defines_boolean_in_params_spec.rb @@ -24,7 +24,7 @@ end context 'Params endpoint type' do - subject { app.new.router.map['POST'].first.options[:params]['message'][:type] } + subject { app.new.router.map[Rack::POST].first.options[:params]['message'][:type] } it 'params type is a boolean' do expect(subject).to eq 'Grape::API::Boolean' diff --git a/spec/grape/api/patch_method_helpers_spec.rb b/spec/grape/api/patch_method_helpers_spec.rb index ad0a162bab..f91f028a55 100644 --- a/spec/grape/api/patch_method_helpers_spec.rb +++ b/spec/grape/api/patch_method_helpers_spec.rb @@ -49,12 +49,12 @@ def app context 'patch' do it 'public' do - patch '/', {}, 'HTTP_ACCEPT' => 'application/vnd.grape-public-v1+json' + patch '/', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.grape-public-v1+json' expect(last_response.status).to eq 405 end it 'private' do - patch '/', {}, 'HTTP_ACCEPT' => 'application/vnd.grape-private-v1+json' + patch '/', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.grape-private-v1+json' expect(last_response.status).to eq 405 end @@ -66,13 +66,13 @@ def app context 'default' do it 'public' do - get '/', {}, 'HTTP_ACCEPT' => 'application/vnd.grape-public-v1+json' + get '/', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.grape-public-v1+json' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ ok: 'public' }.to_json) end it 'private' do - get '/', {}, 'HTTP_ACCEPT' => 'application/vnd.grape-private-v1+json' + get '/', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.grape-private-v1+json' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ ok: 'private' }.to_json) end diff --git a/spec/grape/api_spec.rb b/spec/grape/api_spec.rb index f8aec1c488..218a654616 100644 --- a/spec/grape/api_spec.rb +++ b/spec/grape/api_spec.rb @@ -436,7 +436,7 @@ def to_txt it "allows a(n) #{object.class} json object in params" do subject.format :json subject.send(verb) do - env['api.request.body'] + env[Grape::Env::API_REQUEST_BODY] end send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(verb == :post ? 201 : 200) @@ -447,7 +447,7 @@ def to_txt it 'stores input in api.request.input' do subject.format :json subject.send(verb) do - env['api.request.input'] + env[Grape::Env::API_REQUEST_INPUT] end send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(verb == :post ? 201 : 200) @@ -458,9 +458,9 @@ def to_txt it 'stores input in api.request.input' do subject.format :json subject.send(verb) do - env['api.request.input'] + env[Grape::Env::API_REQUEST_INPUT] end - send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json', 'HTTP_TRANSFER_ENCODING' => 'chunked', 'CONTENT_LENGTH' => nil + send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json', Grape::Http::Headers::HTTP_TRANSFER_ENCODING => 'chunked', 'CONTENT_LENGTH' => nil expect(last_response.status).to eq(verb == :post ? 201 : 200) expect(last_response.body).to eql ::Grape::Json.dump(object).to_json end @@ -1247,12 +1247,12 @@ def to_txt subject.use Gem::Version.new(Rack.release) < Gem::Version.new('3') ? Rack::Chunked : ChunkedResponse subject.get('/stream') { stream test_stream } - get '/stream', {}, 'HTTP_VERSION' => 'HTTP/1.1', 'SERVER_PROTOCOL' => 'HTTP/1.1' + get '/stream', {}, 'HTTP_VERSION' => 'HTTP/1.1', Rack::SERVER_PROTOCOL => 'HTTP/1.1' expect(last_response.content_type).to eq('text/plain') expect(last_response.content_length).to be_nil expect(last_response.headers[Rack::CACHE_CONTROL]).to eq('no-cache') - expect(last_response.headers[Grape::Http::Headers::TRANSFER_ENCODING]).to eq('chunked') + expect(last_response.headers[Rack::TRANSFER_ENCODING]).to eq('chunked') expect(last_response.body).to eq("c\r\nThis is some\r\nd\r\n file content\r\n0\r\n\r\n") end @@ -1321,7 +1321,7 @@ def to_txt subject.post 'attachment' do filename = params[:file][:filename] content_type ct - env['api.format'] = :binary # there's no formatter for :binary, data will be returned "as is" + env[Grape::Env::API_FORMAT] = :binary # there's no formatter for :binary, data will be returned "as is" header 'Content-Disposition', "attachment; filename*=UTF-8''#{CGI.escape(filename)}" params[:file][:tempfile].read end @@ -2582,7 +2582,7 @@ def self.call(message, _backtrace, _options, _env, _original_exception) end it 'uses custom formatter' do - get '/simple.custom', 'HTTP_ACCEPT' => 'application/custom' + get '/simple.custom', Grape::Http::Headers::HTTP_ACCEPT => 'application/custom' expect(last_response.body).to eql '{"custom_formatter":"hash"}' end end @@ -2611,7 +2611,7 @@ def self.call(object, _env) end it 'uses custom formatter' do - get '/simple.custom', 'HTTP_ACCEPT' => 'application/custom' + get '/simple.custom', Grape::Http::Headers::HTTP_ACCEPT => 'application/custom' expect(last_response.body).to eql '{"custom_formatter":"hash"}' end end @@ -2699,7 +2699,7 @@ def self.call(object, _env) before do subject.parser :json, nil subject.put 'data' do - "body: #{env['api.request.body']}" + "body: #{env[Grape::Env::API_REQUEST_BODY]}" end end @@ -2786,7 +2786,7 @@ def self.call(object, _env) route = subject.routes[0] expect(route.version).to be_nil expect(route.path).to eq('/ping(.:format)') - expect(route.request_method).to eq('GET') + expect(route.request_method).to eq(Rack::GET) end end @@ -3247,7 +3247,7 @@ def self.call(object, _env) it 'is able to cascade' do subject.mount lambda { |env| headers = {} - headers[Grape::Http::Headers::X_CASCADE] == 'pass' if env['PATH_INFO'].exclude?('boo') + headers[Grape::Http::Headers::X_CASCADE] == 'pass' if env[Rack::PATH_INFO].exclude?('boo') [200, headers, ['Farfegnugen']] } => '/' @@ -3747,7 +3747,7 @@ def my_method end it 'forces txt from a non-accepting header' do - get '/meaning_of_life', {}, 'HTTP_ACCEPT' => 'application/json' + get '/meaning_of_life', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/json' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end end @@ -3776,7 +3776,7 @@ def my_method end it 'forces txt from a non-accepting header' do - get '/meaning_of_life', {}, 'HTTP_ACCEPT' => 'application/json' + get '/meaning_of_life', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/json' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end end @@ -3801,7 +3801,7 @@ def my_method end it 'forces json from a non-accepting header' do - get '/meaning_of_life', {}, 'HTTP_ACCEPT' => 'text/html' + get '/meaning_of_life', {}, Grape::Http::Headers::HTTP_ACCEPT => 'text/html' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_json) end @@ -3998,7 +3998,7 @@ def before [true, false].each do |anchor| it "anchor=#{anchor}" do subject.route :any, '*path', anchor: anchor do - error!("Unrecognized request path: #{params[:path]} - #{env['PATH_INFO']}#{env['SCRIPT_NAME']}", 404) + error!("Unrecognized request path: #{params[:path]} - #{env[Rack::PATH_INFO]}#{env[Rack::SCRIPT_NAME]}", 404) end get '/v1/hello' expect(last_response).to be_successful diff --git a/spec/grape/dsl/inside_route_spec.rb b/spec/grape/dsl/inside_route_spec.rb index 7c6d752362..45bc737bd5 100644 --- a/spec/grape/dsl/inside_route_spec.rb +++ b/spec/grape/dsl/inside_route_spec.rb @@ -27,7 +27,7 @@ def initialize end it 'returns env[api.version]' do - subject.env['api.version'] = 'dummy' + subject.env[Grape::Env::API_VERSION] = 'dummy' expect(subject.version).to eq 'dummy' end end @@ -96,27 +96,27 @@ def initialize %w[GET PUT OPTIONS].each do |method| it 'defaults to 200 on GET' do request = Grape::Request.new(Rack::MockRequest.env_for('/', method: method)) - expect(subject).to receive(:request).and_return(request) + expect(subject).to receive(:request).and_return(request).twice expect(subject.status).to eq 200 end end it 'defaults to 201 on POST' do - request = Grape::Request.new(Rack::MockRequest.env_for('/', method: 'POST')) + request = Grape::Request.new(Rack::MockRequest.env_for('/', method: Rack::POST)) expect(subject).to receive(:request).and_return(request) expect(subject.status).to eq 201 end it 'defaults to 204 on DELETE' do - request = Grape::Request.new(Rack::MockRequest.env_for('/', method: 'DELETE')) - expect(subject).to receive(:request).and_return(request) + request = Grape::Request.new(Rack::MockRequest.env_for('/', method: Rack::DELETE)) + expect(subject).to receive(:request).and_return(request).twice expect(subject.status).to eq 204 end it 'defaults to 200 on DELETE with a body present' do - request = Grape::Request.new(Rack::MockRequest.env_for('/', method: 'DELETE')) + request = Grape::Request.new(Rack::MockRequest.env_for('/', method: Rack::DELETE)) subject.body 'content here' - expect(subject).to receive(:request).and_return(request) + expect(subject).to receive(:request).and_return(request).twice expect(subject.status).to eq 200 end @@ -247,7 +247,7 @@ def initialize before do subject.header Rack::CACHE_CONTROL, 'cache' subject.header Rack::CONTENT_LENGTH, 123 - subject.header Grape::Http::Headers::TRANSFER_ENCODING, 'base64' + subject.header Rack::TRANSFER_ENCODING, 'base64' end it 'sends no deprecation warnings' do @@ -277,7 +277,7 @@ def initialize it 'does not change the Transfer-Encoding header' do subject.sendfile file_path - expect(subject.header[Grape::Http::Headers::TRANSFER_ENCODING]).to eq 'base64' + expect(subject.header[Rack::TRANSFER_ENCODING]).to eq 'base64' end end @@ -308,7 +308,7 @@ def initialize before do subject.header Rack::CACHE_CONTROL, 'cache' subject.header Rack::CONTENT_LENGTH, 123 - subject.header Grape::Http::Headers::TRANSFER_ENCODING, 'base64' + subject.header Rack::TRANSFER_ENCODING, 'base64' end it 'emits no deprecation warnings' do @@ -344,7 +344,7 @@ def initialize it 'sets Transfer-Encoding header to nil' do subject.stream file_path - expect(subject.header[Grape::Http::Headers::TRANSFER_ENCODING]).to be_nil + expect(subject.header[Rack::TRANSFER_ENCODING]).to be_nil end end @@ -358,7 +358,7 @@ def initialize before do subject.header Rack::CACHE_CONTROL, 'cache' subject.header Rack::CONTENT_LENGTH, 123 - subject.header Grape::Http::Headers::TRANSFER_ENCODING, 'base64' + subject.header Rack::TRANSFER_ENCODING, 'base64' end it 'emits no deprecation warnings' do @@ -388,7 +388,7 @@ def initialize it 'sets Transfer-Encoding header to nil' do subject.stream stream_object - expect(subject.header[Grape::Http::Headers::TRANSFER_ENCODING]).to be_nil + expect(subject.header[Rack::TRANSFER_ENCODING]).to be_nil end end @@ -409,8 +409,8 @@ def initialize describe '#route' do before do - subject.env['grape.routing_args'] = {} - subject.env['grape.routing_args'][:route_info] = 'dummy' + subject.env[Grape::Env::GRAPE_ROUTING_ARGS] = {} + subject.env[Grape::Env::GRAPE_ROUTING_ARGS][:route_info] = 'dummy' end it 'returns route_info' do diff --git a/spec/grape/dsl/routing_spec.rb b/spec/grape/dsl/routing_spec.rb index 8812b05bd4..6d64586198 100644 --- a/spec/grape/dsl/routing_spec.rb +++ b/spec/grape/dsl/routing_spec.rb @@ -128,49 +128,49 @@ class Dummy describe '.get' do it 'delegates to .route' do - expect(subject).to receive(:route).with('GET', path, options) + expect(subject).to receive(:route).with(Rack::GET, path, options) subject.get path, options, &proc end end describe '.post' do it 'delegates to .route' do - expect(subject).to receive(:route).with('POST', path, options) + expect(subject).to receive(:route).with(Rack::POST, path, options) subject.post path, options, &proc end end describe '.put' do it 'delegates to .route' do - expect(subject).to receive(:route).with('PUT', path, options) + expect(subject).to receive(:route).with(Rack::PUT, path, options) subject.put path, options, &proc end end describe '.head' do it 'delegates to .route' do - expect(subject).to receive(:route).with('HEAD', path, options) + expect(subject).to receive(:route).with(Rack::HEAD, path, options) subject.head path, options, &proc end end describe '.delete' do it 'delegates to .route' do - expect(subject).to receive(:route).with('DELETE', path, options) + expect(subject).to receive(:route).with(Rack::DELETE, path, options) subject.delete path, options, &proc end end describe '.options' do it 'delegates to .route' do - expect(subject).to receive(:route).with('OPTIONS', path, options) + expect(subject).to receive(:route).with(Rack::OPTIONS, path, options) subject.options path, options, &proc end end describe '.patch' do it 'delegates to .route' do - expect(subject).to receive(:route).with('PATCH', path, options) + expect(subject).to receive(:route).with(Rack::PATCH, path, options) subject.patch path, options, &proc end end diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index 8b217af9e5..55ae6fd207 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -75,7 +75,7 @@ def app it 'sets itself in the env upon call' do subject.get('/') { 'Hello world.' } get '/' - expect(last_request.env['api.endpoint']).to be_a(described_class) + expect(last_request.env[Grape::Env::API_ENDPOINT]).to be_a(described_class) end describe '#status' do @@ -136,15 +136,16 @@ def app end end + let(:headers) do + Grape::Util::Header.new.tap do |h| + h['Cookie'] = '' + h['Host'] = 'example.org' + end + end + it 'includes request headers' do get '/headers' - cookie_header = Grape::Http::Headers.lowercase? ? 'cookie' : 'Cookie' - host_header = Grape::Http::Headers.lowercase? ? 'host' : 'Host' - - expect(JSON.parse(last_response.body)).to include( - host_header => 'example.org', - cookie_header => '' - ) + expect(JSON.parse(last_response.body)).to include(headers.to_h) end it 'includes additional request headers' do @@ -969,12 +970,12 @@ def memoized end it 'result in a 406 response if they are invalid' do - get '/test', {}, 'HTTP_ACCEPT' => 'application/vnd.ohanapi.v1+json' + get '/test', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.ohanapi.v1+json' expect(last_response.status).to eq(406) end it 'result in a 406 response if they cannot be parsed' do - get '/test', {}, 'HTTP_ACCEPT' => 'application/vnd.ohanapi.v1+json; version=1' + get '/test', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.ohanapi.v1+json; version=1' expect(last_response.status).to eq(406) end end diff --git a/spec/grape/exceptions/invalid_accept_header_spec.rb b/spec/grape/exceptions/invalid_accept_header_spec.rb index 42edfb5261..a0bf111393 100644 --- a/spec/grape/exceptions/invalid_accept_header_spec.rb +++ b/spec/grape/exceptions/invalid_accept_header_spec.rb @@ -19,7 +19,7 @@ shared_examples_for 'a not-cascaded request' do it 'does not include the X-Cascade=pass header' do - expect(last_response.headers[Grape::Http::Headers::X_CASCADE]).to be_nil + expect(last_response.headers).not_to have_key(Grape::Http::Headers::X_CASCADE) end it 'does not accept the request' do @@ -56,7 +56,7 @@ def app end context 'that received a request with correct vendor and version' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v99' } it_behaves_like 'a valid request' end @@ -64,7 +64,7 @@ def app context 'that receives' do context 'an invalid vendor in the request' do before do - get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99', + get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.invalidvendor-v99', 'CONTENT_TYPE' => 'application/json' end @@ -88,20 +88,20 @@ def app end context 'that received a request with correct vendor and version' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v99' } it_behaves_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v77' } it_behaves_like 'a not-cascaded request' end context 'an invalid vendor in the request' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.invalidvendor-v99' } it_behaves_like 'a not-cascaded request' end @@ -131,7 +131,7 @@ def app end context 'that received a request with correct vendor and version' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v99' } it_behaves_like 'a valid request' end @@ -139,7 +139,7 @@ def app context 'that receives' do context 'an invalid vendor in the request' do before do - get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99', + get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.invalidvendor-v99', 'CONTENT_TYPE' => 'application/json' end @@ -168,20 +168,20 @@ def app end context 'that received a request with correct vendor and version' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v99' } it_behaves_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v77' } it_behaves_like 'a not-cascaded request' end context 'an invalid vendor in the request' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.invalidvendor-v99' } it_behaves_like 'a not-cascaded request' end @@ -206,7 +206,7 @@ def app end context 'that received a request with correct vendor and version' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v99' } it_behaves_like 'a valid request' end @@ -214,7 +214,7 @@ def app context 'that receives' do context 'an invalid version in the request' do before do - get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77', + get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v77', 'CONTENT_TYPE' => 'application/json' end @@ -223,7 +223,7 @@ def app context 'an invalid vendor in the request' do before do - get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99', + get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.invalidvendor-v99', 'CONTENT_TYPE' => 'application/json' end @@ -247,20 +247,20 @@ def app end context 'that received a request with correct vendor and version' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v99' } it_behaves_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v77' } it_behaves_like 'a cascaded request' end context 'an invalid vendor in the request' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.invalidvendor-v99' } it_behaves_like 'a cascaded request' end @@ -290,7 +290,7 @@ def app end context 'that received a request with correct vendor and version' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v99' } it_behaves_like 'a valid request' end @@ -298,7 +298,7 @@ def app context 'that receives' do context 'an invalid version in the request' do before do - get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77', + get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v77', 'CONTENT_TYPE' => 'application/json' end @@ -307,7 +307,7 @@ def app context 'an invalid vendor in the request' do before do - get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99', + get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.invalidvendor-v99', 'CONTENT_TYPE' => 'application/json' end @@ -336,20 +336,20 @@ def app end context 'that received a request with correct vendor and version' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v99' } it_behaves_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendorname-v77' } it_behaves_like 'a cascaded request' end context 'an invalid vendor in the request' do - before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' } + before { get '/beer', {}, Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.invalidvendor-v99' } it_behaves_like 'a cascaded request' end diff --git a/spec/grape/integration/rack_sendfile_spec.rb b/spec/grape/integration/rack_sendfile_spec.rb index 87041f7e15..2864ca1010 100644 --- a/spec/grape/integration/rack_sendfile_spec.rb +++ b/spec/grape/integration/rack_sendfile_spec.rb @@ -16,7 +16,7 @@ end options = { - method: 'GET', + method: Rack::GET, 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect', 'HTTP_X_ACCEL_MAPPING' => '/accel/mapping/=/replaced/' } diff --git a/spec/grape/integration/rack_spec.rb b/spec/grape/integration/rack_spec.rb index fc0aca6823..0c09b676be 100644 --- a/spec/grape/integration/rack_spec.rb +++ b/spec/grape/integration/rack_spec.rb @@ -14,7 +14,7 @@ input.rewind options = { input: input, - method: 'POST', + method: Rack::POST, 'CONTENT_TYPE' => 'application/json' } env = Rack::MockRequest.env_for('/', options) diff --git a/spec/grape/middleware/formatter_spec.rb b/spec/grape/middleware/formatter_spec.rb index 20600f9d44..0f67d790ad 100644 --- a/spec/grape/middleware/formatter_spec.rb +++ b/spec/grape/middleware/formatter_spec.rb @@ -12,7 +12,7 @@ let(:body) { { 'abc' => 'def' } } it 'looks at the bodies for possibly serializable data' do - _, _, bodies = *subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json') + _, _, bodies = *subject.call(Rack::PATH_INFO => '/somewhere', Grape::Http::Headers::HTTP_ACCEPT => 'application/json') bodies.each { |b| expect(b).to eq(::Grape::Json.dump(body)) } # rubocop:disable RSpec/IteratedExpectation end @@ -26,7 +26,7 @@ def to_json(*_args) end end - subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('"bar"') } # rubocop:disable RSpec/IteratedExpectation + subject.call(Rack::PATH_INFO => '/somewhere', Grape::Http::Headers::HTTP_ACCEPT => 'application/json').to_a.last.each { |b| expect(b).to eq('"bar"') } # rubocop:disable RSpec/IteratedExpectation end end @@ -40,7 +40,7 @@ def to_json(*_args) end end - subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/vnd.api+json').to_a.last.each { |b| expect(b).to eq('{"foos":[{"bar":"baz"}] }') } # rubocop:disable RSpec/IteratedExpectation + subject.call(Rack::PATH_INFO => '/somewhere', Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.api+json').to_a.last.each { |b| expect(b).to eq('{"foos":[{"bar":"baz"}] }') } # rubocop:disable RSpec/IteratedExpectation end end @@ -53,7 +53,7 @@ def to_xml '' end end - subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('') } # rubocop:disable RSpec/IteratedExpectation + subject.call(Rack::PATH_INFO => '/somewhere.xml', Grape::Http::Headers::HTTP_ACCEPT => 'application/json').to_a.last.each { |b| expect(b).to eq('') } # rubocop:disable RSpec/IteratedExpectation end end end @@ -69,7 +69,7 @@ def to_xml allow(formatter).to receive(:call) { raise Grape::Exceptions::InvalidFormatter.new(String, 'xml') } expect do - catch(:error) { subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json') } + catch(:error) { subject.call(Rack::PATH_INFO => '/somewhere.xml', Grape::Http::Headers::HTTP_ACCEPT => 'application/json') } end.not_to raise_error end @@ -77,102 +77,102 @@ def to_xml allow(formatter).to receive(:call) { raise StandardError } expect do - catch(:error) { subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json') } + catch(:error) { subject.call(Rack::PATH_INFO => '/somewhere.xml', Grape::Http::Headers::HTTP_ACCEPT => 'application/json') } end.to raise_error(StandardError) end end context 'detection' do it 'uses the xml extension if one is provided' do - subject.call('PATH_INFO' => '/info.xml') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info.xml') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) end it 'uses the json extension if one is provided' do - subject.call('PATH_INFO' => '/info.json') - expect(subject.env['api.format']).to eq(:json) + subject.call(Rack::PATH_INFO => '/info.json') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) end it 'uses the format parameter if one is provided' do - subject.call('PATH_INFO' => '/info', 'QUERY_STRING' => 'format=json') - expect(subject.env['api.format']).to eq(:json) - subject.call('PATH_INFO' => '/info', 'QUERY_STRING' => 'format=xml') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Rack::QUERY_STRING => 'format=json') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) + subject.call(Rack::PATH_INFO => '/info', Rack::QUERY_STRING => 'format=xml') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) end it 'uses the default format if none is provided' do - subject.call('PATH_INFO' => '/info') - expect(subject.env['api.format']).to eq(:txt) + subject.call(Rack::PATH_INFO => '/info') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:txt) end it 'uses the requested format if provided in headers' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json') - expect(subject.env['api.format']).to eq(:json) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) end it 'uses the file extension format if provided before headers' do - subject.call('PATH_INFO' => '/info.txt', 'HTTP_ACCEPT' => 'application/json') - expect(subject.env['api.format']).to eq(:txt) + subject.call(Rack::PATH_INFO => '/info.txt', Grape::Http::Headers::HTTP_ACCEPT => 'application/json') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:txt) end end context 'accept header detection' do it 'detects from the Accept header' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/xml') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/xml') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) end it 'uses quality rankings to determine formats' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; q=0.3,application/xml; q=1.0') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json; q=0.3,application/xml; q=1.0') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; q=1.0,application/xml; q=0.3') - expect(subject.env['api.format']).to eq(:json) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json; q=1.0,application/xml; q=0.3') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) end it 'handles quality rankings mixed with nothing' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json,application/xml; q=1.0') - expect(subject.env['api.format']).to eq(:json) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json,application/xml; q=1.0') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/xml; q=1.0,application/json') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/xml; q=1.0,application/json') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) end it 'handles quality rankings that have a default 1.0 value' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json,application/xml;q=0.5') - expect(subject.env['api.format']).to eq(:json) - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/xml;q=0.5,application/json') - expect(subject.env['api.format']).to eq(:json) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json,application/xml;q=0.5') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/xml;q=0.5,application/json') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) end it 'parses headers with other attributes' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; abc=2.3; q=1.0,application/xml; q=0.7') - expect(subject.env['api.format']).to eq(:json) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json; abc=2.3; q=1.0,application/xml; q=0.7') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) end it 'ensures that a quality of 0 is less preferred than any other content type' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json;q=0.0,application/xml') - expect(subject.env['api.format']).to eq(:xml) - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/xml,application/json;q=0.0') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json;q=0.0,application/xml') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/xml,application/json;q=0.0') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) end it 'ignores invalid quality rankings' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json;q=invalid,application/xml;q=0.5') - expect(subject.env['api.format']).to eq(:xml) - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/xml;q=0.5,application/json;q=invalid') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json;q=invalid,application/xml;q=0.5') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/xml;q=0.5,application/json;q=invalid') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json;q=,application/xml;q=0.5') - expect(subject.env['api.format']).to eq(:json) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json;q=,application/xml;q=0.5') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:json) - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json;q=nil,application/xml;q=0.5') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/json;q=nil,application/xml;q=0.5') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) end it 'parses headers with vendor and api version' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test-v1+xml') - expect(subject.env['api.format']).to eq(:xml) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.test-v1+xml') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:xml) end context 'with custom vendored content types' do @@ -182,50 +182,50 @@ def to_xml end it 'uses the custom type' do - subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test+json') - expect(subject.env['api.format']).to eq(:custom) + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.test+json') + expect(subject.env[Grape::Env::API_FORMAT]).to eq(:custom) end end it 'parses headers with symbols as hash keys' do - subject.call('PATH_INFO' => '/info', 'http_accept' => 'application/xml', system_time: '091293') + subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/xml', system_time: '091293') expect(subject.env[:system_time]).to eq('091293') end end context 'content-type' do it 'is set for json' do - _, headers, = subject.call('PATH_INFO' => '/info.json') - expect(headers['Content-type']).to eq('application/json') + _, headers, = subject.call(Rack::PATH_INFO => '/info.json') + expect(headers[Rack::CONTENT_TYPE]).to eq('application/json') end it 'is set for xml' do - _, headers, = subject.call('PATH_INFO' => '/info.xml') - expect(headers['Content-type']).to eq('application/xml') + _, headers, = subject.call(Rack::PATH_INFO => '/info.xml') + expect(headers[Rack::CONTENT_TYPE]).to eq('application/xml') end it 'is set for txt' do - _, headers, = subject.call('PATH_INFO' => '/info.txt') - expect(headers['Content-type']).to eq('text/plain') + _, headers, = subject.call(Rack::PATH_INFO => '/info.txt') + expect(headers[Rack::CONTENT_TYPE]).to eq('text/plain') end it 'is set for custom' do subject.options[:content_types] = {} subject.options[:content_types][:custom] = 'application/x-custom' - _, headers, = subject.call('PATH_INFO' => '/info.custom') - expect(headers['Content-type']).to eq('application/x-custom') + _, headers, = subject.call(Rack::PATH_INFO => '/info.custom') + expect(headers[Rack::CONTENT_TYPE]).to eq('application/x-custom') end it 'is set for vendored with registered type' do subject.options[:content_types] = {} subject.options[:content_types][:custom] = 'application/vnd.test+json' - _, headers, = subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test+json') - expect(headers['Content-type']).to eq('application/vnd.test+json') + _, headers, = subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.test+json') + expect(headers[Rack::CONTENT_TYPE]).to eq('application/vnd.test+json') end it 'is set to closest generic for custom vendored/versioned without registered type' do - _, headers, = subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test+json') - expect(headers['Content-type']).to eq('application/json') + _, headers, = subject.call(Rack::PATH_INFO => '/info', Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.test+json') + expect(headers[Rack::CONTENT_TYPE]).to eq('application/json') end end @@ -234,7 +234,7 @@ def to_xml subject.options[:content_types] = {} subject.options[:content_types][:custom] = "don't care" subject.options[:formatters][:custom] = ->(_obj, _env) { 'CUSTOM FORMAT' } - _, _, body = subject.call('PATH_INFO' => '/info.custom') + _, _, body = subject.call(Rack::PATH_INFO => '/info.custom') expect(read_chunks(body)).to eq(['CUSTOM FORMAT']) end @@ -242,14 +242,14 @@ def to_xml let(:body) { ['blah'] } it 'uses default json formatter' do - _, _, body = subject.call('PATH_INFO' => '/info.json') + _, _, body = subject.call(Rack::PATH_INFO => '/info.json') expect(read_chunks(body)).to eq(['["blah"]']) end end it 'uses custom json formatter' do subject.options[:formatters][:json] = ->(_obj, _env) { 'CUSTOM JSON FORMAT' } - _, _, body = subject.call('PATH_INFO' => '/info.json') + _, _, body = subject.call(Rack::PATH_INFO => '/info.json') expect(read_chunks(body)).to eq(['CUSTOM JSON FORMAT']) end end @@ -282,14 +282,14 @@ def to_xml it "parses the body from #{method} and copies values into rack.request.form_hash" do subject.call( - 'PATH_INFO' => '/info', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/info', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => content_type, - 'rack.input' => io, + Rack::RACK_INPUT => io, 'CONTENT_LENGTH' => io.length ) - expect(subject.env['rack.request.form_hash']['is_boolean']).to be true - expect(subject.env['rack.request.form_hash']['string']).to eq('thing') + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['is_boolean']).to be true + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['string']).to eq('thing') end end @@ -300,10 +300,10 @@ def to_xml it 'returns a 415 HTTP error status' do error = catch(:error) do subject.call( - 'PATH_INFO' => '/info', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/info', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => content_type, - 'rack.input' => io, + Rack::RACK_INPUT => io, 'CONTENT_LENGTH' => io.length ) end @@ -323,10 +323,10 @@ def to_xml it 'does not read and parse the body' do expect(subject).not_to receive(:read_rack_input) subject.call( - 'PATH_INFO' => '/info', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/info', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => 'application/json', - 'rack.input' => io, + Rack::RACK_INPUT => io, 'CONTENT_LENGTH' => 0 ) end @@ -342,10 +342,10 @@ def to_xml it 'does not read and parse the body' do expect(subject).not_to receive(:read_rack_input) subject.call( - 'PATH_INFO' => '/info', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/info', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => 'application/json', - 'rack.input' => io, + Rack::RACK_INPUT => io, 'CONTENT_LENGTH' => 0 ) end @@ -356,57 +356,57 @@ def to_xml it "parses the body from #{method} and copies values into rack.request.form_hash" do io = StringIO.new('{"is_boolean":true,"string":"thing"}') subject.call( - 'PATH_INFO' => '/info', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/info', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => content_type, - 'rack.input' => io, + Rack::RACK_INPUT => io, 'CONTENT_LENGTH' => io.length ) - expect(subject.env['rack.request.form_hash']['is_boolean']).to be true - expect(subject.env['rack.request.form_hash']['string']).to eq('thing') + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['is_boolean']).to be true + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['string']).to eq('thing') end end end it "parses the chunked body from #{method} and copies values into rack.request.from_hash" do io = StringIO.new('{"is_boolean":true,"string":"thing"}') subject.call( - 'PATH_INFO' => '/infol', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/infol', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => 'application/json', - 'rack.input' => io, - 'HTTP_TRANSFER_ENCODING' => 'chunked' + Rack::RACK_INPUT => io, + Grape::Http::Headers::HTTP_TRANSFER_ENCODING => 'chunked' ) - expect(subject.env['rack.request.form_hash']['is_boolean']).to be true - expect(subject.env['rack.request.form_hash']['string']).to eq('thing') + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['is_boolean']).to be true + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['string']).to eq('thing') end it 'rewinds IO' do io = StringIO.new('{"is_boolean":true,"string":"thing"}') io.read subject.call( - 'PATH_INFO' => '/infol', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/infol', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => 'application/json', - 'rack.input' => io, - 'HTTP_TRANSFER_ENCODING' => 'chunked' + Rack::RACK_INPUT => io, + Grape::Http::Headers::HTTP_TRANSFER_ENCODING => 'chunked' ) - expect(subject.env['rack.request.form_hash']['is_boolean']).to be true - expect(subject.env['rack.request.form_hash']['string']).to eq('thing') + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['is_boolean']).to be true + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['string']).to eq('thing') end it "parses the body from an xml #{method} and copies values into rack.request.from_hash" do io = StringIO.new('Test') subject.call( - 'PATH_INFO' => '/info.xml', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/info.xml', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => 'application/xml', - 'rack.input' => io, + Rack::RACK_INPUT => io, 'CONTENT_LENGTH' => io.length ) if Object.const_defined? :MultiXml - expect(subject.env['rack.request.form_hash']['thing']['name']).to eq('Test') + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['thing']['name']).to eq('Test') else - expect(subject.env['rack.request.form_hash']['thing']['name']['__content__']).to eq('Test') + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]['thing']['name']['__content__']).to eq('Test') end end @@ -414,13 +414,13 @@ def to_xml it "ignores #{content_type}" do io = StringIO.new('name=Other+Test+Thing') subject.call( - 'PATH_INFO' => '/info', - 'REQUEST_METHOD' => method, + Rack::PATH_INFO => '/info', + Rack::REQUEST_METHOD => method, 'CONTENT_TYPE' => content_type, - 'rack.input' => io, + Rack::RACK_INPUT => io, 'CONTENT_LENGTH' => io.length ) - expect(subject.env['rack.request.form_hash']).to be_nil + expect(subject.env[Rack::RACK_REQUEST_FORM_HASH]).to be_nil end end end @@ -433,10 +433,10 @@ def to_xml it 'returns a file response' do expect(file).to receive(:each).and_yield('data') - env = { 'PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json' } + env = { Rack::PATH_INFO => '/somewhere', Grape::Http::Headers::HTTP_ACCEPT => 'application/json' } status, headers, body = subject.call(env) expect(status).to eq 200 - expect(headers.transform_keys(&:downcase)).to eq({ 'content-type' => 'application/json' }) + expect(headers).to eq({ Rack::CONTENT_TYPE => 'application/json' }) expect(read_chunks(body)).to eq ['data'] end end @@ -463,7 +463,7 @@ def self.call(_, _) end it 'returns response by invalid formatter' do - env = { 'PATH_INFO' => '/hello.invalid', 'HTTP_ACCEPT' => 'application/x-invalid' } + env = { Rack::PATH_INFO => '/hello.invalid', Grape::Http::Headers::HTTP_ACCEPT => 'application/x-invalid' } _, _, body = *subject.call(env) expect(read_chunks(body).join).to eq({ message: 'invalid' }.to_json) end @@ -479,10 +479,10 @@ def self.call(_, _) io = StringIO.new('{invalid}') error = catch(:error) do subject.call( - 'PATH_INFO' => '/info', - 'REQUEST_METHOD' => 'POST', + Rack::PATH_INFO => '/info', + Rack::REQUEST_METHOD => Rack::POST, 'CONTENT_TYPE' => 'application/json', - 'rack.input' => io, + Rack::RACK_INPUT => io, 'CONTENT_LENGTH' => io.length ) end diff --git a/spec/grape/middleware/globals_spec.rb b/spec/grape/middleware/globals_spec.rb index 272664ef4e..18d3e962b4 100644 --- a/spec/grape/middleware/globals_spec.rb +++ b/spec/grape/middleware/globals_spec.rb @@ -14,17 +14,17 @@ context 'environment' do it 'sets the grape.request environment' do subject.call({}) - expect(subject.env['grape.request']).to be_a(Grape::Request) + expect(subject.env[Grape::Env::GRAPE_REQUEST]).to be_a(Grape::Request) end it 'sets the grape.request.headers environment' do subject.call({}) - expect(subject.env['grape.request.headers']).to be_a(Hash) + expect(subject.env[Grape::Env::GRAPE_REQUEST_HEADERS]).to be_a(Hash) end it 'sets the grape.request.params environment' do - subject.call('QUERY_STRING' => 'test=1', 'rack.input' => StringIO.new) - expect(subject.env['grape.request.params']).to be_a(Hash) + subject.call(Rack::QUERY_STRING => 'test=1', Rack::RACK_INPUT => StringIO.new) + expect(subject.env[Grape::Env::GRAPE_REQUEST_PARAMS]).to be_a(Hash) end end end diff --git a/spec/grape/middleware/versioner/accept_version_header_spec.rb b/spec/grape/middleware/versioner/accept_version_header_spec.rb index c2a66f2157..4f44384980 100644 --- a/spec/grape/middleware/versioner/accept_version_header_spec.rb +++ b/spec/grape/middleware/versioner/accept_version_header_spec.rb @@ -19,20 +19,20 @@ end it 'is set' do - status, _, env = subject.call('HTTP_ACCEPT_VERSION' => 'v1') - expect(env['api.version']).to eql 'v1' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => 'v1') + expect(env[Grape::Env::API_VERSION]).to eql 'v1' expect(status).to eq(200) end it 'is set if format provided' do - status, _, env = subject.call('HTTP_ACCEPT_VERSION' => 'v1') - expect(env['api.version']).to eql 'v1' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => 'v1') + expect(env[Grape::Env::API_VERSION]).to eql 'v1' expect(status).to eq(200) end it 'fails with 406 Not Acceptable if version is not supported' do expect do - subject.call('HTTP_ACCEPT_VERSION' => 'v2').last + subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => 'v2').last end.to throw_symbol( :error, status: 406, @@ -43,13 +43,13 @@ end it 'succeeds if :strict is not set' do - expect(subject.call('HTTP_ACCEPT_VERSION' => '').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => '').first).to eq(200) expect(subject.call({}).first).to eq(200) end it 'succeeds if :strict is set to false' do @options[:version_options][:strict] = false - expect(subject.call('HTTP_ACCEPT_VERSION' => '').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => '').first).to eq(200) expect(subject.call({}).first).to eq(200) end @@ -72,7 +72,7 @@ it 'fails with 406 Not Acceptable if header is empty' do expect do - subject.call('HTTP_ACCEPT_VERSION' => '').last + subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => '').last end.to throw_symbol( :error, status: 406, @@ -82,7 +82,7 @@ end it 'succeeds if proper header is set' do - expect(subject.call('HTTP_ACCEPT_VERSION' => 'v1').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => 'v1').first).to eq(200) end end @@ -106,7 +106,7 @@ it 'fails with 406 Not Acceptable if header is empty' do expect do - subject.call('HTTP_ACCEPT_VERSION' => '').last + subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => '').last end.to throw_symbol( :error, status: 406, @@ -116,7 +116,7 @@ end it 'succeeds if proper header is set' do - expect(subject.call('HTTP_ACCEPT_VERSION' => 'v1').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT_VERSION => 'v1').first).to eq(200) end end end diff --git a/spec/grape/middleware/versioner/header_spec.rb b/spec/grape/middleware/versioner/header_spec.rb index ec116a7419..1d686aae33 100644 --- a/spec/grape/middleware/versioner/header_spec.rb +++ b/spec/grape/middleware/versioner/header_spec.rb @@ -16,37 +16,37 @@ context 'api.type and api.subtype' do it 'sets type and subtype to first choice of content type if no preference given' do - status, _, env = subject.call('HTTP_ACCEPT' => '*/*') - expect(env['api.type']).to eql 'application' - expect(env['api.subtype']).to eql 'vnd.vendor+xml' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => '*/*') + expect(env[Grape::Env::API_TYPE]).to eql 'application' + expect(env[Grape::Env::API_SUBTYPE]).to eql 'vnd.vendor+xml' expect(status).to eq(200) end it 'sets preferred type' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/*') - expect(env['api.type']).to eql 'application' - expect(env['api.subtype']).to eql 'vnd.vendor+xml' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/*') + expect(env[Grape::Env::API_TYPE]).to eql 'application' + expect(env[Grape::Env::API_SUBTYPE]).to eql 'vnd.vendor+xml' expect(status).to eq(200) end it 'sets preferred type and subtype' do - status, _, env = subject.call('HTTP_ACCEPT' => 'text/plain') - expect(env['api.type']).to eql 'text' - expect(env['api.subtype']).to eql 'plain' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'text/plain') + expect(env[Grape::Env::API_TYPE]).to eql 'text' + expect(env[Grape::Env::API_SUBTYPE]).to eql 'plain' expect(status).to eq(200) end end context 'api.format' do it 'is set' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor+json') - expect(env['api.format']).to eql 'json' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor+json') + expect(env[Grape::Env::API_FORMAT]).to eql 'json' expect(status).to eq(200) end it 'is nil if not provided' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor') - expect(env['api.format']).to be_nil + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor') + expect(env[Grape::Env::API_FORMAT]).to be_nil expect(status).to eq(200) end @@ -57,14 +57,14 @@ end it 'is set' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json') - expect(env['api.format']).to eql 'json' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1+json') + expect(env[Grape::Env::API_FORMAT]).to eql 'json' expect(status).to eq(200) end it 'is nil if not provided' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1') - expect(env['api.format']).to be_nil + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1') + expect(env[Grape::Env::API_FORMAT]).to be_nil expect(status).to eq(200) end end @@ -73,19 +73,19 @@ context 'api.vendor' do it 'is set' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor') - expect(env['api.vendor']).to eql 'vendor' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor') + expect(env[Grape::Env::API_VENDOR]).to eql 'vendor' expect(status).to eq(200) end it 'is set if format provided' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor+json') - expect(env['api.vendor']).to eql 'vendor' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor+json') + expect(env[Grape::Env::API_VENDOR]).to eql 'vendor' expect(status).to eq(200) end it 'fails with 406 Not Acceptable if vendor is invalid' do - expect { subject.call('HTTP_ACCEPT' => 'application/vnd.othervendor+json').last } + expect { subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.othervendor+json').last } .to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql(Grape::Http::Headers::X_CASCADE => 'pass') @@ -100,19 +100,19 @@ end it 'is set' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1') - expect(env['api.vendor']).to eql 'vendor' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1') + expect(env[Grape::Env::API_VENDOR]).to eql 'vendor' expect(status).to eq(200) end it 'is set if format provided' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json') - expect(env['api.vendor']).to eql 'vendor' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1+json') + expect(env[Grape::Env::API_VENDOR]).to eql 'vendor' expect(status).to eq(200) end it 'fails with 406 Not Acceptable if vendor is invalid' do - expect { subject.call('HTTP_ACCEPT' => 'application/vnd.othervendor-v1+json').last } + expect { subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.othervendor-v1+json').last } .to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql(Grape::Http::Headers::X_CASCADE => 'pass') @@ -129,19 +129,19 @@ end it 'is set' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1') - expect(env['api.version']).to eql 'v1' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1') + expect(env[Grape::Env::API_VERSION]).to eql 'v1' expect(status).to eq(200) end it 'is set if format provided' do - status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json') - expect(env['api.version']).to eql 'v1' + status, _, env = subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1+json') + expect(env[Grape::Env::API_VERSION]).to eql 'v1' expect(status).to eq(200) end it 'fails with 406 Not Acceptable if version is invalid' do - expect { subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v2+json').last }.to raise_exception do |exception| + expect { subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v2+json').last }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidVersionHeader) expect(exception.headers).to eql(Grape::Http::Headers::X_CASCADE => 'pass') expect(exception.status).to be 406 @@ -151,19 +151,19 @@ end it 'succeeds if :strict is not set' do - expect(subject.call('HTTP_ACCEPT' => '').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT => '').first).to eq(200) expect(subject.call({}).first).to eq(200) end it 'succeeds if :strict is set to false' do @options[:version_options][:strict] = false - expect(subject.call('HTTP_ACCEPT' => '').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT => '').first).to eq(200) expect(subject.call({}).first).to eq(200) end it 'succeeds if :strict is set to false and given an invalid header' do @options[:version_options][:strict] = false - expect(subject.call('HTTP_ACCEPT' => 'yaml').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'yaml').first).to eq(200) expect(subject.call({}).first).to eq(200) end @@ -183,7 +183,7 @@ end it 'fails with 406 Not Acceptable if header is empty' do - expect { subject.call('HTTP_ACCEPT' => '').last }.to raise_exception do |exception| + expect { subject.call(Grape::Http::Headers::HTTP_ACCEPT => '').last }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql(Grape::Http::Headers::X_CASCADE => 'pass') expect(exception.status).to be 406 @@ -192,7 +192,7 @@ end it 'succeeds if proper header is set' do - expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1+json').first).to eq(200) end end @@ -213,7 +213,7 @@ end it 'fails with 406 Not Acceptable if header is application/xml' do - expect { subject.call('HTTP_ACCEPT' => 'application/xml').last } + expect { subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/xml').last } .to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql({}) @@ -223,7 +223,7 @@ end it 'fails with 406 Not Acceptable if header is empty' do - expect { subject.call('HTTP_ACCEPT' => '').last }.to raise_exception do |exception| + expect { subject.call(Grape::Http::Headers::HTTP_ACCEPT => '').last }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql({}) expect(exception.status).to be 406 @@ -232,7 +232,7 @@ end it 'fails with 406 Not Acceptable if header contains a single invalid accept' do - expect { subject.call('HTTP_ACCEPT' => 'application/json;application/vnd.vendor-v1+json').first } + expect { subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/json;application/vnd.vendor-v1+json').first } .to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql({}) @@ -242,7 +242,7 @@ end it 'succeeds if proper header is set' do - expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1+json').first).to eq(200) end end @@ -252,15 +252,15 @@ end it 'succeeds with v1' do - expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v1+json').first).to eq(200) end it 'succeeds with v2' do - expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v2+json').first).to eq(200) + expect(subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v2+json').first).to eq(200) end it 'fails with another version' do - expect { subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v3+json') }.to raise_exception do |exception| + expect { subject.call(Grape::Http::Headers::HTTP_ACCEPT => 'application/vnd.vendor-v3+json') }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidVersionHeader) expect(exception.headers).to eql(Grape::Http::Headers::X_CASCADE => 'pass') expect(exception.status).to be 406 diff --git a/spec/grape/middleware/versioner/param_spec.rb b/spec/grape/middleware/versioner/param_spec.rb index 9c2e540efa..00099dfc91 100644 --- a/spec/grape/middleware/versioner/param_spec.rb +++ b/spec/grape/middleware/versioner/param_spec.rb @@ -3,19 +3,19 @@ describe Grape::Middleware::Versioner::Param do subject { described_class.new(app, **options) } - let(:app) { ->(env) { [200, env, env['api.version']] } } + let(:app) { ->(env) { [200, env, env[Grape::Env::API_VERSION]] } } let(:options) { {} } it 'sets the API version based on the default param (apiver)' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' }) - expect(subject.call(env)[1]['api.version']).to eq('v1') + expect(subject.call(env)[1][Grape::Env::API_VERSION]).to eq('v1') end it 'cuts (only) the version out of the params' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1', 'other_param' => '5' }) - env['rack.request.query_hash'] = Rack::Utils.parse_nested_query(env['QUERY_STRING']) - expect(subject.call(env)[1]['rack.request.query_hash']['apiver']).to be_nil - expect(subject.call(env)[1]['rack.request.query_hash']['other_param']).to eq('5') + env[Rack::RACK_REQUEST_QUERY_HASH] = Rack::Utils.parse_nested_query(env[Rack::QUERY_STRING]) + expect(subject.call(env)[1][Rack::RACK_REQUEST_QUERY_HASH]['apiver']).to be_nil + expect(subject.call(env)[1][Rack::RACK_REQUEST_QUERY_HASH]['other_param']).to eq('5') end it 'provides a nil version if no version is given' do @@ -28,12 +28,12 @@ it 'sets the API version based on the custom parameter name' do env = Rack::MockRequest.env_for('/awesome', params: { 'v' => 'v1' }) - expect(subject.call(env)[1]['api.version']).to eq('v1') + expect(subject.call(env)[1][Grape::Env::API_VERSION]).to eq('v1') end it 'does not set the API version based on the default param' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' }) - expect(subject.call(env)[1]['api.version']).to be_nil + expect(subject.call(env)[1][Grape::Env::API_VERSION]).to be_nil end end @@ -47,7 +47,7 @@ it 'allows versions that have been specified' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' }) - expect(subject.call(env)[1]['api.version']).to eq('v1') + expect(subject.call(env)[1][Grape::Env::API_VERSION]).to eq('v1') end end diff --git a/spec/grape/middleware/versioner/path_spec.rb b/spec/grape/middleware/versioner/path_spec.rb index d5b28a88b1..79aff53761 100644 --- a/spec/grape/middleware/versioner/path_spec.rb +++ b/spec/grape/middleware/versioner/path_spec.rb @@ -3,30 +3,30 @@ describe Grape::Middleware::Versioner::Path do subject { described_class.new(app, **options) } - let(:app) { ->(env) { [200, env, env['api.version']] } } + let(:app) { ->(env) { [200, env, env[Grape::Env::API_VERSION]] } } let(:options) { {} } it 'sets the API version based on the first path' do - expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1') + expect(subject.call(Rack::PATH_INFO => '/v1/awesome').last).to eq('v1') end it 'does not cut the version out of the path' do - expect(subject.call('PATH_INFO' => '/v1/awesome')[1]['PATH_INFO']).to eq('/v1/awesome') + expect(subject.call(Rack::PATH_INFO => '/v1/awesome')[1][Rack::PATH_INFO]).to eq('/v1/awesome') end it 'provides a nil version if no path is given' do - expect(subject.call('PATH_INFO' => '/').last).to be_nil + expect(subject.call(Rack::PATH_INFO => '/').last).to be_nil end context 'with a pattern' do let(:options) { { pattern: /v./i } } it 'sets the version if it matches' do - expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1') + expect(subject.call(Rack::PATH_INFO => '/v1/awesome').last).to eq('v1') end it 'ignores the version if it fails to match' do - expect(subject.call('PATH_INFO' => '/awesome/radical').last).to be_nil + expect(subject.call(Rack::PATH_INFO => '/awesome/radical').last).to be_nil end end @@ -35,11 +35,11 @@ let(:options) { { versions: versions } } it 'throws an error if a non-allowed version is specified' do - expect(catch(:error) { subject.call('PATH_INFO' => '/v3/awesome') }[:status]).to eq(404) + expect(catch(:error) { subject.call(Rack::PATH_INFO => '/v3/awesome') }[:status]).to eq(404) end it 'allows versions that have been specified' do - expect(subject.call('PATH_INFO' => '/v1/asoasd').last).to eq('v1') + expect(subject.call(Rack::PATH_INFO => '/v1/asoasd').last).to eq('v1') end end end @@ -48,7 +48,7 @@ let(:options) { { prefix: '/v1', pattern: /v./i } } it 'recognizes potential version' do - expect(subject.call('PATH_INFO' => '/v3/foo').last).to eq('v3') + expect(subject.call(Rack::PATH_INFO => '/v3/foo').last).to eq('v3') end end @@ -56,7 +56,7 @@ let(:options) { { mount_path: '/mounted', versions: [:v1] } } it 'recognizes potential version' do - expect(subject.call('PATH_INFO' => '/mounted/v1/foo').last).to eq('v1') + expect(subject.call(Rack::PATH_INFO => '/mounted/v1/foo').last).to eq('v1') end end end diff --git a/spec/grape/request_spec.rb b/spec/grape/request_spec.rb index 4c235ebf23..298c70513b 100644 --- a/spec/grape/request_spec.rb +++ b/spec/grape/request_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true describe Grape::Request do - let(:default_method) { 'GET' } + let(:default_method) { Rack::GET } let(:default_params) { {} } let(:default_options) do { diff --git a/spec/grape/util/accept_header_handler_spec.rb b/spec/grape/util/accept_header_handler_spec.rb index de85ed26b5..6c94f05ecc 100644 --- a/spec/grape/util/accept_header_handler_spec.rb +++ b/spec/grape/util/accept_header_handler_spec.rb @@ -84,7 +84,7 @@ context 'when allowed_methods present' do subject { instance.match_best_quality_media_type!(allowed_methods: allowed_methods) } - let(:allowed_methods) { ['OPTIONS'] } + let(:allowed_methods) { [Rack::OPTIONS] } it { is_expected.to match_array(allowed_methods) } end diff --git a/spec/grape/validations/validators/presence_spec.rb b/spec/grape/validations/validators/presence_spec.rb index 349fcf8d0d..e49d5f4d01 100644 --- a/spec/grape/validations/validators/presence_spec.rb +++ b/spec/grape/validations/validators/presence_spec.rb @@ -74,12 +74,12 @@ def app expect(last_response.body).to eq('{"error":"id is missing"}') io = StringIO.new('{"id" : "a56b"}') - post '/', {}, 'rack.input' => io, 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => io.length + post '/', {}, Rack::RACK_INPUT => io, 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => io.length expect(last_response.body).to eq('{"error":"id is invalid"}') expect(last_response.status).to eq(400) io = StringIO.new('{"id" : 56}') - post '/', {}, 'rack.input' => io, 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => io.length + post '/', {}, Rack::RACK_INPUT => io, 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => io.length expect(last_response.body).to eq('{"ret":56}') expect(last_response.status).to eq(201) end diff --git a/spec/integration/hashie/hashie_spec.rb b/spec/integration/hashie/hashie_spec.rb index 094c686db4..8c8314997f 100644 --- a/spec/integration/hashie/hashie_spec.rb +++ b/spec/integration/hashie/hashie_spec.rb @@ -108,7 +108,7 @@ end describe 'Grape::Request' do - let(:default_method) { 'GET' } + let(:default_method) { Rack::GET } let(:default_params) { {} } let(:default_options) do { diff --git a/spec/integration/rack_2_0/headers_spec.rb b/spec/integration/rack_2_0/headers_spec.rb deleted file mode 100644 index ad3408019a..0000000000 --- a/spec/integration/rack_2_0/headers_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -describe Grape::Http::Headers, if: Gem::Version.new(Rack.release) < Gem::Version.new('3.0.0') do - it { expect(described_class::ALLOW).to eq('Allow') } - it { expect(described_class::LOCATION).to eq('Location') } - it { expect(described_class::TRANSFER_ENCODING).to eq('Transfer-Encoding') } - it { expect(described_class::X_CASCADE).to eq('X-Cascade') } -end diff --git a/spec/integration/rack_3_0/headers_spec.rb b/spec/integration/rack_3_0/headers_spec.rb index 1007cd4389..dc5118759a 100644 --- a/spec/integration/rack_3_0/headers_spec.rb +++ b/spec/integration/rack_3_0/headers_spec.rb @@ -1,8 +1,77 @@ # frozen_string_literal: true describe Grape::Http::Headers, if: Gem::Version.new(Rack.release) >= Gem::Version.new('3') do - it { expect(described_class::ALLOW).to eq('allow') } - it { expect(described_class::LOCATION).to eq('location') } - it { expect(described_class::TRANSFER_ENCODING).to eq('transfer-encoding') } - it { expect(described_class::X_CASCADE).to eq('x-cascade') } + subject { last_response.headers } + + describe 'returned headers should all be in lowercase' do + context 'when setting an header in an API' do + let(:app) do + Class.new(Grape::API) do + get do + header['GRAPE'] = '1' + return_no_content + end + end + end + + before { get '/' } + + it { is_expected.to include('grape' => '1') } + end + + context 'when error!' do + let(:app) do + Class.new(Grape::API) do + rescue_from ArgumentError do + error!('error!', 500, { 'GRAPE' => '1' }) + end + + get { raise ArgumentError } + end + end + + before { get '/' } + + it { is_expected.to include('grape' => '1') } + end + + context 'when redirect' do + let(:app) do + Class.new(Grape::API) do + get do + redirect 'https://www.ruby-grape.org/' + end + end + end + + before { get '/' } + + it { is_expected.to include('location' => 'https://www.ruby-grape.org/') } + end + + context 'when options' do + let(:app) do + Class.new(Grape::API) do + get { return_no_content } + end + end + + before { options '/' } + + it { is_expected.to include('allow' => 'OPTIONS, GET, HEAD') } + end + + context 'when cascade' do + let(:app) do + Class.new(Grape::API) do + version 'v0', using: :path, cascade: true + get { return_no_content } + end + end + + before { get '/v1' } + + it { is_expected.to include('x-cascade' => 'pass') } + end + end end diff --git a/spec/shared/versioning_examples.rb b/spec/shared/versioning_examples.rb index 192d7bd03b..0215a7c440 100644 --- a/spec/shared/versioning_examples.rb +++ b/spec/shared/versioning_examples.rb @@ -5,7 +5,7 @@ subject.format :txt subject.version 'v1', macro_options subject.get :hello do - "Version: #{request.env['api.version']}" + "Version: #{request.env[Grape::Env::API_VERSION]}" end versioned_get '/hello', 'v1', **macro_options expect(last_response.body).to eql 'Version: v1' @@ -16,7 +16,7 @@ subject.prefix 'api' subject.version 'v1', macro_options subject.get :hello do - "Version: #{request.env['api.version']}" + "Version: #{request.env[Grape::Env::API_VERSION]}" end versioned_get '/hello', 'v1', **macro_options.merge(prefix: 'api') expect(last_response.body).to eql 'Version: v1' @@ -65,12 +65,12 @@ subject.format :txt subject.version 'v2', macro_options subject.get 'version' do - request.env['api.version'] + request.env[Grape::Env::API_VERSION] end subject.version 'v1', macro_options do get 'version' do - "version #{request.env['api.version']}" + "version #{request.env[Grape::Env::API_VERSION]}" end end @@ -89,12 +89,12 @@ subject.prefix 'api' subject.version 'v2', macro_options subject.get 'version' do - request.env['api.version'] + request.env[Grape::Env::API_VERSION] end subject.version 'v1', macro_options do get 'version' do - "version #{request.env['api.version']}" + "version #{request.env[Grape::Env::API_VERSION]}" end end diff --git a/spec/support/cookie_jar.rb b/spec/support/cookie_jar.rb index 1e67a95a60..e36ec66cc8 100644 --- a/spec/support/cookie_jar.rb +++ b/spec/support/cookie_jar.rb @@ -5,7 +5,7 @@ module Rack class MockResponse def cookie_jar - @cookie_jar ||= Array(headers['Set-Cookie']).flat_map { |h| h.split("\n") }.map { |c| Cookie.new(c).to_h } + @cookie_jar ||= Array(headers[Rack::SET_COOKIE]).flat_map { |h| h.split("\n") }.map { |c| Cookie.new(c).to_h } end # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie diff --git a/spec/support/endpoint_faker.rb b/spec/support/endpoint_faker.rb index 773eb85a30..8e597520e3 100644 --- a/spec/support/endpoint_faker.rb +++ b/spec/support/endpoint_faker.rb @@ -17,7 +17,7 @@ def call(env) @request = Grape::Request.new(env.dup) end - @app.call(env.merge('api.endpoint' => @endpoint)) + @app.call(env.merge(Grape::Env::API_ENDPOINT => @endpoint)) end end end diff --git a/spec/support/versioned_helpers.rb b/spec/support/versioned_helpers.rb index ea78013d43..e216f7c8f6 100644 --- a/spec/support/versioned_helpers.rb +++ b/spec/support/versioned_helpers.rb @@ -29,14 +29,14 @@ def versioned_headers(**options) {} # no-op when :header { - 'HTTP_ACCEPT' => [ + Grape::Http::Headers::HTTP_ACCEPT => [ "application/vnd.#{options[:vendor]}-#{options[:version]}", options[:format] ].compact.join('+') } when :accept_version_header { - 'HTTP_ACCEPT_VERSION' => options[:version].to_s + Grape::Http::Headers::HTTP_ACCEPT_VERSION => options[:version].to_s } else raise ArgumentError.new("unknown versioning strategy: #{options[:using]}")