Skip to content
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

oas3-valid-oas-content-example fails to consider allOf when validating examples against endpoint request schema #1583

Closed
elsewhat opened this issue Apr 26, 2021 · 3 comments
Assignees
Labels
t/bug Something isn't working

Comments

@elsewhat
Copy link

Describe the bug
The error code oas3-valid-oas-content-example is reported in situations where the OpenAPI specification uses the allOf directive and is according with the standard.

Example of reported error (see test case below):
error oas3-valid-oas-content-example Property "planningPlantId" is not expected to be here components.examples.create-work-order-minimal.value

In this instance planningPlantId is present in the schema through an allOf directive.

To Reproduce

  1. OpenAPI test specification
openapi: 3.0.1
info:
  title: Example API
  version: "0.1.0"  
paths:   
  /work-order:               
    post:
      summary: Create Work order
      operationId: CreateWorkOrder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkOrderCreate'
            examples:
              create-work-order-minimal:
                $ref: '#/components/examples/create-work-order-minimal'
      responses:
        '204':
          description: Success - No content

components:
  schemas:
    WorkOrderCreateAbstract:
      type: object
      properties:
        planningPlantId:
          type: string
          example: '1100'
      additionalProperties: false          

    WorkOrderCreate:
      allOf:
        - $ref: '#/components/schemas/WorkOrderCreateAbstract'
      type: object
      properties:
        text:
          type: string
          example: '0010'
      additionalProperties: false            
      required: ["planningPlantId","text"]

  examples:
    create-work-order-minimal:
      summary: Create minimal
      value:
        text: 'Test text'
        planningPlantId: '1100'


  1. Run this CLI command 'spectral lint'
C:\temp>spectral lint spectral_issue_allof_example_api.yaml
OpenAPI 3.x detected

c:/temp/spectral_issue_allof_example_api.yaml
  1:1   warning  oas3-api-servers                OpenAPI `servers` must be present and non-empty array.
  1:1   warning  openapi-tags                    OpenAPI object should have non-empty `tags` array.
  2:6   warning  info-contact                    Info object should contain `contact` object.                             info
  2:6   warning  info-description                OpenAPI object info `description` must be present and non-empty string.  info
  7:10  warning  operation-description           Operation `description` must be present and non-empty string.            paths./work-order.post
  7:10  warning  operation-tags                  Operation should have non-empty `tags` array.                            paths./work-order.post
 47:13    error  oas3-valid-oas-content-example  Property `planningPlantId` is not expected to be here                    components.examples.create-work-order-minimal.value

✖ 7 problems (1 error, 6 warnings, 0 infos, 0 hints)
  1. See error oas3-valid-oas-content-example Property "planningPlantId" is not expected to be here components.examples.create-work-order-minimal.value which should not have occured

Expected behavior
No error message should be thrown for the validation of example 'create-work-order-minimal'

Environment (remove any that are not applicable):

  • Library version: 5.9.1
  • OS: Windows
@elsewhat elsewhat added the t/bug Something isn't working label Apr 26, 2021
@EvanCarroll
Copy link

I think this is the same problem in #1347

@P0lip P0lip self-assigned this May 4, 2021
@P0lip
Copy link
Contributor

P0lip commented May 5, 2021

Hey @elsewhat!
Thanks a lot for filing the ticket!

After the investigation I've made, I've come to a conclusion that what Spectral (and Ajv in this particular case) outputs here might be correct. Let me explain why.

This is (more or less) the schema Spectral passes to Ajv.

allOf:
  - type: object
    properties:
      planningPlantId:
        type: string
        example: '1100'
    additionalProperties: false
type: object
properties:
  text:
    type: string
    example: '0010'
additionalProperties: false
required:
  - planningPlantId
  - text

Now, if you take a look at the additionalProperties properties, you should be able to notice they somewhat clash with each other.
The first item (the subschema) in allOf specifies additionalProperties with the value of false, and the "top-level" definition is no different.
In this particular case, due to the presence of allOf, the first subschema is evaluated separately, therefore we validate the data against the allOf subschema initially (and we fail, because the object cannot have additional properties), and then when we validate an actual top-level definition (it also fails likewise).

I cannot think of any value that could meet the criteria imposed by such a schema.

If you still think this is an actual issue, let's chat - it could be I misunderstand how allOf validation is supposed to work in cases like this one, yet I tried a few other validators and they all produced the same result as Ajv does.

@elsewhat
Copy link
Author

elsewhat commented May 6, 2021

Hey @elsewhat!
Thanks a lot for filing the ticket!

After the investigation I've made, I've come to a conclusion that what Spectral (and Ajv in this particular case) outputs here might be correct. Let me explain why.

Thanks for the thorough investigation. I believe your conclusion is correct and that additionalProperties has a different semantics than what I had anticipated . https://stackoverflow.com/a/23001194/250787 is another source saying the same.

Our main goal with adding additionalProperties is to be able to verify (today in postman using tv4 and custom scripting) that no additional properties is being returned by the API response.
But realize now that before we run the custom script in postman, we first "normalize" away all the allOfs using https://github.com/davidkelley/json-dereference-cli . It's only therefore we're able to check it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants