pact-foundation / pact-specification

Describes the pact format and verification specifications
MIT License
295 stars 28 forks source link

How to match a non-json format respond body? #81

Open YingzheHeBetty opened 3 years ago

YingzheHeBetty commented 3 years ago

Hi, I have a pact file like this:

{
  "consumer": {
    "name": "CMM"
  },
  "provider": {
    "name": "Analytics Service"
  },
  "interactions": [
    {
      "description": "a get request for Creatives Metadata Report",
      "providerState": "agency id 25342d03-d07f-4047-8887-5f671f3082d6 exist",
      "request": {
        "method": "get",
        "path": "/v1/cloud_ingestion/agencies/25342d03-d07f-4047-8887-5f671f3082d6/reports/metadata/creatives",
        "query": ""
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "text/csv"
        },
        "body": "id,external_ref,external_source,name,media_type,pixel_size",
        "matchingRules": {
          "$.body": {
            "match": "type"
          }
        }
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}

When I verified it on the provider side, the test failed:

`1) a get request for Creatives Metadata Report

    1.1) body: / Actual body 'id,external_ref,external_source,name,media_type,pixel_size
' is not equal to the expected body 'id,external_ref,external_source,name,media_type,pixel_size'

java.lang.AssertionError: 
Failures:

1) a get request for Creatives Metadata Report

    1.1) body: / Actual body 'id,external_ref,external_source,name,media_type,pixel_size
' is not equal to the expected body 'id,external_ref,external_source,name,media_type,pixel_size'

`

Any solutions? Thank you!

bethesque commented 3 years ago

CSV matching is not supported (except in Pact Ruby). You can only do exact string matching unfortunately.

uglyog commented 3 years ago

I think this is a valid concern, so re-opening

uglyog commented 3 years ago

This highlights a deeper issue, how can we provide an extension mechanism for formats that don't have a default implementation. Maybe shared libraries, or possibly an embedded scripting language so that support for other formats can be easily added.

bethesque commented 3 years ago

The ruby one allows you to configure a differ based on the content type, so you can write your own. That's why it has the CSV support.

uglyog commented 3 years ago

I assume that needs to be written in Ruby and made available to the underlying Ruby engine. That you can't write it in the language being used? I was thinking of something like an API that allows extensions to be added in a generic way.

mefellows commented 3 years ago

I looked into this when spiking protobufs. Golang has very good support for cross platform plugins, and I showed that I could integrate that into rust as a lib. But then I just thought about the complexitybthay might result it.

A possibly better alternative is to have the plugin expose an well defined API interface and register with the system. This would have the upside of allowing anyone to write a plugin in any language and would require them contributing it back (the downside is they will be written in many languages 😂)

YingzheHeBetty commented 3 years ago

The ruby one allows you to configure a differ based on the content type, so you can write your own. That's why it has the CSV support.

Could you provide more details/examples on CSV support? In my case, my consumer is written in ruby and my provider is written in JVM. Is there any way that I could verify CSV format response body?

bethesque commented 3 years ago

I haven't touched it for years, but here are the docs https://www.rubydoc.info/gems/pact-csv/0.0.1

YingzheHeBetty commented 3 years ago

I haven't touched it for years, but here are the docs https://www.rubydoc.info/gems/pact-csv/0.0.1

YingzheHeBetty commented 3 years ago

Is it possible to verify non-json format response body? If my provider is written in Java?

This highlights a deeper issue, how can we provide an extension mechanism for formats that don't have a default implementation. Maybe shared libraries, or possibly an embedded scripting language so that support for other formats can be easily added.

It would be very useful to have it added into pact testing!

uglyog commented 2 years ago

A prototype CSV plugin has been written. See https://github.com/pact-foundation/pact-plugins/tree/main/plugins/csv