pact-foundation / pact-support

Shared code for Pact gems
MIT License
7 stars 46 forks source link

Matching rules input / output mismatch #65

Closed tall-dan closed 3 months ago

tall-dan commented 5 years ago

I am using pact specification version 3, and using multiple files to declare my interactions, as described here.

I've noticed that the matching rules are being lost for all interactions besides the last one to execute during my test suite. I've dug through the source code and the pact specification, and I think I found a discrepancy.

Pact Specification The Jsonpath section of the specification seems to declare that matchingRules be a top level key for request and response, and that matchingRules should then have keys that dictate what section of the request / response are being matched. It looks like Jsonpath takes over from there.

Code Pact::InteractionV3Parser.parse_request_with_non_string_body takes care of nested matching rules, and line 45 indexes into request_matching_rules with a key, e.g. body. This is consistent with what the specification describes.

The pact file I'm getting Looks something like this:

{
  "consumer": {
    "name": "My Consumer"
  },
  "provider": {
    "name": "My Provider"
  },
  "interactions": [
    {
      "description": "An events request",
      "providerState": "an event board exists",
      "request": {
        "method": "POST",
        "path": "/graphql",
        "body": {
          "operationName": null,
          "query": "{\n  eventBoard {\n    title\n     __typename\n  }\n}\n",
          "variables": { }
        }
      },
      "response": {
        "status": 200,
        "body": {
          "data": {
            "eventBoard": {
              "title": {
                "__typename": "TranslatableField",
                "en": "Example Event Board Title"
              },
              "__typename": "EventBoard"
            }
          }
        },
        "matchingRules": {
          "$.body.data.eventBoard.title": {
            "match": "type"
          }
        }
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "3.0.0"
    }
  }
}

Note that the matchingRules that are written here do not conform with the spec. I'm still reading through the code to find out where the contract gets written to the filesystem, but this seems to be the source of my problem. Can anyone confirm that this is a bug, or am I missing something?

Local setup npm packages:

gems (which come from pact-node)

tall-dan commented 5 years ago

Update: I just found Pact::MatchingRules::V3::Extract and the corresponding spec

The spec makes it seem intentional that that there is no secondary key underneath matchingRules. Based on the pact specification I referenced above, I would've expected the following

{                                                                       
  body: Pact::SomethingLike.new(foo: 'bar', alligator: { name: 'Mary' })
}                                                                      

translating to something like

{      
 "body" => {                                   
    "$" => {                          
      "matchers" => [ {"match" => "type"} ]
    }                   
  }                   
}                                        

What am I missing here?

bethesque commented 5 years ago

I'm sorry, v3 is only partially supported. It's a (slow) work in progress.

YOU54F commented 3 months ago

The matching rules are not correctly serialised for v3 pacts as per the spec and progress will be tracked against the above linked issue.

Thanks for the code pointers they will be helpful for anyone attempting to fix in the future

as a side-note pact-js now uses the pact-reference project via ffi, and supports v3/v4 spec with the correct matching rules, so that should be solved for non ruby users.