Skip to content

Commit

Permalink
Require discriminator propertyName property
Browse files Browse the repository at this point in the history
https://spec.openapis.org/oas/v3.1.0#discriminator-object

> The expectation now is that a property with name petType MUST be present in the response payload

It's a little unclear because the specification examples mostly specify
the `propertyName` property under `required` as well, which seems
redundant. It's probably safer this way, though, and the spec says
"MUST" so we must.
  • Loading branch information
davishmcclurg committed Sep 26, 2023
1 parent 5c002fe commit be45f04
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [2.1.0] - XXXX-XX-XX

### Bug Fixes

- Require discriminator `propertyName` property

[2.1.0]: https://github.com/davishmcclurg/json_schemer/releases/tag/v2.1.0

## [2.0.0] - 2023-08-20
Expand Down
3 changes: 2 additions & 1 deletion lib/json_schemer/openapi31/vocab/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def validate(instance, instance_location, keyword_location, context)
property_name = value.fetch('propertyName')
mapping = value['mapping'] || {}

return result(instance, instance_location, keyword_location, true) unless instance.is_a?(Hash) && instance.key?(property_name)
return result(instance, instance_location, keyword_location, true) unless instance.is_a?(Hash)
return result(instance, instance_location, keyword_location, false) unless instance.key?(property_name)

property = instance.fetch(property_name)
ref = mapping.fetch(property, property)
Expand Down
8 changes: 4 additions & 4 deletions test/open_api_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def test_discriminator_specification_example
assert_equal([['enum', '/components/schemas/Cat/allOf/1/properties/huntingSkill']], schemer.validate(invalid_hunting_skill).map { |error| error.values_at('type', 'schema_pointer') })
assert_equal([['required', '/components/schemas/Dog/allOf/1']], schemer.validate(missing_pack_size).map { |error| error.values_at('type', 'schema_pointer') })
assert_equal([['format', '/components/schemas/Dog/allOf/1/properties/packSize']], schemer.validate(invalid_pack_size).map { |error| error.values_at('type', 'schema_pointer') })
assert_equal([['required', '/components/schemas/Pet']], schemer.validate(missing_pet_type).map { |error| error.values_at('type', 'schema_pointer') })
assert_equal([['required', '/components/schemas/Pet'], ['discriminator', '/components/schemas/Pet']], schemer.validate(missing_pet_type).map { |error| error.values_at('type', 'schema_pointer') })
assert_equal([['required', '/components/schemas/Pet'], ['required', '/components/schemas/Cat/allOf/1']], schemer.validate(missing_name).map { |error| error.values_at('type', 'schema_pointer') })
assert_raises(JSONSchemer::UnknownRef) { schemer.validate(invalid_pet_type) }
end
Expand Down Expand Up @@ -404,7 +404,7 @@ def test_all_of_discriminator_subclass_schemas_work_on_their_own
assert(schemer.valid?(CAT))
assert(schemer.valid?(MISTY))
assert_equal(['/components/schemas/Cat/allOf/1/properties/name'], schemer.validate(INVALID_CAT).map { |error| error.fetch('schema_pointer') })
assert_equal([['required', '/components/schemas/Pet']], schemer.validate({}).map { |error| error.values_at('type', 'schema_pointer') })
assert_equal([['required', '/components/schemas/Pet'], ['discriminator', '/components/schemas/Pet']], schemer.validate({}).map { |error| error.values_at('type', 'schema_pointer') })
end

def test_all_of_discriminator_with_non_discriminator_ref
Expand Down Expand Up @@ -444,7 +444,7 @@ def test_all_of_discriminator_with_non_discriminator_ref
refute(schemer.valid?(CAT))
assert(schemer.valid?(CAT.merge('other' => 'y')))
assert_equal(['/components/schemas/Other', '/components/schemas/Cat/allOf/2/properties/name'], schemer.validate(INVALID_CAT).map { |error| error.fetch('schema_pointer') })
assert_equal([['required', '/components/schemas/Pet'], ['required', '/components/schemas/Other']], schemer.validate({}).map { |error| error.values_at('type', 'schema_pointer') })
assert_equal([['required', '/components/schemas/Pet'], ['discriminator', '/components/schemas/Pet'], ['required', '/components/schemas/Other']], schemer.validate({}).map { |error| error.values_at('type', 'schema_pointer') })
end

def test_any_of_discriminator_without_matching_schema
Expand Down Expand Up @@ -597,7 +597,7 @@ def test_non_json_pointer_discriminator
def test_discriminator_non_object_and_missing_property_name
schemer = JSONSchemer.schema({ 'discriminator' => { 'propertyName' => 'x' } }, :meta_schema => JSONSchemer.openapi31)
assert(schemer.valid?(1))
assert(schemer.valid?({ 'y' => 'z' }))
refute(schemer.valid?({ 'y' => 'z' }))
end

def test_openapi31_formats
Expand Down

0 comments on commit be45f04

Please sign in to comment.