-
Notifications
You must be signed in to change notification settings - Fork 23
Allow for passing in Definition when loading OpenAPI definitions #356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,24 @@ def initialize(contents, filepath = nil) | |
| # @return [Enumerable[Router::Route]] | ||
| def_delegators :@router, :routes | ||
|
|
||
| # Returns a unique identifier for this API definition | ||
| # @return [String] A unique key for this API definition | ||
| def key | ||
| return filepath if filepath | ||
|
|
||
| info = self['info'] || {} | ||
| title = info['title'] | ||
| version = info['version'] | ||
|
|
||
| if title.nil? || version.nil? | ||
| raise ArgumentError, | ||
| "Cannot generate key for the OpenAPI document because 'info.title' or 'info.version' is missing. " \ | ||
| 'Please add these fields to your OpenAPI document.' | ||
| end | ||
|
|
||
| "#{title} @ #{version}" | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thoughts? You mentioned using a hash of the definition. Would you prefer that over this?
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Until now openapi_first did not have an opinion about the contents of the OAD…, but I think its' fine the way you did it, because it will lead to a human readable key and the code is easy to follow. |
||
| end | ||
|
|
||
| # Validates the request against the API description. | ||
| # @param [Rack::Request] request The Rack request object. | ||
| # @param [Boolean] raise_error Whether to raise an error if validation fails. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ class Plan | |
| class UnknownRequestError < StandardError; end | ||
|
|
||
| def self.for(oad, skip_response: nil) | ||
| plan = new(filepath: oad.filepath) | ||
| plan = new(definition_key: oad.key, filepath: oad.filepath) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand why you changed this. This makes sense to me. |
||
| oad.routes.each do |route| | ||
| responses = skip_response ? route.responses.reject(&skip_response) : route.responses | ||
| plan.add_route request_method: route.request_method, | ||
|
|
@@ -24,13 +24,14 @@ def self.for(oad, skip_response: nil) | |
| plan | ||
| end | ||
|
|
||
| def initialize(filepath:) | ||
| def initialize(definition_key:, filepath: nil) | ||
| @routes = [] | ||
| @index = {} | ||
| @api_identifier = filepath || definition_key | ||
| @filepath = filepath | ||
| end | ||
|
|
||
| attr_reader :filepath, :routes | ||
| attr_reader :api_identifier, :filepath, :routes | ||
| private attr_reader :index | ||
|
|
||
| def track_request(validated_request) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,48 @@ | |
| expect(described_class[:mine].filepath).to eq('./examples/openapi.yaml') | ||
| end | ||
|
|
||
| it 'can register a Definition object' do | ||
| definition = OpenapiFirst.load('./examples/openapi.yaml') | ||
| described_class.register(definition, as: :from_definition) | ||
| expect(described_class[:from_definition]).to eq(definition) | ||
| end | ||
|
|
||
| it 'uses filepath as key for Definition objects with filepath' do | ||
| # Register a definition with filepath and start tracking | ||
| definition = OpenapiFirst.load('./spec/data/dice.yaml') | ||
| described_class.register(definition, as: :with_filepath) | ||
| OpenapiFirst::Test::Coverage.start | ||
|
|
||
| # Verify the plan was registered with the filepath key | ||
| filepath = './spec/data/dice.yaml' | ||
| plan = OpenapiFirst::Test::Coverage.current_run[filepath] | ||
|
|
||
| expect(plan).not_to be_nil | ||
| expect(plan.filepath).to eq(filepath) | ||
| expect(plan.api_identifier).to eq(filepath) | ||
| end | ||
|
|
||
| it 'uses the definition key for Definition objects without filepath' do | ||
| # Create a definition without filepath | ||
| dice_hash = YAML.load_file('./spec/data/dice.yaml') | ||
| dice_hash['info'] = { | ||
| 'title' => 'Dice API', | ||
| 'version' => '1.0.0' | ||
| } | ||
| definition = OpenapiFirst.parse(dice_hash) | ||
|
|
||
| # Register and start tracking | ||
| described_class.register(definition, as: :without_filepath) | ||
| OpenapiFirst::Test::Coverage.start | ||
|
|
||
| expected_key = definition.key | ||
| plan = OpenapiFirst::Test::Coverage.current_run[expected_key] | ||
|
|
||
| # Verify the plan was registered with the definition key | ||
| expect(plan).to be_a(OpenapiFirst::Test::Coverage::Plan) | ||
| expect(plan.api_identifier).to eq(expected_key) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've created a
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. |
||
| end | ||
|
|
||
| it 'raises an error if the same API description is registered twice' do | ||
| described_class.register('./examples/openapi.yaml') | ||
| expect do | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you want
.loadto be able to accept a Definition instance? In order to avoid something likeif path_or_definition.is_a?(Definition)in test.rb?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was treating
.loadas a single place to handle this. A definition or file path goes in at the edges and then you always get a definition. However, if you prefer to not do that, I'm happy to change it! I leave to you.