Skip to content

Commit 38071c8

Browse files
committed
Merge pull request #51 from denyago/master
Serialize parameters with Arrays and Hashes properly.
2 parents 4c76c40 + 4c12172 commit 38071c8

File tree

5 files changed

+112
-8
lines changed

5 files changed

+112
-8
lines changed

features/oauth2_mac_client.feature

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,38 @@ Feature: Use OAuth2 MAC client as a test client
3131
response.finish
3232
end
3333
34+
run app
35+
end
36+
37+
map "/multiple" do
38+
app = lambda do |env|
39+
if env["HTTP_AUTHORIZATION"].blank?
40+
return [401, {"Content-Type" => "text/plain"}, [""]]
41+
end
42+
43+
request = Rack::Request.new(env)
44+
response = Rack::Response.new
45+
response["Content-Type"] = "text/plain"
46+
response.write("hello #{request.params["targets"].join(", ")}")
47+
response.finish
48+
end
49+
50+
run app
51+
end
52+
53+
map "/multiple_nested" do
54+
app = lambda do |env|
55+
if env["HTTP_AUTHORIZATION"].blank?
56+
return [401, {"Content-Type" => "text/plain"}, [""]]
57+
end
58+
59+
request = Rack::Request.new(env)
60+
response = Rack::Response.new
61+
response["Content-Type"] = "text/plain"
62+
response.write("hello #{request.params["targets"].sort.map {|company, products| company.to_s + ' with ' + products.join(' and ')}.join(", ")}")
63+
response.finish
64+
end
65+
3466
run app
3567
end
3668
end
@@ -50,6 +82,35 @@ Feature: Use OAuth2 MAC client as a test client
5082
response_body.should eq('hello rspec_api_documentation')
5183
end
5284
end
85+
86+
get "/multiple" do
87+
parameter :targets, "The people you want to greet"
88+
89+
let(:targets) { ["eric", "sam"] }
90+
91+
example "Greeting your favorite people" do
92+
do_request
93+
94+
response_headers["Content-Type"].should eq("text/plain")
95+
status.should eq(200)
96+
response_body.should eq("hello eric, sam")
97+
end
98+
end
99+
100+
get "/multiple_nested" do
101+
parameter :targets, "The companies you want to greet"
102+
103+
let(:targets) { { "apple" => ['mac', 'ios'], "google" => ['search', 'mail']} }
104+
105+
example "Greeting your favorite companies" do
106+
do_request
107+
108+
response_headers["Content-Type"].should eq("text/plain")
109+
status.should eq(200)
110+
response_body.should eq("hello apple with mac and ios, google with search and mail")
111+
end
112+
end
113+
53114
end
54115
"""
55116
When I run `rspec app_spec.rb --format RspecApiDocumentation::ApiFormatter`
@@ -61,6 +122,10 @@ Feature: Use OAuth2 MAC client as a test client
61122
Greetings
62123
GET /
63124
* Greeting your favorite gem
125+
GET /multiple
126+
* Greeting your favorite people
127+
GET /multiple_nested
128+
* Greeting your favorite companies
64129
"""
65-
And the output should contain "1 example, 0 failures"
130+
And the output should contain "3 examples, 0 failures"
66131
And the exit status should be 0

gemfiles/minimum_dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ gem "rspec", "2.6.0"
66
gem "activesupport", "3.0.0"
77
gem "i18n", "0.4.0"
88
gem "mustache", "0.99.4"
9-
gem "webmock", "1.8.0"
9+
gem "webmock", "1.8.8"
1010
gem "json", "1.4.6"
1111
gem "rack-test", "0.5.5"
1212
gem "rack-oauth2", "0.14.4"

lib/rspec_api_documentation/dsl/endpoint.rb

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
require 'rspec/core/formatters/base_formatter'
2+
require 'rack/utils'
3+
require 'rack/test/utils'
24

35
module RspecApiDocumentation::DSL
46
module Endpoint
57
extend ActiveSupport::Concern
8+
include Rack::Test::Utils
69

710
delegate :response_headers, :status, :response_status, :response_body, :to => :client
811

@@ -45,11 +48,7 @@ def do_request(extra_params = {})
4548
end
4649

4750
def query_string
48-
query = params.to_a.map do |param|
49-
param.map! { |a| CGI.escape(a.to_s) }
50-
param.join("=")
51-
end
52-
query.join("&")
51+
build_nested_query(params || {})
5352
end
5453

5554
def params

lib/rspec_api_documentation/oauth2_mac_client.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,15 @@ def do_request(method, path, params, request_headers)
4848

4949
class ProxyApp < Struct.new(:client, :app)
5050
def call(env)
51+
env["QUERY_STRING"] = query_string_hack(env)
5152
client.last_request = Struct.new(:env, :content_type).new(env, env["CONTENT_TYPE"])
5253
app.call(env.merge("SCRIPT_NAME" => ""))
5354
end
55+
56+
private
57+
def query_string_hack(env)
58+
env["QUERY_STRING"].gsub('%5B', '[').gsub('%5D', ']').gsub(/\[\d+/) { |s| "#{$1}[" }
59+
end
5460
end
5561

5662
def access_token

spec/dsl_spec.rb

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@
246246
trigger_callback do
247247
uri = URI.parse(callback_url)
248248
Net::HTTP.start(uri.host, uri.port) do |http|
249-
# debugger
250249
http.request Net::HTTP::Post.new(uri.path)
251250
end
252251
end
@@ -380,6 +379,41 @@
380379
end
381380
end
382381

382+
context "proper query_string serialization" do
383+
get "/orders" do
384+
context "with an array parameter" do
385+
parameter :id_eq, "List of IDs"
386+
387+
let(:id_eq) { [1, 2] }
388+
389+
example "parsed properly" do
390+
client.should_receive(:get).with do |path, data, headers|
391+
Rack::Utils.parse_nested_query(path.gsub('/orders?', '')).should eq({"id_eq"=>['1', '2']})
392+
end
393+
do_request
394+
end
395+
end
396+
397+
context "with a deep nested parameter, including Hashes and Arrays" do
398+
parameter :within_id, "Fancy search condition"
399+
400+
let(:within_id) { {"first" => 1, "last" => 10, "exclude" => [3,5,7]} }
401+
scope_parameters :search, :all
402+
403+
example "parsed properly" do
404+
client.should_receive(:get).with do |path, data, headers|
405+
Rack::Utils.parse_nested_query(path.gsub('/orders?', '')).should eq({
406+
"search" => { "within_id" => {"first" => '1', "last" => '10', "exclude" => ['3','5','7']}}
407+
})
408+
end
409+
do_request
410+
end
411+
end
412+
end
413+
end
414+
415+
416+
383417
context "auto request" do
384418
post "/orders" do
385419
parameter :order_type, "Type of order"

0 commit comments

Comments
 (0)