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

Headers matching fails due to splitting multi-value values #1398

Closed artemptushkin closed 2 years ago

artemptushkin commented 3 years ago

I migrate from au.com.dius.pact.provider:junit:4.1.11 to 4.2.7, same issue with 4.1.23

Some tests started failing on:

1) Get current account billing information status value includes headers "access-control-allow-headers" with value "[Content-Type, Authorization]"

    1.1) header: Expected header 'access-control-allow-headers' to have value 'Content-Type, Authorization' but was 'Content-Type'

    1.2) header: Expected header 'access-control-allow-methods' to have value 'POST, GET, PUT, HEAD, DELETE, OPTIONS, PATCH' but was 'POST'

    1.3) header: Expected header content-type to have value 'application/json, charset=utf-8' but was 'application/json;charset=utf-8'

Pact looks like this:

"response": {
                "status": 200,
                "headers": {
                    "access-control-allow-credentials": "true",
                    "access-control-allow-headers": "Content-Type, Authorization",
                    "access-control-allow-methods": "POST, GET, PUT, HEAD, DELETE, OPTIONS, PATCH",
                    "content-type": "application/json, charset=utf-8"
                }
            }

The provider response headers looks like this:

'Access-Control-Allow-Headers': 'Content-Type, Authorization'
'Access-Control-Allow-Methods': 'POST, GET, PUT, HEAD, DELETE, OPTIONS, PATCH'

Obviously, headers are identical, should match. Case sensitive difference it has only, but it isn't the problem as I see in debug: it reaches this line

Looks like it splits the actual response headers and then fails to match. Is this something expected?

uglyog commented 3 years ago

What has generated your Pact file? Are you able to provide the complete file?

artemptushkin commented 3 years ago

@uglyog like this:

"response": {
                "status": 200,
                "headers": {
                    "access-control-allow-credentials": "true",
                    "access-control-allow-headers": "Content-Type, Authorization",
                    "access-control-allow-methods": "POST, GET, PUT, HEAD, DELETE, OPTIONS, PATCH",
                    "content-type": "application/json, charset=utf-8"
                }
            }
uglyog commented 3 years ago

Released 4.1.24 and 4.2.9

artemptushkin commented 2 years ago

@uglyog this is still broken 4.2.14

Pact content:

"headers": {
                    "access-control-allow-credentials": "true",
                    "access-control-allow-headers": "Content-Type, Authorization",
                    "access-control-allow-methods": "POST, GET, PUT, HEAD, DELETE, OPTIONS, PATCH",
                    "content-type": "application/json, charset=utf-8"
                }

tests output:

returns a response which
          has status code 201 (OK)
          includes headers
            "access-control-allow-credentials" with value "true" (OK)
            "access-control-allow-headers" with value "Content-Type, Authorization" (FAILED)
            "access-control-allow-methods" with value "POST, GET, PUT, HEAD, DELETE, OPTIONS, PATCH" (FAILED)
            "content-type" with value "application/json, charset=utf-8" (FAILED)
          has a matching body (OK)

    Failures:

    1) Verifying a pact between tenant-portal and users - Invites an end user includes headers "access-control-allow-headers" with value "[Content-Type, Authorization]"

        1.1) header: Expected header 'access-control-allow-headers' to have value 'Content-Type' but was 'Origin'

        1.2) header: Expected header 'access-control-allow-headers' to have value 'Authorization' but was 'X-Requested-With'

        1.5) header: Expected header 'access-control-allow-methods' to have value 'POST' but was 'GET'

        1.6) header: Expected header 'access-control-allow-methods' to have value 'GET' but was 'POST'

        1.7) header: Expected header 'access-control-allow-methods' to have value 'HEAD' but was 'DELETE'

        1.8) header: Expected header 'access-control-allow-methods' to have value 'DELETE' but was 'OPTIONS'

        1.9) header: Expected header 'access-control-allow-methods' to have value 'OPTIONS' but was 'PATCH'

        1.10) header: Expected header 'access-control-allow-methods' to have value 'PATCH' but was ''

        1.11) header: Expected a header 'content-type' but was missing
artemptushkin commented 2 years ago

I just realized that this is a matter of order now... It works like equals if there are no matchers.

I just changed the order of headers and this is ok, seems like no issue, thanks.

So, the best way to do it in contains way is to write a custom matcher on the consumer side.