-
Notifications
You must be signed in to change notification settings - Fork 3
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
TypeError when parsing OAS with parameters
shared between methods in path
#48
Comments
Hey @klausmeyer, how are you doing? Thanks for discovering this bug, I forgot that there is path-wide parameter definitions so not everything is a http method. Please feel free to submit a PR, ideally with a example schema that is breaking. I will merge & push out a new version ASAP. |
Hi Konstantin, thanks for the fast reply. I'm doing good so far and you? I'll try to find some time next week to work on it. When playing around with the code yesterday I also found another possible problem but there I'm not sure yet if it was not introduced by my tinkering. Perhaps we can then also check quickly before shipping a new version just for the one problem. |
I've now created a PR with a potential fix. When trying it inside one of my affected applications I run into another error but I assume it might be separate one:
Note that we're using that feature of having different name for the OAS file: def oas
@oas ||= OpenapiContracts::Doc.parse(Rails.root.join('spec/fixtures/oas'), 'configuration-v1.openapi.yaml')
end |
Hi @klausmeyer, yes, I believe as well it is the separate one and I may have found a cause. In this line https://github.com/mkon/openapi_contracts/blob/main/lib/openapi_contracts/doc/file_parser.rb#L60 file name is added here I have attempted a simple fix by modifying the code to |
Hey, thanks for reporting this. Would it be possible for you to submit a demo file that causes the issue? It seems to be a bug in how this generates the compound document before passing it to json_schemer. I recently changed something there that allows pointing into other yaml files with a combination of relative file path and json pointer. |
Sure thing. The OAS file below contains all existing endpoints compounded into one file (including the ones Klaus added, but they are commented out because they cause already described error). Now, this small test already detects the problem: #/spec/openapi_contracts/match_spec.rb
context 'when schema pointers are within file' do
let(:doc) { OpenapiContracts::Doc.parse(FIXTURES_PATH.join('openapi'), 'example.openapi.yaml') }
it { is_expected.to be_valid }
end #/spec/fixtures/openapi/example.openapi.yaml
openapi: 3.0.0
info:
version: 1.0.0
title: Example.com
termsOfService: 'https://example.com/terms/'
contact:
email: contact@example.com
url: 'http://example.com/contact'
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
x-logo:
url: 'https://redocly.github.io/openapi-template/logo.png'
description: >
This is an **example** API to demonstrate features of OpenAPI specification
tags:
- name: Auth
description: Authentication
- name: Comments
description: Comments
- name: Messages
description: Messages
- name: User
description: Operations about user
servers:
- url: '//api.host.example'
paths:
# /comments/{id}:
# parameters:
# - name: id
# in: path
# description: ID of the comment.
# required: true
# schema:
# type: string
# example: '112547'
# get:
# tags:
# - Comments
# summary: Get Comment
# description: Get comment details.
# operationId: getComment
# responses:
# '200':
# description: OK
# patch:
# tags:
# - Comments
# summary: Update Comment
# description: Patch Comment
# operationId: patchComment
# responses:
# '204':
# description: OK
/health:
get:
operationId: healthCheck
summary: Health Check
responses:
'200':
description: OK
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequest'
'500':
description: Server Error
/messages/{id}:
get:
tags:
- Messages
summary: Get Message
description: Get message details
operationId: getMessage
parameters:
- name: id
in: path
description: ID of the message.
required: true
schema:
type: string
example: '193628'
responses:
'200':
description: OK
headers:
x-request-id:
schema:
type: string
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequest'
/user:
get:
tags:
- User
summary: Get all Users
description: This endpoint returns all users.
operationId: getUser
responses:
'200':
description: OK
headers:
x-request-id:
schema:
type: string
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequest'
post:
tags:
- User
summary: Create User
description: This endpoint creates a new user.
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
type:
type: string
attributes:
type: object
properties:
name:
type: string
nullable: true
email:
type: string
example: someone@host.example
additionalProperties: false
required:
- name
- email
additionalProperties: false
required:
- type
- attributes
responses:
'201':
description: Created
headers:
x-request-id:
schema:
type: string
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequest'
components:
schemas:
BadRequest:
type: object
properties:
errors:
type: array
items:
type: object
Message:
type: object
properties:
data:
type: object
properties:
id:
type: string
example: acd3751
type:
type: string
attributes:
type: object
properties:
body:
type: string
additionalProperties: false
required:
- body
additionalProperties: false
required:
- id
- type
- attributes
required:
- data
additionalProperties: false
User:
type: object
properties:
data:
type: object
properties:
id:
type: string
example: acd3751
readOnly: true
type:
type: string
attributes:
type: object
properties:
name:
type: string
nullable: true
addresses:
type: array
items:
oneOf:
- type: object
properties:
street:
type: string
city:
type: string
email:
type: string
example: someone@host.example
additionalProperties: false
required:
- name
- email
additionalProperties: false
required:
- id
- type
- attributes
required:
- data
additionalProperties: false P.S. I believe it makes sense to have one kind of file like this with multiple different endpoints and acceptable differences so tests can recognize problems in the future and make the gem more robust to different valid OAS files. Maybe the existing |
Ok I see now, thanks @dveljacic. I think I know the bug, it is not related to custom root file but I am not handling correctly JSON pointers in the root file. I always handle it like it is a extending file where the file name has to become part of the pointer. Eg if the root file is named You can see the compound file by adding a debugger in the end of the |
I will try to fix it asap. |
@klausmeyer can you try the branch |
Of course. Here the results:
|
Version 0.7.1 contains the fix. |
Hi @mkon,
we're getting the following error after updating to 0.7.0:
I did a bit of debugging and figured out being related to the case when having a
parameters:
block shared between the defined methods of a certain path.Here a way to reproduce it via change in the fixtures:
The issue seems to be mainly the
parameters
key not being filtered out here (or in the logic before):openapi_contracts/lib/openapi_contracts/doc/path.rb
Line 5 in f0ac4d0
Let me know if I should try to provide a fix or if you want to do it on your own.
Thanks, Klaus
The text was updated successfully, but these errors were encountered: