Skip to content

Commit cbaf7d8

Browse files
authored
Merge pull request ota42y#128 from yckimura/fix-nullable
Fix nullable field does not work with allOf, anyOf and oneOf keyword
2 parents 2914d2e + e0c225d commit cbaf7d8

File tree

5 files changed

+90
-0
lines changed

5 files changed

+90
-0
lines changed

lib/openapi_parser/schema_validator/all_of_validator.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ class AllOfValidator < Base
55
# @param [Object] value
66
# @param [OpenAPIParser::Schemas::Schema] schema
77
def coerce_and_validate(value, schema, **keyword_args)
8+
if value.nil? && schema.nullable
9+
return [value, nil]
10+
end
11+
812
# if any schema return error, it's not valida all of value
913
remaining_keys = value.kind_of?(Hash) ? value.keys : []
1014
nested_additional_properties = false

lib/openapi_parser/schema_validator/any_of_validator.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ class AnyOfValidator < Base
33
# @param [Object] value
44
# @param [OpenAPIParser::Schemas::Schema] schema
55
def coerce_and_validate(value, schema, **_keyword_args)
6+
if value.nil? && schema.nullable
7+
return [value, nil]
8+
end
69
if schema.discriminator
710
return validate_discriminator_schema(schema.discriminator, value)
811
end

lib/openapi_parser/schema_validator/one_of_validator.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ class OneOfValidator < Base
33
# @param [Object] value
44
# @param [OpenAPIParser::Schemas::Schema] schema
55
def coerce_and_validate(value, schema, **_keyword_args)
6+
if value.nil? && schema.nullable
7+
return [value, nil]
8+
end
69
if schema.discriminator
710
return validate_discriminator_schema(schema.discriminator, value)
811
end

spec/data/normal.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ paths:
245245
id:
246246
type: integer
247247
format: int64
248+
all_of_with_nullable:
249+
nullable: true
250+
allOf:
251+
- type: integer
248252
one_of_data:
249253
oneOf:
250254
- $ref: '#/components/schemas/one_of_object1'
@@ -258,6 +262,10 @@ paths:
258262
mapping:
259263
obj1: '#/components/schemas/one_of_object1'
260264
obj2: '#/components/schemas/one_of_object2'
265+
one_of_with_nullable:
266+
nullable: true
267+
oneOf:
268+
- type: integer
261269
object_1:
262270
type: object
263271
properties:
@@ -314,6 +322,10 @@ paths:
314322
anyOf:
315323
- type: string
316324
- type: boolean
325+
any_of_with_nullable:
326+
nullable: true
327+
anyOf:
328+
- type: integer
317329
unspecified_type: {}
318330
enum_string:
319331
type: string

spec/openapi_parser/schema_validator_spec.rb

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,28 @@
209209
end
210210
end
211211

212+
context 'anyOf with nullable' do
213+
subject { request_operation.validate_request_body(content_type, { 'any_of_with_nullable' => params }) }
214+
215+
context 'integer' do
216+
let(:params) { 1 }
217+
218+
it { expect(subject).to eq({ 'any_of_with_nullable' => 1 }) }
219+
end
220+
221+
context 'null' do
222+
let(:params) { nil }
223+
224+
it { expect(subject).to eq({ 'any_of_with_nullable' => nil }) }
225+
end
226+
227+
context 'invalid' do
228+
let(:params) { 'foo' }
229+
230+
it { expect { subject }.to raise_error(OpenAPIParser::NotAnyOf) }
231+
end
232+
end
233+
212234
context 'unspecified_type' do
213235
it do
214236
expect(request_operation.validate_request_body(content_type, { 'unspecified_type' => "foo" })).
@@ -369,6 +391,30 @@
369391
end
370392
end
371393

394+
describe 'allOf with nullable' do
395+
context 'with nullable' do
396+
subject { request_operation.validate_request_body(content_type, { 'all_of_with_nullable' => params }) }
397+
398+
context 'integer' do
399+
let(:params) { 1 }
400+
401+
it { expect(subject).to eq({ 'all_of_with_nullable' => 1 }) }
402+
end
403+
404+
context 'null' do
405+
let(:params) { nil }
406+
407+
it { expect(subject).to eq({ 'all_of_with_nullable' => nil }) }
408+
end
409+
410+
context 'invalid' do
411+
let(:params) { 'foo' }
412+
413+
it { expect { subject }.to raise_error(::OpenAPIParser::ValidateError) }
414+
end
415+
end
416+
end
417+
372418
describe 'one_of' do
373419
context 'normal' do
374420
subject { request_operation.validate_request_body(content_type, { 'one_of_data' => params }) }
@@ -430,6 +476,28 @@
430476

431477
it { expect(subject).not_to eq nil }
432478
end
479+
480+
context 'with nullable' do
481+
subject { request_operation.validate_request_body(content_type, { 'one_of_with_nullable' => params }) }
482+
483+
context 'integer' do
484+
let(:params) { 1 }
485+
486+
it { expect(subject).to eq({ 'one_of_with_nullable' => 1 }) }
487+
end
488+
489+
context 'null' do
490+
let(:params) { nil }
491+
492+
it { expect(subject).to eq({ 'one_of_with_nullable' => nil }) }
493+
end
494+
495+
context 'invalid' do
496+
let(:params) { 'foo' }
497+
498+
it { expect { subject }.to raise_error(OpenAPIParser::NotOneOf) }
499+
end
500+
end
433501
end
434502

435503
it 'unknown param' do

0 commit comments

Comments
 (0)