Add better support for WireMock's RequestMatcherExtension
With RequestMatcherExtension we could consider allowing giving the users the option to pass in their own, custom matching options. Sth like this:
class DefaultRequestMatcher extends RequestMatcherExtension {
private static final String GROOVY_EXPRESSION = "groovy-expression";
@Override
public MatchResult match(Request request, Parameters parameters) {
if (!parameters.containsKey(GROOVY_EXPRESSION)) {
return MatchResult.exactMatch();
}
String expression = parameters.getString(GROOVY_EXPRESSION);
GroovyShell groovyShell = new GroovyShell();
groovyShell.setVariable("body", request.getBody());
return MatchResult.of(groovyShell.evaluate(expression) != null);
}
@Override
public String getName() {
return GROOVY_EXPRESSION;
}
}
the WireMock stub could look like this:
{
"request" : {
"customMatcher" : {
"name" : "groovy-expression",
"parameters" : {
"groovy-expression" : "new JsonSlurper(body.asString()).findAll {it.name == 'foo'}"
}
}
},
"response" : {
"status" : 422
}
}
then in the DSL one could call:
bodyMatchers {
expression('new JsonSlurper(body.asString()).findAll {it.name == 'foo'}')
}
To consider:
- security issues (you can run an arbitrary Groovy code)
- maybe SPeL would be enough
- passing in slurped body (either json or xml) instead of WireMock's body
As per our (@marcingrzejszczak and I) discussion yesterday:
Tim: I’d suggest to start with a custom matcher based on SPeL, and make a separate one for groovy? Like you said, it has a lot of security implications. Marcin: I wonder if Spel is actually good enough to do the slurping etc. cause the body would need to be converted to a map or sth for spel to work. otoh we already parse groovy scripts that can contain all sort of crap. Tim: That’s also true 😂 But passing the slurped body to both custom matchers should make your life easier I guess. Marcin: I think that it could be a map - then Spel would work Tim: Let me add these comments to github later today, so others can see our new thoughts :)