Should it be possible to use matchers in content-t...
# pact-js
a
Should it be possible to use matchers in content-types of a request? (V3 .59 & .60) I get
PactffiWithBody(arg 2) expected a string
m
As in, a header?
I think so
t
(in the pact file, at least)
well, maybe not explicitly. They are at least in the examples 😅
a
this works for me
Copy code
provider.uponReceiving(`as '${user}', a PUT request to upload a file to '${file}'`)
    .withRequest({
      method: 'PUT',
...
      contentType: 'text/plain; charset=utf-8'
    })
    .willRespondWith(response)
but this not
Copy code
provider.uponReceiving(`as '${user}', a PUT request to upload a file to '${file}'`)
    .withRequest({
      method: 'PUT',
...
      contentType: MatchersV3.regex('text/plain(;()?charset=(utf|UTF)-8)?', 'text/plain; charset=utf-8')
    })
    .willRespondWith(response)
m
It should definitely be supported. Is the error on the consumer or provider side?
I know I tested it with Go so the core supports it at least, so could be a bug/feature in JS land if we haven't added it there
a
running the consumer tests I get
PactffiWithBody(arg 2) expected a string
m
sorry, you did say that Artur
a
If that supposed to be supported and its a limitation I can try to look into it today, let's see what I find
m
OK just looked. This is the consumer request content type, right? Any reason you need a matcher there? In any case, the
contentType
property cannot be a matcher (see the type definition). It says “this is the content type of this request”. It’s an optional field though.
for now, you can do it the way you used to - don’t set
contentType
but set the header
Content-Type
and use the matcher there - that should work as you expect
a
I need a matcher there because different versions of the provider answer differently, but both inside of the specs. e.g. upper/lowercase
m
In your example above it’s the consumer, but I assume you want the provider also? If so, same deal.
a
'text/xml; charset=utf-8'
is valid but also
Copy code
'application/xml; charset=UTF-8'
m
e.g. this sort of thing
Copy code
withResponse: {
              headers: { "Content-Type": MatchersV3.regex('text/plain(;()?charset=(utf|UTF)-8)?', 'text/plain; charset=utf-8') },
            },
a
yes finally its about the provider Thanks I will try that
m
yep, we do support it - just omit
contentType
all together and use the standard header matching
I’m tempted to remove the
contentType
definition altogether. We can derive it by other means (extract from headers) and default to JSON otherwise.
what do you think?
a
yes, why not. at the end of the day its just a header like any other
t
Oh! Pact V3 is supposed to understand the content type anyway
You can just say it's application/json and it should work even if there's a charset given by the actual code
👍 1
At least, according to the spec
Matchers are still supposed to work in headers, so there's still a bug
But, if you only need this for content type, just omit the charset and it is supposed to work
m
Matchers are still supposed to work in headers, so there’s still a bug
Artur wasn’t using it on the headers but an optional
contentType
field on the response object. That doesn’t take a matcher, but the exact content type of the request / response
a
also with xml?
m
it should, yes
a
works fine with putting the content-type only in the header. I cannot remember why I started to use the
contentType
parameter maybe it was because of this issue https://github.com/pact-foundation/pact-js/issues/575
m
might have been! I’m still a little hazy on what should be explicitly set by the user in a pact test (via something like
contentType
- not the header), implicitly via content sniffing in the core, or via the usual header match.
My sense is to use headers, and to not add additional overhead via
contentType
a
here the next issue, maybe related I have this interaction in the JSON file
Copy code
"description": "as 'admin', a POST request to create a user",
"request": {
  "body": "password=1234&userid=testUser1",
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded",
    "authorization": "Basic YWRtaW46YWRtaW4="
  },
......
with .59 it sends me the data as expected with .60 it converts the body to a JSON string (see wireshark screenshot)