pb33f / wiretap

The world's coolest API Validation and compliance tool. Validate APIs against OpenAPI specifications and much more
https://pb33f.io/wiretap/
Other
125 stars 18 forks source link

Wiretap fails to validate correct request #113

Closed mkatanski closed 7 months ago

mkatanski commented 7 months ago

While running mock server with command yarn wiretap -s ./swagger.yml -u http://localhost:3000 -x I have incosistent behaviour of path parameter validator.

I have this parameter defined in OpenApi yaml file:

PathTrackId:
      in: path
      name: trackId
      required: true
      schema:
        type: string
        pattern: ^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
        example: 123e4567-e89b-12d3-a456-426614174000
        format: uuid
        minLength: 32
        maxLength: 36

and it is used in a path like this:

/contents/tracks/{trackId}:
    get:
      tags:
        - Contents
      summary: Get tracks based on {trackId}, from contents
      operationId: contentsTracksTrackIdGet
      parameters:
        - $ref: '#/components/parameters/PathTrackId'

My frontend app sends request with some example ID:

GET http://localhost:4200/api/contents/tracks/123e4567-e89b-12d3-a456-426614174010

where http://localhost:4200/api/ is a proxy for default wiretap http://localhost:9000.

Issue

Wiretap returns

{
    "type": "https://pb33f.io/wiretap/error",
    "title": "unable to serve mocked response",
    "status": 500,
    "detail": "Error: Path parameter 'trackId' failed to validate, Reason: The path parameter 'trackId' is defined as an string, however it failed to pass a schema validation, Validation Errors: [Reason: 'tracks' is not valid 'uuid', Location: /format Reason: length must be \u003e= 32, but got 6, Location: /minLength Reason: does not match pattern '^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$', Location: /pattern], Line: 47, Column: 9"
}

when request is send for the first time but its ok if the same request is send once again.

First request - 500:

GET /api/contents/tracks/123e4567-e89b-12d3-a456-426614174010 HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
Authorization: test_token
Connection: keep-alive
DNT: 1
Host: localhost:4200
Referer: http://localhost:4200/app/game/track/123e4567-e89b-12d3-a456-426614174010
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
sec-ch-ua: "Not-A.Brand";v="99", "Chromium";v="124"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

Second request - OK:

GET /api/contents/tracks/123e4567-e89b-12d3-a456-426614174010 HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
Authorization: test_token
Connection: keep-alive
DNT: 1
Host: localhost:4200
Referer: http://localhost:4200/app/game/track/123e4567-e89b-12d3-a456-426614174010
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
sec-ch-ua: "Not-A.Brand";v="99", "Chromium";v="124"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
daveshanley commented 7 months ago

In v0.1.9 Using the following spec:

openapi: 3.0.1
paths:
  /contents/tracks/{trackId}:
    get:
      tags:
        - Contents
      summary: Get tracks based on {trackId}, from contents
      operationId: contentsTracksTrackIdGet
      parameters:
        - $ref: '#/components/parameters/PathTrackId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Track'
components:
  parameters:
    PathTrackId:
      in: path
      name: trackId
      required: true
      schema:
        type: string
        pattern: ^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$
        example: 123e4567-e89b-12d3-a456-426614174000
        format: uuid
        minLength: 32
        maxLength: 36
  schemas:
    Track:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        name:
          type: string
          example: 'Track Name'
        description:
          type: string
          example: 'Track Description'
        duration:
          type: integer
          example: 120
        createdAt:
          type: string
          format: date-time
          example: '2020-01-01T00:00:00Z'
        updatedAt:
          type: string
          format: date-time
          example: '2020-01-01T00:00:00Z'

and the following request:

http://localhost:9090/contents/tracks/123e4567-e89b-12d3-a456-42661417401

The following response is now returned, consistently.

{
    "type": "https://pb33f.io/wiretap/error",
    "title": "unable to serve mocked response",
    "status": 500,
    "detail": "Error: Path parameter 'trackId' failed to validate, Reason: The path parameter 'trackId' is defined as an string, however it failed to pass a schema validation, Validation Errors: [Reason: '123e4567-e89b-12d3-a456-42661417401' is not valid 'uuid', Location: /format Reason: does not match pattern '^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$', Location: /pattern], Line: 25, Column: 9"
}

When sending a valid UUID like so:

http://localhost:9090/contents/tracks/f3bea935-6aac-4a42-ae6b-15ad8be8e7c9

Wiretap mocks the response accordingly.

{
    "createdAt": "2020-01-01T00:00:00Z",
    "description": "Track Description",
    "duration": 120,
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "name": "Track Name",
    "updatedAt": "2020-01-01T00:00:00Z"
}