pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 479 forks source link

Problem with JSON response body containing a string as root value #1658

Open thibaut-bodart opened 1 year ago

thibaut-bodart commented 1 year ago

I am migrating from 4.3.17 to 4.4.4 and upgrading my contracts to use the V4 Pact specifications (from V3).

My response is in JSON format and only contains a UUID. See below a valid JSON response.

"08f7a210-95db-4827-bcc8-d2025ba506cf"

I am using the following code to define the interaction:

.willRespondWith()
.status(201)
.headers(headers())
.body(PactDslJsonRootValue.uuid(JOB_ID)));

With 4.3.17, using a Pact v3 contract, the generated contract looks like:

"response": {
        "body": "\"08f7a210-95db-4827-bcc8-d2025ba506cf\"",
}

With 4.4.4, using a Pact v4 contract, it looks like:

"response": {
        "body": {
          "content": "08f7a210-95db-4827-bcc8-d2025ba506cf",
          "contentType": "application/json",
          "encoded": false
        }
}

The value of the content property is not a valid JSON value in the case of 4.4.4 and the V4 spec.
For this reason, the contract cannot be verified by the provider (also using pact-jvm 4.4.4). See the exception below. This is expected since 08f7a210-95db-4827-bcc8-d2025ba506cf is not a valid JSON document (double quotes are required since this is a string and not a numerical value).

    1.1) Invalid JSON (1:5), found unexpected character '7'

Am I doing something wrong or is that a bug? If I modify the contract manually as illustrated below, the provider can successfully verify it. Is there a way to generate the response below using the Pact DSL?

"response": {
  "body": {
    "content": "\"08f7a210-95db-4827-bcc8-d2025ba506cf\"",
    "contentType": "application/json",
    "encoded": false
  },

Thanks in advance!

rholshausen commented 1 year ago

/jira ticket

github-actions[bot] commented 1 year ago

👋 Thanks, Jira [PACT-688] ticket created.

rholshausen commented 1 year ago

The content is correctly formed, as the Pact file is JSON and the contents is JSON, so the body contents is written directly as is. It must be an error with the provider verification. Are able to provide the debug logs from the provider verification?

I am going to update it to write the Pact file as

"response": {
  "body": {
    "content": "08f7a210-95db-4827-bcc8-d2025ba506cf",
    "contentType": "application/json",
    "encoded": "json" //<---
  },

to make it explicit that it has been encoded in JSON form.

rholshausen commented 1 year ago

Actually, I think I have replicated the issue. It is when the Pact file is loaded.

rholshausen commented 1 year ago

Just a note, after reviewing the V4 spec, the correct forms are:

"response": {
  "body": {
    "content": "08f7a210-95db-4827-bcc8-d2025ba506cf",
    "contentType": "application/json",
    "encoded": false
  },

or

"response": {
  "body": {
    "content": "\"08f7a210-95db-4827-bcc8-d2025ba506cf\"",
    "contentType": "application/json",
    "encoded": "JSON"
  },

Currently, there is no way with the DSL to get it to write the latter form.

thibaut-bodart commented 1 year ago

Thanks a lot for the quick feedback and action!