Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize parameters with Arrays and Hashes properly. #51

Merged
merged 5 commits into from
Sep 19, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion features/oauth2_mac_client.feature
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,38 @@ Feature: Use OAuth2 MAC client as a test client
response.finish
end

run app
end

map "/multiple" do
app = lambda do |env|
if env["HTTP_AUTHORIZATION"].blank?
return [401, {"Content-Type" => "text/plain"}, [""]]
end

request = Rack::Request.new(env)
response = Rack::Response.new
response["Content-Type"] = "text/plain"
response.write("hello #{request.params["targets"].join(", ")}")
response.finish
end

run app
end

map "/multiple_nested" do
app = lambda do |env|
if env["HTTP_AUTHORIZATION"].blank?
return [401, {"Content-Type" => "text/plain"}, [""]]
end

request = Rack::Request.new(env)
response = Rack::Response.new
response["Content-Type"] = "text/plain"
response.write("hello #{request.params["targets"].sort.map {|company, products| company.to_s + ' with ' + products.join(' and ')}.join(", ")}")
response.finish
end

run app
end
end
Expand All @@ -50,6 +82,35 @@ Feature: Use OAuth2 MAC client as a test client
response_body.should eq('hello rspec_api_documentation')
end
end

get "/multiple" do
parameter :targets, "The people you want to greet"

let(:targets) { ["eric", "sam"] }

example "Greeting your favorite people" do
do_request

response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq("hello eric, sam")
end
end

get "/multiple_nested" do
parameter :targets, "The companies you want to greet"

let(:targets) { { "apple" => ['mac', 'ios'], "google" => ['search', 'mail']} }

example "Greeting your favorite companies" do
do_request

response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq("hello apple with mac and ios, google with search and mail")
end
end

end
"""
When I run `rspec app_spec.rb --format RspecApiDocumentation::ApiFormatter`
Expand All @@ -61,6 +122,10 @@ Feature: Use OAuth2 MAC client as a test client
Greetings
GET /
* Greeting your favorite gem
GET /multiple
* Greeting your favorite people
GET /multiple_nested
* Greeting your favorite companies
"""
And the output should contain "1 example, 0 failures"
And the output should contain "3 examples, 0 failures"
And the exit status should be 0
2 changes: 1 addition & 1 deletion gemfiles/minimum_dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ gem "rspec", "2.6.0"
gem "activesupport", "3.0.0"
gem "i18n", "0.4.0"
gem "mustache", "0.99.4"
gem "webmock", "1.8.0"
gem "webmock", "1.8.8"
gem "json", "1.4.6"
gem "rack-test", "0.5.5"
gem "rack-oauth2", "0.14.4"
Expand Down
9 changes: 4 additions & 5 deletions lib/rspec_api_documentation/dsl/endpoint.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
require 'rspec/core/formatters/base_formatter'
require 'rack/utils'
require 'rack/test/utils'

module RspecApiDocumentation::DSL
module Endpoint
extend ActiveSupport::Concern
include Rack::Test::Utils

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

Expand Down Expand Up @@ -45,11 +48,7 @@ def do_request(extra_params = {})
end

def query_string
query = params.to_a.map do |param|
param.map! { |a| CGI.escape(a.to_s) }
param.join("=")
end
query.join("&")
build_nested_query(params || {})
end

def params
Expand Down
6 changes: 6 additions & 0 deletions lib/rspec_api_documentation/oauth2_mac_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,15 @@ def do_request(method, path, params, request_headers)

class ProxyApp < Struct.new(:client, :app)
def call(env)
env["QUERY_STRING"] = query_string_hack(env)
client.last_request = Struct.new(:env, :content_type).new(env, env["CONTENT_TYPE"])
app.call(env.merge("SCRIPT_NAME" => ""))
end

private
def query_string_hack(env)
env["QUERY_STRING"].gsub('%5B', '[').gsub('%5D', ']').gsub(/\[\d+/) { |s| "#{$1}[" }
end
end

def access_token
Expand Down
36 changes: 35 additions & 1 deletion spec/dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@
trigger_callback do
uri = URI.parse(callback_url)
Net::HTTP.start(uri.host, uri.port) do |http|
# debugger
http.request Net::HTTP::Post.new(uri.path)
end
end
Expand Down Expand Up @@ -380,6 +379,41 @@
end
end

context "proper query_string serialization" do
get "/orders" do
context "with an array parameter" do
parameter :id_eq, "List of IDs"

let(:id_eq) { [1, 2] }

example "parsed properly" do
client.should_receive(:get).with do |path, data, headers|
Rack::Utils.parse_nested_query(path.gsub('/orders?', '')).should eq({"id_eq"=>['1', '2']})
end
do_request
end
end

context "with a deep nested parameter, including Hashes and Arrays" do
parameter :within_id, "Fancy search condition"

let(:within_id) { {"first" => 1, "last" => 10, "exclude" => [3,5,7]} }
scope_parameters :search, :all

example "parsed properly" do
client.should_receive(:get).with do |path, data, headers|
Rack::Utils.parse_nested_query(path.gsub('/orders?', '')).should eq({
"search" => { "within_id" => {"first" => '1', "last" => '10', "exclude" => ['3','5','7']}}
})
end
do_request
end
end
end
end



context "auto request" do
post "/orders" do
parameter :order_type, "Type of order"
Expand Down