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

False positive validation using .spectral ruleset #595

Open
tina-junold opened this issue Dec 16, 2024 · 1 comment
Open

False positive validation using .spectral ruleset #595

tina-junold opened this issue Dec 16, 2024 · 1 comment

Comments

@tina-junold
Copy link

Given is the following openapi.yml

openapi: 3.0.3
info:
  title: Chat Gateway
  description: A HTTP Gateway to the grpc chat service.
  version: draft
  license:
    name: UNLICENSED
    url: https://www.company.com
  contact:
    name: Company Inc.
    email: [email protected]
    url: https://www.company.com

servers:
  - url: https://localhost:5000
    description: Local Development Server

tags:
  - name: authenticate
    description: Authentication request
  - name: chat
    description: Chat service related requests

paths:
  /login:
    post:
      operationId: login
      description: Login to the chat server
      summary: To use the chat server, you have to login.
      security: []
      tags:
        - authenticate
      requestBody:
        description: The login request body.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
            example:
              name: client.1
      responses:
        '200':
          description: Successful login
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginResponse'
              example:
                clientID: 4b84bbfc-e6ee-4e8b-a391-695b07b18416
                token: 20ca572a-6797-4c9e-b119-680d780f6738
        '400':
          $ref: '#/components/responses/400'
        '500':
          $ref: '#/components/responses/500'
  /clients:
    get:
      operationId: clients
      description: Get a list of current clients
      summary: This returns a list of current connected clients.
      security:
        - bearerAuth: []
      tags:
        - chat
      responses:
        '200':
          description: Successful client list request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientsResponse'
              example:
                clients:
                  - name: client.1
                    clientID: 4b84bbfc-e6ee-4e8b-a391-695b07b18416
        '400':
          $ref: '#/components/responses/400'
        '500':
          $ref: '#/components/responses/500'
  /messages:
    get:
      operationId: messages
      description: Get a list of received messages
      summary: This returns all received but not read messages.
      security:
        - bearerAuth: [ ]
      tags:
        - chat
      responses:
        '200':
          description: Successful message list request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessagesResponse'
              example:
                messages:
                  - message: "Hello from client.1"
                    clientID: 4b84bbfc-e6ee-4e8b-a391-695b07b18416
        '400':
          $ref: '#/components/responses/400'
        '500':
          $ref: '#/components/responses/500'
  /send:
    post:
      operationId: send
      description: Send a message
      summary: This allows to send a message through the chat server to all connected clients.
      security:
        - bearerAuth: []
      tags:
        - chat
      requestBody:
        description: The message request body.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendRequest'
            example:
              message: "Hello @chat"
      responses:
        '204':
          description: Successful send message
        '400':
          $ref: '#/components/responses/400'
        '500':
          $ref: '#/components/responses/500'
