Skip to content

Commit 6167858

Browse files
authored
Merge branch 'master' into handle-route-prefixes
2 parents f70bcbc + 3de44a3 commit 6167858

File tree

8 files changed

+109
-14
lines changed

8 files changed

+109
-14
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#### Fixes
88

99
* [#758](https://github.com/ruby-grape/grape-swagger/pull/758): Handle cases where a route's prefix is a nested URL - [@SimonKaluza](https://github.com/simonkaluza).
10+
* [#757](https://github.com/ruby-grape/grape-swagger/pull/757): Fix `array_use_braces` for nested body params - [@bikolya](https://github.com/bikolya).
11+
* [#756](https://github.com/ruby-grape/grape-swagger/pull/756): Fix reference creation when custom type for documentation is provided - [@bikolya](https://github.com/bikolya).
1012

1113
### 0.33.0 (June 21, 2019)
1214

lib/grape-swagger/doc_methods/extensions.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,12 @@ def extension(part, identifier = :x)
8787
part.select { |x| x == identifier }
8888
end
8989

90-
def method
90+
def method(*args)
91+
# We're shadowing Object.method(:symbol) here so we provide
92+
# a compatibility layer for code that introspects the methods
93+
# of this class
94+
return super if args.size.positive?
95+
9196
@route.request_method.downcase.to_sym
9297
end
9398
end

lib/grape-swagger/endpoint.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,10 @@ def params_object(route, options, path)
178178
parameters = partition_params(route, options).map do |param, value|
179179
value = { required: false }.merge(value) if value.is_a?(Hash)
180180
_, value = default_type([[param, value]]).first if value == ''
181-
if value[:type]
182-
expose_params(value[:type])
183-
elsif value[:documentation]
181+
if value.dig(:documentation, :type)
184182
expose_params(value[:documentation][:type])
183+
elsif value[:type]
184+
expose_params(value[:type])
185185
end
186186
GrapeSwagger::DocMethods::ParseParams.call(param, value, path, route, @definitions)
187187
end

lib/grape-swagger/endpoint/params_parser.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,14 @@ def initialize(params, settings)
1515
end
1616

1717
def parse_request_params
18-
array_keys = []
1918
public_params.each_with_object({}) do |(name, options), memo|
2019
name = name.to_s
2120
param_type = options[:type]
2221
param_type = param_type.to_s unless param_type.nil?
2322

2423
if param_type_is_array?(param_type)
25-
array_keys << name
2624
options[:is_array] = true
27-
28-
name += '[]' if array_use_braces?(options)
25+
name += '[]' if array_use_braces?
2926
end
3027

3128
memo[name] = options
@@ -34,8 +31,8 @@ def parse_request_params
3431

3532
private
3633

37-
def array_use_braces?(options)
38-
settings[:array_use_braces] && !(options[:documentation] && options[:documentation][:param_type] == 'body')
34+
def array_use_braces?
35+
@array_use_braces ||= settings[:array_use_braces] && !includes_body_param?
3936
end
4037

4138
def param_type_is_array?(param_type)
@@ -61,6 +58,12 @@ def public_parameter?(param)
6158
param_hidden = param_hidden.call if param_hidden.is_a?(Proc)
6259
!param_hidden
6360
end
61+
62+
def includes_body_param?
63+
params.any? do |_, options|
64+
options.dig(:documentation, :param_type) == 'body' || options.dig(:documentation, :in) == 'body'
65+
end
66+
end
6467
end
6568
end
6669
end

spec/lib/endpoint/params_parser_spec.rb

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,53 @@
5656
end
5757

5858
context 'when param is nested in a param of hash type' do
59-
let(:params) { [['param_1', { type: 'Hash' }], ['param_1[param_2]', { type: 'String' }]] }
59+
let(:params) { [param_1, param_2] }
60+
let(:param_1) { ['param_1', { type: 'Hash' }] }
61+
let(:param_2) { ['param_1[param_2]', { type: 'String' }] }
6062

6163
context 'and array_use_braces setting set to true' do
6264
let(:settings) { { array_use_braces: true } }
6365

64-
it 'does not add braces to the param key' do
65-
expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
66+
context 'and param is of simple type' do
67+
it 'does not add braces to the param key' do
68+
expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
69+
end
70+
end
71+
72+
context 'and param is of array type' do
73+
let(:param_2) { ['param_1[param_2]', { type: 'Array[String]' }] }
74+
75+
it 'adds braces to the param key' do
76+
expect(parse_request_params.keys.last).to eq 'param_1[param_2][]'
77+
end
78+
79+
context 'and `param_type` option is set to body' do
80+
let(:param_2) do
81+
['param_1[param_2]', { type: 'Array[String]', documentation: { param_type: 'body' } }]
82+
end
83+
84+
it 'does not add braces to the param key' do
85+
expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
86+
end
87+
end
88+
89+
context 'and `in` option is set to body' do
90+
let(:param_2) do
91+
['param_1[param_2]', { type: 'Array[String]', documentation: { in: 'body' } }]
92+
end
93+
94+
it 'does not add braces to the param key' do
95+
expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
96+
end
97+
end
98+
99+
context 'and hash `param_type` option is set to body' do
100+
let(:param_1) { ['param_1', { type: 'Hash', documentation: { param_type: 'body' } }] }
101+
102+
it 'does not add braces to the param key' do
103+
expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
104+
end
105+
end
66106
end
67107
end
68108
end

spec/lib/extensions_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
require 'spec_helper'
44

55
describe GrapeSwagger::DocMethods::Extensions do
6+
context 'it should not break method introspection' do
7+
describe '.method' do
8+
describe 'method introspection' do
9+
specify do
10+
expect(described_class.method(described_class.methods.first)).to be_a(Method)
11+
end
12+
end
13+
end
14+
end
15+
616
describe '#find_definition' do
717
subject { described_class }
818

spec/swagger_v2/api_swagger_v2_hash_and_array_spec.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ module TheApi
1010
class TestApi < Grape::API
1111
format :json
1212

13-
documentation = ::Entities::DocumentedHashAndArrayModel.documentation if ::Entities::DocumentedHashAndArrayModel.respond_to?(:documentation)
13+
if ::Entities::DocumentedHashAndArrayModel.respond_to?(:documentation)
14+
documentation = ::Entities::DocumentedHashAndArrayModel.documentation
15+
end
1416

1517
desc 'This returns something'
1618
namespace :arbitrary do

spec/swagger_v2/endpoint_versioned_path_spec.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,39 @@
5252
expect(subject.first['/v1/item'][:get][:tags]).to eq ['special-item']
5353
end
5454
end
55+
56+
context 'when parameter with a custom type is specified' do
57+
let(:item) do
58+
Class.new(Grape::API) do
59+
Color = Struct.new(:value) do
60+
def self.parse(value)
61+
new(value: value)
62+
end
63+
end
64+
65+
class ColorEntity < Grape::Entity
66+
expose :value
67+
end
68+
69+
version 'v1', using: :path
70+
71+
resource :item do
72+
params do
73+
requires :root, type: Hash do
74+
optional :color, type: Color, documentation: { type: ColorEntity }
75+
end
76+
end
77+
post '/'
78+
end
79+
end
80+
end
81+
82+
it 'creates a reference to the model instead of using the non-existent type' do
83+
color = subject.dig(1, 'postV1Item', :properties, :root, :properties, :color)
84+
expect(color).not_to eq(type: 'ColorEntity')
85+
expect(color).to eq('$ref' => '#/definitions/ColorEntity')
86+
end
87+
end
5588
end
5689

5790
context 'when mounting an API more than once', if: GrapeVersion.satisfy?('>= 1.2.0') do

0 commit comments

Comments
 (0)