Skip to content

Commit

Permalink
Version specific allow_extensions for Discriminator
Browse files Browse the repository at this point in the history
A change in OpenAPI 3.1 is that the Discriminator object can accept
extensions, when previously this was not allowed.

In order to code this I've had to adjust the DSL so that the
allow_extensions method can accept a block.

We didn't have unit tests for the DSL so I'm only testing this at the
node level. This should be ok as it has full coverage.
  • Loading branch information
kevindew committed Jul 9, 2022
1 parent 827cf08 commit fc98338
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 3 deletions.
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ For OpenAPI 3.1
- [ ] Callbacks can now reference a PathItem - previously required them
- [ ] Check out whether pathItem references match the rules for relative resolution
- [ ] Parameter object can have space delimited or pipeDelimited styles
- [ ] Discriminator object can be extended
- [x] Discriminator object can be extended
- [x] mutualTLS as a security scheme
- [ ] I think strictness of Security Requirement rules has changed

2 changes: 2 additions & 0 deletions lib/openapi3_parser/node_factory/discriminator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
module Openapi3Parser
module NodeFactory
class Discriminator < NodeFactory::Object
allow_extensions { |context| context.openapi_version >= "3.1" }

field "propertyName", input_type: String, required: true
field "mapping", input_type: Hash,
validate: :validate_mapping,
Expand Down
1 change: 1 addition & 0 deletions lib/openapi3_parser/node_factory/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Object
def_delegators "self.class",
:field_configs,
:extension_regex,
:allowed_extensions?,
:mutually_exclusive_fields,
:allowed_default?,
:validations
Expand Down
15 changes: 14 additions & 1 deletion lib/openapi3_parser/node_factory/object_factory/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,21 @@ def field_configs
@field_configs ||= {}
end

def allow_extensions(regex: EXTENSION_REGEX)
def allow_extensions(regex: EXTENSION_REGEX, &block)
@extension_regex = regex
@allowed_extensions = block || true
end

def allowed_extensions?(context)
@allowed_extensions ||= nil

allowed = if @allowed_extensions.respond_to?(:call)
@allowed_extensions.call(context)
else
@allowed_extensions
end

!!allowed
end

def extension_regex
Expand Down
4 changes: 3 additions & 1 deletion lib/openapi3_parser/node_factory/object_factory/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ def check_required_fields
end

def check_unexpected_fields
extension_regex = factory.extension_regex if factory.allowed_extensions?(validatable.context)

Validators::UnexpectedFields.call(
validatable,
extension_regex: factory.extension_regex,
extension_regex: extension_regex,
allowed_fields: factory.allowed_fields,
raise_on_invalid: raise_on_invalid
)
Expand Down
28 changes: 28 additions & 0 deletions spec/lib/openapi3_parser/node_factory/discriminator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,32 @@
}
end
end

describe "allow extensions" do
it "accepts extensions for OpenAPI 3.1" do
factory_context = create_node_factory_context(
{
"propertyName" => "test",
"x-extension" => "value"
},
document_input: { "openapi" => "3.1.0" }
)

instance = described_class.new(factory_context)
expect(instance).to be_valid
end

it "rejects extensions for OpenAPI < 3.1" do
factory_context = create_node_factory_context(
{
"propertyName" => "test",
"x-extension" => "value"
},
document_input: { "openapi" => "3.0.0" }
)

instance = described_class.new(factory_context)
expect(instance).not_to be_valid
end
end
end

0 comments on commit fc98338

Please sign in to comment.