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

Return most specific match when multiple matches are found

Open jstockwin opened this issue 3 years ago • 4 comments
trafficstars

I have a contract for /endpoint, which returns a list of items. It's possible to apply filters in query params, e.g. /endpoint?type=foo, but this is optional.

Let's say I have three interactions:

  1. path: /endpoint (no query)
  2. path: /endpoint, query: type=foo
  3. path: /endpoint, query: type=bar

When running the stub server, if I make a request for /endpoint?type=foo the stub service matches both (1) and (2). It (correctly) does not match (3). It throws a warning about multiple matches, and says WARN -- : Sorting responses by response status and returning first.

I understand that we're trying to be permissive here - i.e. in the case that interaction (2) didn't exist, I'd see why you'd want to return (1) instead of 404/500. However, in the case that one match is more specific, it'd be nice to return this.

In my case, I'm getting the response from (1), which is returning all items instead of only items with type=foo. Then when trying to use the stub-service for integration testing, the filtering appears to not work.

I have tried explicitly setting query="" when running my unit tests (to make 1 more explicit), but this does not get saved into the contract file.

My current workaround is to put xxxx into my test name for the one with no query params. This means the test runs last, and so is the last entry in the contract json file, meaning the more specific one happens to get picked first.

jstockwin avatar Oct 19 '22 09:10 jstockwin

Can you confirm the version you are using? I can't replicate this, it works correctly for me.

With a Pact file with those 3 interactions, I get:

❯ curl 'http://127.0.0.1:40957/endpoint'
{"response":1}
❯ curl 'http://127.0.0.1:40957/endpoint?type=foo'
{"response":2}
❯ curl 'http://127.0.0.1:40957/endpoint?type=bar'
{"response":3}
❯ curl -v 'http://127.0.0.1:40957/endpoint?type=x'
*   Trying 127.0.0.1:40957...
* Connected to 127.0.0.1 (127.0.0.1) port 40957 (#0)
> GET /endpoint?type=x HTTP/1.1
> Host: 127.0.0.1:40957
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< access-control-allow-origin: *
< content-length: 0
< date: Mon, 24 Oct 2022 05:17:05 GMT
< 
* Connection #0 to host 127.0.0.1 left intact

rholshausen avatar Oct 24 '22 05:10 rholshausen

Hi @rholshausen, thanks for the response.

I've just created https://github.com/jstockwin/pact-issue-demo to demonstrate this issue.

If I curl http://localhost:8000/endpoint?type=bar there, I'm getting the (incorrect) response of {"type":"none"}.

The docker-logs.txt file shows the messages about multiple interactions matching.

I probably should have mentioned that I'm doing this through the pactfoundation/pact-cli:latest docker image. Am I in the wrong place?

Overriding the command there to run the version command of the CLI gives me 0.5.0. I don't seem to be able to do this for the stub-service command on it's own.

jstockwin avatar Oct 26 '22 09:10 jstockwin

Ah! Yeah, that would need to be addressed with the pact-cli project. It is a different implementation.

rholshausen avatar Nov 03 '22 04:11 rholshausen

I'll move this issue to that project

rholshausen avatar Nov 03 '22 04:11 rholshausen