Hello, Pact Foundation I am facing an issue with ...
# pact-js
n
Hello, Pact Foundation I am facing an issue with consumer-provider tests while running pact tests. For context, in this test, the provider is expected to respond with an html document, in other words with content-type = text/html; charset=utf-8. The consumer tests have the following expected body: willRespondWith: { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' }, body: regex(regexp, "<html><head></head><body><h1>Hello, World!</h1></body></html>") } where
regex
is a V3RegexMatcher and the consumer tests are all passing as expected. The issue arises in the provider test where the html in the response is not tested against the provided regex and I keep getting the following error: Expected body '{"pactmatchertype":"regex","regex":"<html>[\\\\s\\\\S]*?<head>[\\\\s\\\\S]*?<\\\\/head>[\\\\s\\\\S]*?<body>[\\\\s\\\\S]*?<\\\\/body>[\\\\s\\\\S]*?<\\\\/html>","value":"<html><head></head><body><h1>Hello, World!</h1></body></html>"}' to match ' <here goes the html document in the actual response> ' The question we have is: How can we test the content of a response that is not in JSON format, rather it is a string as in an HTML document? I have tried with
like
,
somethingLike
,
regex
,
string
and it seems like none of them work for our purposes/needs. Thank you for your time and help in advance.
p
@Matt (pactflow.io / pact-js / pact-go) @Yousaf Nabi (pactflow.io)
j
There's no need to @ mention people. We monitor these channels regularly and will respond in time.
m
I suspect I was wrong about matchers on non-JSON content. Ideally, regex matcher would work on any text-based content type
@rholshausen am I right about ^^
r
As the saying goes: You have a problem. You add a regex to solve the problem. Now you have two problems.
I would never add a regex to try match an HTML document. Rather use XML if you can, or just assert that the content is the correct type.
m
That’s a good point. But more generally, does the regex matcher only work on JSON properties, or would it work for other content type bodies also?
r
Regex works on anything, if you can work out the regex to use
j
It might be worth having multiple individually simpler regex patterns. E.g., one to match the opening and closing
<html>
, and a couple of patterns to find some specific values within.
Also it might be important to make clear what kind of regex matcher Pact is using internally; whether it matches the entire content as one long string, or line by line, and whether
.
matches new lines or not
m
The reason it looks like it’s not, is that you can see the “Expected body” includes the integration JSON on it. Maybe it’s a different language verifying it @Noel Rojas what version of Pact JS are you using? What language are you using to run the verification?
r
Ah! Now I understand your question. No, the intermediate JSON is for JSON only.
😆 1
m
It would make sense to support it for other content types, I can raise a feature request. How difficult would it be? I’m imagining the error scenarios about when a matcher can/can’t apply would be one of the primary challenges
r
There are only 2 or 3 matchers that you can use with general text format
m
yeah, regex is the one that jumps out
n
@Matt (pactflow.io / pact-js / pact-go) I am using version
^12.1.0
for both the consumer and provider. Also both consumer and provider are in TypeScript/JavaScript.
👍 1
m
Thanks Noel. As per above, we don’t support using matchers on non-JSON bodies.
Do you need to actually assert the contents of the HTML? If so, you could use the XML interface (see the examples on the Pact JS github repo). Alternatively, if you don’t actually need to assert on the body, you can just check you get the correct content type as a response
n
Thanks Matt. I am already asserting for the correct content type. I will take a look at the XML docs
👍 1
m
What's the actual use case?
n
What I am trying to do is verify that the provider actually returns valid HTML.
👍 1
Just wanted to check for some HTML tags that must be in the body. I am not looking to verify/validate the entire HTML document.
👍 1
m
OK cool, see how you go with the XML matcher then, I think that should work
r
Also the content type matcher, but I'm unsure how you would specify that with Pact-JS
m
Good point. Remind me how that is done via the FFI?
r
By calling FFI functions
😅 1
nod hmm yes 1
m
Ah, it’s the
contentType
matcher in IntegrationJSON. Can this apply at any level? e.g. could you have a field that is base64 encoded and use this matcher? Or does it only apply at the level of the entire response?
r
No, you have to use the FFI functions to set the matcher, you can't use that form on non-JSON
Maybe have a look at Python, it might have implemented it (FYI @Joshua Ellis)
j
Unfortunately, I don't think that's been implemented in Python yet. The wrapper for the FFI is there, but it still requires the JSON matcher to be built manually. I will need to add Python matchers at some point to make it much more user friendly
m
No, you have to use the FFI functions to set the matcher, you can’t use that form on non-JSON
I’m not sure I follow this, sorry. Which FFI function?
j
I believe Ron is referring to pactffi_with_matching_rules
r
Yeah, that one
👍 1
j
It serves to add matching rules directly, which can match any part of the payload (as per the matching rule). This is distinct to the smarts done in some of the other functions (e.g. ,
with_body
) which can detect JSON content and try and convert it to a matching rule
👍 1
m
got it, thanks