<#1063 Term/array on query parameters generate inv...
# pact-js-development
g
#1063 Term/array on query parameters generate invalid matching rules and expected value Issue created by pdeszynski Software versions Please provide at least OS and version of pact-jsOS: Mac OSX 13.2.1 • Consumer Pact library: @pact-foundation/pact-core@13.13.4, @pact-foundation/pact@10.4.1, jest-pact@0.10.2 • Node Version:
v19.7.0
Issue Checklist Please confirm the following: ☑︎ I have upgraded to the latest ☐ I have the read the FAQs in the Readme ☑︎ I have triple checked, that there are no unhandled promises in my code and have read the section on intermittent test failures ☑︎ I have set my log level to debug and attached a log file showing the complete request/response cycle ☑︎ For bonus points and virtual high fives, I have created a reproduceable git repository (see below) to illustrate the problem (https://github.com/pdeszynski/pact-test) Expected behaviour When running test like:
Copy code
import { MatchersV3, TemplateQuery } from '@pact-foundation/pact';
import { HTTPMethods } from '@pact-foundation/pact/src/common/request';
import { pactWith } from 'jest-pact/dist/v3';
import axios from 'axios';
import qs from 'querystring';

pactWith({ consumer: 'Test', provider: 'Test' }, (interaction) => {
  interaction('Test', ({ provider, execute }) => {
    const request = {
      ids: MatchersV3.eachLike('id', 1),
    };

    const response = [{ example: 'response' }];

    beforeEach(() => {
      provider
        .uponReceiving('test request')
        .given('test given')
        .withRequest({
          method: HTTPMethods.GET,
          path: '/expected/url',
          query: request as TemplateQuery,
        })
        .willRespondWith({
          status: 200,
          body: response,
        });
    });

    execute('it will work', async (mockserver) => {
      const result = await axios.get(mockserver.url + '/expected/url', {
        params: {
          ids: ['id'],
        },
        paramsSerializer: {
          serialize: (params: any) => qs.stringify(params),
        },
      });

      expect(result.status).toEqual(200);
    });
  });
});
Should generate a matching rule like:
Copy code
"query": {
  "$.ids": { //...
Actual behaviour Running previous test generate pact with a rule on
$.ids[0]
and an example value for ids. This makes
stub-server
not matching requests.
Copy code
{
  "consumer": {
    "name": "Test"
  },
  "interactions": [
    {
      "description": "test request",
      "request": {
        "matchingRules": {
          "query": {
            "$.ids[0]": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type",
                  "min": 1
                }
              ]
            }
          }
        },
        "method": "GET",
        "path": "/expected/url",
        "query": {
          "ids": [
            "[\"id\"]"
          ]
        }
      },
      "response": {
        "body": [
          {
            "example": "response"
          }
        ],
        "headers": {
          "Content-Type": "application/json"
        },
        "status": 200
      }
    }
  ],
  "metadata": {
    "pact-js": {
      "version": "10.4.1"
    },
    "pactRust": {
      "ffi": "0.4.0",
      "models": "1.0.4"
    },
    "pactSpecification": {
      "version": "3.0.0"
    }
  },
  "provider": {
    "name": "Test"
  }
}
Whether such case is not described in the docs, then using a
term
should be:
Alternatively, if the order of the query parameters does not matter, you can specify the query as a hash. You can embed Pact::Terms or Pact::SomethingLike inside the hash.
Also an issue was already closed with some PRs being added pact-foundation/pact-reference#205 so I'm assuming that this should work already? This also leads to wrongly generated
matchingRule
(
$.ids[0]
instead of
$ids
) Steps to reproduce Run the snipped above / replace
MatchersV3.eachLike
with
Matchers.term({generate: 'id', matcher: '(.+)'})
Relevant log files None pact-foundation/pact-js