components:
  securitySchemes:
    bearerAuth:
      description: Authentication via token. Use the /login request to obtain the token.
      type: http
      scheme: bearer

  schemas:
    ErrorCode:
      description: The error code.
      type: integer
      example: 123
    ErrorMessage:
      description: The error message. Use only for internal evaluation.
      type: string
      example: validation error
    ErrorRelate:
      description: Describes a field or parameter this error belongs to. Can be null.
      type: string
      nullable: true
      example: custom.field
    ErrorDetail:
      type: object
      description: contains some detailed error information.
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          $ref: '#/components/schemas/ErrorMessage'
        relate:
          $ref: '#/components/schemas/ErrorRelate'
      required:
        - code
        - message
        - relate
      example:
        code: 123
        message: validation error
        relate: custom.field
    ErrorDetails:
      description: A list with error details.
      type: array
      items:
        $ref: '#/components/schemas/ErrorDetail'
      example:
        - code: 123
          message: validation error
          relate: custom.field
    ErrorResponseDetails:
      type: object
      description: A detailed error response.
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          $ref: '#/components/schemas/ErrorMessage'
        error-details:
          $ref: '#/components/schemas/ErrorDetails'
      required:
        - code
        - message
        - error-details
      example:
        code: 123
        message: validation error
        error-details:
          - code: 456
            message: specific validation error
            relate: custom.field
    ErrorResponseMinimal:
      description: A minimal error response.
      type: object
      properties:
        message:
          $ref: '#/components/schemas/ErrorMessage'
      required:
        - message
      example:
        message: an error occurred

    Token:
      description: An auth token
      type: string
      format: uuid
      example: 20ca572a-6797-4c9e-b119-680d780f6738
      x-oapi-codegen-extra-tags:
        validate: required

    ClientName:
      description: A client name
      type: string
      example: client.1
      x-oapi-codegen-extra-tags:
        validate: required

    ClientID:
      description: A client id
      type: string
      format: uuid
      example: 4b84bbfc-e6ee-4e8b-a391-695b07b18416
      x-oapi-codegen-extra-tags:
        validate: required

    Client:
      description: A client
      properties:
        name:
          $ref: '#/components/schemas/ClientName'
        clientID:
          $ref: '#/components/schemas/ClientID'
      required:
        - name
        - clientID

    Message:
      description: A message
      properties:
        message:
          description: The message
          type: string
          example: "Hello World"
          x-oapi-codegen-extra-tags:
            validate: required
        clientID:
          $ref: '#/components/schemas/ClientID'
      required:
        - message
        - clientID

    LoginRequest:
      description: The login request
      properties:
        name:
          $ref: '#/components/schemas/ClientName'
      required:
        - name

    LoginResponse:
      description: The login response
      properties:
        clientID:
          $ref: "#/components/schemas/ClientID"
        token:
          $ref: "#/components/schemas/Token"
      required:
        - clientID
        - token

    ClientsResponse:
      description: The clients response
      properties:
        clients:
          description: The clients
          type: array
          items:
            $ref: '#/components/schemas/Client'
          example:
            - name: client.1
              clientID: 4b84bbfc-e6ee-4e8b-a391-695b07b18416
            - name: client.2
              clientID: 2fb0def5-1c64-42a2-9c98-58c0fa6a3313
          x-oapi-codegen-extra-tags:
            validate: required
      required:
        - clients

    MessagesResponse:
      description: The messages response
      properties:
        messages:
          description: The messages
          type: array
          items:
            $ref: '#/components/schemas/Message'
          example:
            - message:  "Hello from client.1"
              clientID: 4b84bbfc-e6ee-4e8b-a391-695b07b18416
            - message: "Hello back from client.2"
              clientID: 2fb0def5-1c64-42a2-9c98-58c0fa6a3313
          x-oapi-codegen-extra-tags:
            validate: required
      required:
        - messages

    SendRequest:
      description: The send request
      properties:
        message:
          type: string
          example: "Hello @chat"
          x-oapi-codegen-extra-tags:
            validate: required
      required:
        - message

  responses:
    '400':
      description: An error response.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseDetails'
          examples:
            errorResponse:
              $ref: '#/components/examples/ErrorResponse'
    '500':
      description: A bad request response.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseMinimal'
          examples:
            basicErrorResponse:
              $ref: '#/components/examples/BasicErrorResponse'

  examples:
    ErrorResponse:
      description: An error response example.
      value:
        code: 123
        message: validation error
        error-details:
          - code: 456
            message: specific validation error
            relate: custom.field
    BasicErrorResponse:
      description: A basic error response example.
      value:
        message: an error occurred

and the .spectral.yml ruleset:

---
extends:
  - [spectral:oas, all]

If i lint this, i got the message:

------------------------------------------------
Location        | Severity | Message                                                                             | Rule                  | Category   | Path
openapi.yml:0:0 | warning  | 'postResponseSuccess' function has invalid options supplied. Example valid optio... | post-response-success | Operations | $.paths.*.post.responses

This is imho a bug since POST /send contains a valid 204 response.

@LasneF
Copy link

LasneF commented Dec 16, 2024

i tried to reproduce your issue and found that

  • if you are leveraging the Doctor online the issue does not appear you have 100% score 🎉
  • if you use the command line vacuum generate-ruleset all my-ruleset and then use it , it is also not triggering the issue

the issue is triggerd only when you use the ruleset you mentionned
extends: [[spectral:oas, all]]

so there is kind of special case when using this model vs the others even if the rules is 100% the same

notice that the Location 0:0 is suspicious as usually vacuum maintains a precise location for such error, a deep dive is required🐟

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants