Skip to content

Serialize parameters with Arrays and Hashes properly. #51

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

Merged
merged 5 commits into from
Sep 19, 2012
Merged
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
@@ -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
@@ -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`
@@ -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
@@ -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"
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

@@ -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
6 changes: 6 additions & 0 deletions lib/rspec_api_documentation/oauth2_mac_client.rb
Original file line number Diff line number Diff line change
@@ -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
36 changes: 35 additions & 1 deletion spec/dsl_spec.rb
Original file line number Diff line number Diff line change
@@ -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
@@ -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"