diff --git a/lib/grape-swagger/doc_methods/move_params.rb b/lib/grape-swagger/doc_methods/move_params.rb index ad7f4030..c6b5b23e 100644 --- a/lib/grape-swagger/doc_methods/move_params.rb +++ b/lib/grape-swagger/doc_methods/move_params.rb @@ -86,6 +86,7 @@ def build_properties(params) else document_as_property(param) end + add_extension_properties(properties[name], param) required << name if deletable?(param) && param[:required] end @@ -102,6 +103,12 @@ def document_as_array(param) end end + def add_extension_properties(definition, value) + value.each do |key, value| + definition[key] = value if key.start_with?('x-') + end + end + def document_as_property(param) property_keys.each_with_object({}) do |x, memo| next unless param.key?(x) diff --git a/lib/grape-swagger/doc_methods/parse_params.rb b/lib/grape-swagger/doc_methods/parse_params.rb index 0787b982..6ec8472d 100644 --- a/lib/grape-swagger/doc_methods/parse_params.rb +++ b/lib/grape-swagger/doc_methods/parse_params.rb @@ -108,6 +108,10 @@ def parse_array_item(definitions, type, value_type) set_additional_properties, additional_properties = parse_additional_properties(definitions, value_type) array_items[:additionalProperties] = additional_properties if set_additional_properties + if value_type.key?(:items) + GrapeSwagger::DocMethods::Extensions.add_extensions_to_root(value_type[:items], array_items) + end + array_items end diff --git a/spec/issues/901_extensions_on_body_params_spec.rb b/spec/issues/901_extensions_on_body_params_spec.rb new file mode 100644 index 00000000..66d8e53c --- /dev/null +++ b/spec/issues/901_extensions_on_body_params_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe '#901 params extension does not work when param_type is body' do + let(:app) do + Class.new(Grape::API) do + namespace :issue_901 do + params do + requires :user_id, type: Integer, documentation: { type: 'integer', param_type: 'body', x: { nullable: true } } + requires :friend_ids, type: [Integer], documentation: { type: 'integer', is_array: true, param_type: 'body', x: { type: 'array' }, items: { x: { type: 'item' } } } + requires :address, type: Hash, documentation: { type: 'object', param_type: 'body', x: { type: 'address' } } do + requires :city_id, type: Integer, documentation: { type: 'integer', x: { type: 'city' } } + end + end + post do + present params + end + end + + add_swagger_documentation format: :json + end + end + + subject do + get '/swagger_doc' + JSON.parse(last_response.body) + end + + let(:definition) { subject['definitions']['postIssue901'] } + + specify do + expect(definition['properties']).to match( + 'user_id' => hash_including('type' => 'integer', 'x-nullable' => true), + 'address' => hash_including( + 'type' => 'object', + 'x-type' => 'address', + 'properties' => { + 'city_id' => hash_including('type' => 'integer', 'x-type' => 'city') + } + ), + 'friend_ids' => hash_including( + 'type' => 'array', + 'x-type' => 'array', + 'items' => hash_including('type' => 'integer', 'x-type' => 'item') + ) + ) + end +end