stoplightio / spectral

A flexible JSON/YAML linter for creating automated style guides, with baked in support for OpenAPI v3.1, v3.0, and v2.0 as well as AsyncAPI v2.x.
https://stoplight.io/spectral
Apache License 2.0
2.43k stars 235 forks source link

oas3-valid-media-example rule cannot handle schemas with discriminator #2509

Open TiMESPLiNTER opened 1 year ago

TiMESPLiNTER commented 1 year ago

Describe the bug The oas3-valid-media-example rule cannot handle schemas with discriminator and reports various validation errors.

In this case it reports 2 errors with the below spec:

To Reproduce

Use this OpenAPI spec to reproduce:

openapi: 3.1.0

info:
  title: Example
  description: Test
  version: 0.1.0
  contact:
    name: Pascal
    url: www.timesplinter.ch
    email: dev@timesplinter.ch

tags:
  - name: Car

servers:
  - url: https://development.cars.com

paths:
  /v1/cars:
    post:
      operationId: createCar
      description: Create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CarCreateRequest'
            examples:
              full-request:
                $ref: '#/components/examples/car-create-request'
      responses:
        '202':
          description: Reference to the intent created based on the request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Intent'
              examples:
                full-response:
                  $ref: '#/components/examples/car-create-response'
      tags:
        - Car

  /v1/cars/{carId}:
    patch:
      operationId: updateCar
      description: Update
      parameters:
        - $ref: '#/components/parameters/carId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CarUpdateRequest'
            examples:
              full-request:
                $ref: '#/components/examples/car-update-request'
      responses:
        '202':
          description: Reference to the intent created based on the request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Intent'
              examples:
                full-response:
                  $ref: '#/components/examples/car-update-response'
      tags:
        - Car

components:
  parameters:
    carId:
      name: carId
      required: true
      in: path
      schema:
        type: string
        format: uuid

  examples:
    car-create-request:
      value:
        brand: "Aston Martin"
        color: "red"
        type: "CarCreateRequest"

    car-update-request:
      value:
        color: "blue"
        type: "CarUpdateRequest"

    car-create-response:
      value:
        id: "3fa85f64-5717-4562-b3fc-2c963f66afa6"
        payload: 
          brand: "Aston Martin"
          color: "red"
          type: "CarCreateRequest"

    car-update-response:
      value:
        id: "3fa85f64-5717-4562-b3fc-2c963f66afa6"
        payload:
          color: "blue"
          type: "CarUpdateRequest"

  schemas:
    CarCreateRequest:
      type: object
      properties:
        brand:
          type: string
          example: Audi
        color:
          type: string
          example: red
        type:
          type: string
      required:
        - brand
        - color
        - type

    CarUpdateRequest:
      type: object
      properties:
        color:
          type: string
          example: blue
        type:
          type: string
      required:
        - type

    IntentPayload:
      additionalProperties: false
      discriminator:
        propertyName: type
        mapping:
          CarCreateRequest: '#/components/schemas/CarCreateRequest'
          CarUpdateRequest: '#/components/schemas/CarUpdateRequest'
      oneOf:
        - $ref: '#/components/schemas/CarCreateRequest'
        - $ref: '#/components/schemas/CarUpdateRequest'

    Intent:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
          example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
        payload:
          $ref: '#/components/schemas/IntentPayload'
      required:
        - id
        - payload

Expected behavior The above API spec should be valid.

Screenshots image

Environment (remove any that are not applicable):

Additional context None.

philsturgeon commented 2 months ago

Discriminator does not affect the validity of your JSON Schema. It is almost certainly being ignored entirely.

The oneOf and sub schemas should be completely valid in their own right, and the discriniator can even be deleted because they serve pretty much zero purpose once you've got a oneOf on there.

Either way, make your oneOf valid, ignore the disciminator, maybe delete it or comment it out to confirm, and the error will go away.