pact-php icon indicating copy to clipboard operation
pact-php copied to clipboard

Pact-PHP <=9.x.x - Verification failed when the query has nested keys

Open mark-onenetwork opened this issue 4 years ago • 7 comments

Hi All,

I encountered a weird issue: verification failed when the query has nested keys key_a[]=1&key_b[1]=2, key_a is an array, key_b is a hash.

Here is the output:

W, [2021-09-28T01:44:25.107664 #4532]  WARN -- : Verifying - actual interactions do not match expected interactions.
Incorrect requests:
        GET /api/products/my_endpoint?travel_date=2021-04-10&key_b[1]=2&key_a[]=1 (request query did not match)

Diff with interaction: "A get request to /api/products/my_endpoint" given "Resource 112 exists, and is available on 2021-05-21"
Diff
--------------------------------------
Key: - is expected
     + is actual
Matching keys and values are not shown

 {
   "query": {
-    "key_a": [
+    "key_a[]": [
       "1"
     ]

Description of differences
--------------------------------------
* Could not find key "key_a" (keys present are: key_b[1], key_a[]) at $.query
* Did not expect the key "key_a[]" to exist at $.query

I debug code and got some clues:

  1. When parsing the expected interaction, the query string: key_a[]=1&key_b[1]=2 is covert to key_a=1&key_b[1]=2 because of the logic here.
  2. However when trying to match the candidate interactions with actual request, the square brackets in the actual query key key_a[]=1 is not removed as in expected interaction key_a=1, which causes the inconsistency between expected interaction and actual interaction.

I'm wondering if it's a bug.

mark-onenetwork avatar Sep 28 '21 02:09 mark-onenetwork

The query matching logic is a nightmare, because there are many different ways a query can be parsed. I'm afraid you'll need to try using a string query expectation in this case.

bethesque avatar Sep 28 '21 06:09 bethesque

@bethesque Thanks for the quick response. Then it's a "know issue". Could you please explain a bit more on using string query expectation instead? Would be appreciated, I'm not Ruby expert.

mark-onenetwork avatar Sep 28 '21 06:09 mark-onenetwork

Can you please copy your Pact expectation code into a comment.

bethesque avatar Sep 28 '21 07:09 bethesque

$request = new ConsumerRequest();
$request
    ->setMethod('GET')
    ->setPath('/api/products/my_endpoint?key_a[]=1&key_b[1]=2')
    ->addHeader('Content-Type', 'application/json');

It's in PHP, probably no way to do that.

mark-onenetwork avatar Sep 28 '21 07:09 mark-onenetwork

Ah, it's already a string. Is there no separate method to set the query? In the other languages, the path and the query are set separately, so that suggests to me that something in the php is splitting them out.

bethesque avatar Sep 28 '21 21:09 bethesque

Yes, there is a separate method to set the query.

$request = new ConsumerRequest();
$request
    ->setMethod('GET')
    ->setPath('/api/products/my_endpoint')
    ->setQuery('key_a[]=1&key_b[1]=2')
    ->addHeader('Content-Type', 'application/json');

mark-onenetwork avatar Oct 08 '21 01:10 mark-onenetwork