Another question: > Response body is incompati...
# pactflow
t
Another question:
Response body is incompatible with the response body schema in the spec file: should be object
I think there is something missing in the error message? What
should be object
?
Expected response:
Copy code
Status:200
Headers:
{
    "Content-Type": "application/json"
}

Body:
{"foo":true}
API:
Copy code
{
  "foo": true
}
pact
Copy code
{
  "consumer": {
    "name": "gem"
  },
  "provider": {
    "name": "service"
  },
  "interactions": [
    {
      "description": "A request to fetch the user's example",
      "providerState": "the required headers are passed to the request",
      "request": {
        "method": "get",
        "path": "/v1/user/925888/example.json",
        "headers": {
          "Accept": "application/json"
        }
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json"
        },
        "body": "{\"foo\":true}"
      }
    },
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}
t
How did you define this contract?
t
We are using
pact (1.63.0)
for ruby on the consumer side. The above pact is a bit simplified.
Is there a way to see detail validation logs on pact-flow?
Hello, something is wrong here and I don't know what. Here is a full example: OAS file:
Copy code
openapi: 3.0.0
x-stoplight:
  id: zri1hpqxajhkj
info:
  title: internal.v1
  version: '1.0'
  description: Simply dummy `application/json` API.
servers:
  - url: '<http://localhost:3000>'
paths:
  '/v1/users/{userId}':
    parameters:
      - schema:
          type: integer
        name: userId
        in: path
        required: true
        description: Id of an existing user.
    get:
      summary: Get User Info by User ID
      tags: []
      responses:
        '200':
          description: User Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
              examples:
                Example:
                  value:
                    id: 4711
                    first_name: Bob
                    email: <mailto:bob.doe@example.com|bob.doe@example.com>
                    email_verified: true
                    create_date: '2023-04-07'
      operationId: get-users-userId
      description: Retrieve the information of the user with the matching user ID.
      x-internal: true
components:
  schemas:
    User:
      title: User
      type: object
      x-examples:
        Example:
          id: 4711
          first_name: Bob
          email: <mailto:bob.doe@example.com|bob.doe@example.com>
          email_verified: true
          create_date: '2023-04-07'
      x-internal: true
      properties:
        id:
          type: integer
          description: Unique identifier for the given user.
          example: 4711
        first_name:
          type: string
          example: Bob
        email:
          type: string
          format: email
          example: <mailto:bob.doe@example.com|bob.doe@example.com>
        email_verified:
          type: boolean
          description: Set to true if the user's email has been verified.
          default: true
        create_date:
          type: string
          format: date
          description: The date that the user was created.
          example: '2023-04-07'
      required:
        - id
        - first_name
        - email
        - email_verified
x-internal: true
Pact:
Copy code
{
  "consumer": {
    "name": "sandbox-gem"
  },
  "provider": {
    "name": "sandbox-service"
  },
  "interactions": [
    {
      "description": "A request to fetch a dummy user",
      "providerState": "and the service returns successful response",
      "request": {
        "method": "get",
        "path": "/v1/users/925888",
        "headers": {
          "Accept": "application/json"
        }
      },
      "response": {
        "status": 200,
        "headers": {},
        "body": "{\"id\":4711,\"first_name\":\"Bob\",\"email\":\"<mailto:bob.doe@example.com|bob.doe@example.com>\",\"email_verified\":true,\"create_date\":\"2023-04-07\"}"
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}
Pactflow validation result
Copy code
response body is incompatible

Response body is incompatible with the response body schema in the spec file: should be object

Mismatched at:
[root].interactions[0].response.body
message has been deleted
Should I create an issue on github? @Matt (pactflow.io / pact-js / pact-go)
Using jsonapi (
application/vnd.api+json
) doesn't lead to the above error! OAS:
Copy code
openapi: 3.0.0
x-stoplight:
  id: zri1hpqxajhkj
info:
  title: internal.v1
  version: '1.0'
  description: 'Simply dummy `application/vnd.api+json` API. <https://jsonapi.org/>'
servers:
  - url: '<http://localhost:3000>'
paths:
  '/v1/users/{userId}':
    parameters:
      - schema:
          type: integer
        name: userId
        in: path
        required: true
        description: Id of an existing user.
    get:
      summary: Get User Info by User ID
      tags: []
      responses:
        '200':
          description: User Found
          content:
            application/vnd.api+json:
              schema:
                $ref: '#/components/schemas/User'
              examples:
                Example:
                  value:
                    data:
                      id: 4711
                      type: user
                      attributes:
                        email: <mailto:bob.doe@example.com|bob.doe@example.com>
                        email_verified: true
                        create_date: '2023-04-07'
      operationId: get-users-userId
      description: Retrieve the information of the user with the matching user ID.
      x-internal: true
components:
  schemas:
    User:
      title: User
      type: object
      x-examples:
        Example:
          data:
            id: 4711
            type: user
            attributes:
              email: <mailto:bob.doe@example.com|bob.doe@example.com>
              email_verified: true
              create_date: '2023-04-07'
      x-internal: true
      properties:
        data:
          type: object
          required:
            - id
            - type
            - attributes
          properties:
            id:
              type: integer
              example: 4711
            type:
              type: string
              enum:
                - user
              example: user
            attributes:
              type: object
              required:
                - email
                - email_verified
              properties:
                email:
                  type: string
                  format: email
                  example: <mailto:bob.doe@example.com|bob.doe@example.com>
                email_verified:
                  type: boolean
                  default: true
                create_date:
                  type: string
                  format: date
                  example: '2023-04-07'
      required:
        - data
x-internal: true
Pact:
Copy code
{
  "consumer": {
    "name": "sandbox-gem"
  },
  "provider": {
    "name": "sandbox-service"
  },
  "interactions": [
    {
      "description": "A request to fetch a dummy user",
      "providerState": "and the service returns successful response",
      "request": {
        "method": "get",
        "path": "/v1/users/925888",
        "headers": {
          "Accept": "application/vnd.api+json"
        }
      },
      "response": {
        "status": 200,
        "headers": {},
        "body": "{\"data\":{\"id\":4711,\"type\":\"user\",\"attributes\":{\"email\":\"<mailto:bob.doe@example.com|bob.doe@example.com>\",\"email_verified\":true,\"create_date\":\"2023-04-07\"}}}"
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}
For me it looks like, that
application/hal+json
also works, but I haven't investigated that in depth.
m
Hi Thomas. Something doesn’t look right to me though. The
response.body
property is escaped JSON, but it shouldn’t be if it is supposed to be a type of JSON
How are you generated that?
t
The
response.body
property is escaped JSON, but it shouldn’t be if it is supposed to be a type of JSON
Thank you for the hint. It wasn't clear for me, that this could be the issue. I'll try to generate a non-escaped version.
👍 1
m
Yeah, that’s a tricky one. It’s a legit possibility to have escaped JSON, and because it’s a string, it’s also valid JSON
t
The non-escaped version of the JSON response body works.
👍 1
How are you generated that?
We use pact-ruby for testing the consumer contract. There I used a ruby hash for the response body and called
.json
on it. This resulted in the escaped JSON string in the pact. I would expect a warning from
pact-ruby
in this case.
m
Thanks. Perhaps it’s worth raising an issue for it? (or a PR if you have a good suggestion)
t
I'll think about it.
👍 1
Now I understand the original error message:
Response body is incompatible with the response body schema in the spec file: should be object
For me "Response body is incompatible with the response body schema in the spec file: The response body should be a JSON object, but is as (JSON) string" would be more clear and helpful.
👍 1
t
I agree
m
thanks, we’ll add this feedback