diff --git a/CHANGELOG.md b/CHANGELOG.md index 5139357f..cf20845b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ #### Fixes * [#389](https://github.com/ruby-grape/grape-swagger/pull/389): respect X-Forwarded-Host - [@edvakf](https://github.com/edvakf). +* [#393](https://github.com/ruby-grape/grape-swagger/pull/393): properly handle header parameters- [@wleeper](https://github.com/wleeper). ### 0.20.1 / 2016-04-17 diff --git a/lib/grape-swagger/doc_methods.rb b/lib/grape-swagger/doc_methods.rb index 19d4446f..34f3fa73 100644 --- a/lib/grape-swagger/doc_methods.rb +++ b/lib/grape-swagger/doc_methods.rb @@ -9,6 +9,7 @@ require 'grape-swagger/doc_methods/tag_name_description' require 'grape-swagger/doc_methods/parse_params' require 'grape-swagger/doc_methods/move_params' +require 'grape-swagger/doc_methods/headers' module GrapeSwagger module DocMethods diff --git a/lib/grape-swagger/doc_methods/headers.rb b/lib/grape-swagger/doc_methods/headers.rb new file mode 100644 index 00000000..f6cd2501 --- /dev/null +++ b/lib/grape-swagger/doc_methods/headers.rb @@ -0,0 +1,18 @@ +module GrapeSwagger + module DocMethods + class Headers + class << self + def parse(route) + route.route_headers.to_a.map do |route_header| + route_header.tap do |header| + hash = header[1] + description = hash.delete('description') + hash[:documentation] = { desc: description, in: 'header' } + hash[:type] = hash['type'].titleize if hash['type'] + end + end + end + end + end + end +end diff --git a/lib/grape-swagger/endpoint.rb b/lib/grape-swagger/endpoint.rb index 3619ba43..d393253f 100644 --- a/lib/grape-swagger/endpoint.rb +++ b/lib/grape-swagger/endpoint.rb @@ -105,7 +105,6 @@ def path_item(routes, options) def method_object(route, options, path) method = {} method[:description] = description_object(route, options[:markdown]) - method[:headers] = route.route_headers if route.route_headers method[:produces] = produces_object(route, options[:produces] || options[:format]) method[:consumes] = consumes_object(route, options[:format]) method[:parameters] = params_object(route) @@ -194,14 +193,13 @@ def tag_object(route, version) def partition_params(route) declared_params = route.route_settings[:declared_params] if route.route_settings[:declared_params].present? required, exposed = route.route_params.partition { |x| x.first.is_a? String } - + required.concat GrapeSwagger::DocMethods::Headers.parse(route) unless route.route_headers.nil? default_type(required) default_type(exposed) - unless declared_params.nil? + unless declared_params.nil? && route.route_headers.nil? request_params = parse_request_params(required) end - if !exposed.empty? exposed_params = exposed.each_with_object({}) { |x, memo| memo[x.first] = x.last } properties = parse_response_params(exposed_params) @@ -215,8 +213,7 @@ def partition_params(route) @definitions[key] = { type: 'object', properties: properties } unless @definitions.key?(key) @definitions[key][:properties].merge!(properties) if @definitions.key?(key) end - - return route.route_params if route.route_params && !route.route_settings[:declared_params].present? + return route.route_params if route.route_params.present? && !route.route_settings[:declared_params].present? request_params || {} end @@ -244,6 +241,7 @@ def parse_response_params(params) return if params.nil? params.each_with_object({}) do |x, memo| + next if x[1].fetch(:documentation, {}).fetch(:in, nil).to_s == 'header' x[0] = x.last[:as] if x.last[:as] model = x.last[:using] if x.last[:using].present? diff --git a/spec/swagger_v2/api_swagger_v2_headers_spec.rb b/spec/swagger_v2/api_swagger_v2_headers_spec.rb index a0ed41a5..50fae833 100644 --- a/spec/swagger_v2/api_swagger_v2_headers_spec.rb +++ b/spec/swagger_v2/api_swagger_v2_headers_spec.rb @@ -36,9 +36,13 @@ def app end specify do - expect(subject['paths']['/use_headers']['get']).to include('headers') - expect(subject['paths']['/use_headers']['get']['headers']).to eql({ - "X-Rate-Limit-Limit"=>{"description"=>"The number of allowed requests in the current period", "type"=>"integer"} - }) + expect(subject['paths']['/use_headers']['get']['parameters']).to eql([ + {"in"=>"header", + "name"=>"X-Rate-Limit-Limit", + "description"=>"The number of allowed requests in the current period", + "type"=>"integer", + "format" => "int32", + "required"=>false}, + ]) end end diff --git a/spec/swagger_v2/param_type_spec.rb b/spec/swagger_v2/param_type_spec.rb index 26f1cbba..234cea5a 100644 --- a/spec/swagger_v2/param_type_spec.rb +++ b/spec/swagger_v2/param_type_spec.rb @@ -50,7 +50,7 @@ def app it 'has consistent types' do types = subject.map { |param| param['type'] } - expect(types).to eq(%w(string)) + expect(types).to eq(%w(string string)) end end end diff --git a/spec/swagger_v2/simple_mounted_api_spec.rb b/spec/swagger_v2/simple_mounted_api_spec.rb index 8d438969..cb2a7ddd 100644 --- a/spec/swagger_v2/simple_mounted_api_spec.rb +++ b/spec/swagger_v2/simple_mounted_api_spec.rb @@ -97,10 +97,10 @@ def app "/simple_with_headers"=>{ "get"=>{ "description"=>"this gets something else", - "headers"=>{ - "XAuthToken"=>{"description"=>"A required header.", "required"=>true}, - "XOtherHeader"=>{"description"=>"An optional header.", "required"=>false}}, "produces"=>["application/json"], + "parameters"=>[ + {"in"=>"header", "name"=>"XAuthToken", "description"=>"A required header.", "type"=>"string", "required"=>true}, + {"in"=>"header", "name"=>"XOtherHeader", "description"=>"An optional header.", "type"=>"string", "required"=>false}], "tags"=>["simple_with_headers"], "operationId"=>"getSimpleWithHeaders", "responses"=>{ @@ -203,10 +203,10 @@ def app "/simple_with_headers"=>{ "get"=>{ "description"=>"this gets something else", - "headers"=>{ - "XAuthToken"=>{"description"=>"A required header.", "required"=>true}, - "XOtherHeader"=>{"description"=>"An optional header.", "required"=>false}}, "produces"=>["application/json"], + "parameters"=>[ + {"in"=>"header", "name"=>"XAuthToken", "description"=>"A required header.", "type"=>"string", "required"=>true}, + {"in"=>"header", "name"=>"XOtherHeader", "description"=>"An optional header.", "type"=>"string", "required"=>false}], "tags"=>["simple_with_headers"], "operationId"=>"getSimpleWithHeaders", "responses"=>{