Skip to content

Commit

Permalink
Add support for :query_params to set query parameters for non-GET req…
Browse files Browse the repository at this point in the history
…uests

This allows you to set both body parameters (:params) and query
parameters (:query_params) for non-GET requests.

For consistency, GET requests also support :query_params.  If both
:params and :query_params are provided, :params will append to the
existing query before :query_params.

Implements #150.
  • Loading branch information
jeremyevans committed May 2, 2022
1 parent 736a1f9 commit 463ad89
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
20 changes: 15 additions & 5 deletions lib/rack/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -230,17 +230,17 @@ def env_for(uri, env)
# Stringifying and upcasing methods has be commit upstream
env['REQUEST_METHOD'] ||= env[:method] ? env[:method].to_s.upcase : 'GET'

params = env.delete(:params) do {} end
params = env.delete(:params)
query_array = [uri.query]

if env['REQUEST_METHOD'] == 'GET'
# merge :params with the query string
# Treat params as query params
if params
params = parse_nested_query(params) if params.is_a?(String)

uri.query = [uri.query, build_nested_query(params)].compact.reject { |v| v == '' }.join('&')
append_query_params(query_array, params)
end
elsif !env.key?(:input)
env['CONTENT_TYPE'] ||= 'application/x-www-form-urlencoded'
params ||= {}

if params.is_a?(Hash)
if data = build_multipart(params)
Expand All @@ -257,11 +257,21 @@ def env_for(uri, env)
end
end

if query_params = env.delete(:query_params)
append_query_params(query_array, query_params)
end
uri.query = query_array.compact.reject { |v| v == '' }.join('&')

set_cookie(env.delete(:cookie), uri) if env.key?(:cookie)

Rack::MockRequest.env_for(uri.to_s, env)
end

def append_query_params(query_array, query_params)
query_params = parse_nested_query(query_params) if query_params.is_a?(String)
query_array << build_nested_query(query_params)
end

def multipart_content_type(env)
requested_content_type = env['CONTENT_TYPE']
if requested_content_type.start_with?('multipart/')
Expand Down
29 changes: 28 additions & 1 deletion spec/rack/test_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,38 @@
end
end

it 'supports sending :params' do
it 'supports sending :params for GET' do
request '/', params: { 'foo' => 'bar' }
expect(last_request.GET['foo']).to eq('bar')
end

it 'supports sending :query_params for GET' do
request '/', query_params: { 'foo' => 'bar' }
expect(last_request.GET['foo']).to eq('bar')
end

it 'supports sending both :params and :query_params for GET' do
request '/', query_params: { 'foo' => 'bar' }, params: { 'foo2' => 'bar2' }
expect(last_request.GET['foo']).to eq('bar')
expect(last_request.GET['foo2']).to eq('bar2')
end

it 'supports sending :params for POST' do
request '/', method: :post, params: { 'foo' => 'bar' }
expect(last_request.POST['foo']).to eq('bar')
end

it 'supports sending :query_params for POST' do
request '/', method: :post, query_params: { 'foo' => 'bar' }
expect(last_request.GET['foo']).to eq('bar')
end

it 'supports sending both :params and :query_params for POST' do
request '/', method: :post, query_params: { 'foo' => 'bar' }, params: { 'foo2' => 'bar2' }
expect(last_request.GET['foo']).to eq('bar')
expect(last_request.POST['foo2']).to eq('bar2')
end

it "doesn't follow redirects by default" do
request '/redirect'
expect(last_response).to be_redirect
Expand Down

0 comments on commit 463ad89

Please sign in to comment.