Is there any way we can only validate field name not value in Pact json - pact

The example below is the response. In this I just want to validate field not field value from the body.
When I do pact verify:
{
"provider": {
"name": "provider"
},
"consumer": {
"name": "consumer"
},
"interactions": [
{
"description": "A valid data read request",
"request": {
"method": "GET",
"path": "/v1/users",
"query": {
"user": [
"1"
]
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"name": "xyz",
"work": "gen",
"age": "29",
}
},
"providerStates": [
{
"name": "user exists state"
}
]
}
],
"metadata": {
"pactSpecification": {
"version": "3.0.0"
},
"pact-jvm": {
"version": "4.0.4"
}
}
}
Only i need to validate field such as name, age and work not field value.

got solution we can achieve this using
final DslPart body = new PactDslJsonBody()
.stringType("name", "xyz")
.stringType("work", "gen")
.integerType("age", 29)
or for only optional
DslPart body = new PactDslJsonBody()
.eachKeyLike("name", PactDslJsonRootValue.stringType("xyz"))
.eachKeyLike("work", PactDslJsonRootValue.stringType("gen"))
.eachKeyLike("age", PactDslJsonRootValue.integerType(29))
.asBody()
and set this body to PactDslWithProvider body and we can have matching rule generated in the json so that when we verify only the field type and field name

Related

How to find the parent keys of a jsonpath result

I have this json obj
{
"abc": {
"some_field": {
"title": "Token",
"type": "password"
},
"some_field_2": {
"title": "Domain",
"type": "text"
},
"some_field_3": {
"title": "token2",
"type": "password"
}
}
}
And I want to get a list of keys [some_field,some_field_3] where type=password
This jsonpath $..[?(#.type=='password')] returns:
[
{
"title": "Token",
"type": "password"
},
{
"title": "token2",
"type": "password"
},
]
What should I do?
Thanks.
You are almost there, just need to add a ~ to the end to get the key(s) instead of the value(s):
$..[?(#.type=='password')]~
Note: this might not work depending on your jsonpath engine. It works on https://jsonpath.com.

Pact provider verification fails with : For input string: "\null"

I am trying to validate on the provider side but getting error -
Verifying a pact between DataConsumer and DataProvider
[Using File pact/DataConsumer-DataProvider.json]
Given some state
a request for json data
Request Failed - For input string: "\null"
Not sure what did I miss here.
My Pojo -
#EqualsAndHashCode
#RequiredArgsConstructor
#Builder(toBuilder = true)
#JsonDeserialize(builder = DataModel.DataModelBuilder.class)
public class DataModel {
#JsonProperty("name")
private final String name;
#JsonProperty("price")
private final double price;
}
Pact -
{
"provider": {
"name": "DataProvider"
},
"consumer": {
"name": "DataConsumer"
},
"interactions": [
{
"description": "a request for json data",
"request": {
"method": "GET",
"path": "/get/ice/2.0"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset\u003dUTF-8"
},
"body": {
"price": 10,
"name": "some name"
},
"matchingRules": {
"header": {
"Content-Type": {
"matchers": [
{
"match": "regex",
"regex": "application/json(;\\s?charset\u003d[\\w\\-]+)?"
}
],
"combine": "AND"
}
}
},
"generators": {
"body": {
"$.name": {
"type": "ProviderState",
"expression": "\\${name}",
"dataType": "STRING"
},
"$.price": {
"type": "ProviderState",
"expression": "\\${price}",
"dataType": "FLOAT"
}
}
}
},
"providerStates": [
{
"name": "some state"
}
]
}
],
"metadata": {
"pactSpecification": {
"version": "3.0.0"
},
"pact-jvm": {
"version": "3.6.15"
}
}
}
Test -
#ExtendWith(SpringExtension.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#Provider("DataProvider")
#PactFolder(value = "pact")
public class ContractVerificationTest {
#TestTemplate
#ExtendWith(PactVerificationSpringProvider.class)
void pactVerificationTestTemplate(PactVerificationContext context) {
context.verifyInteraction();
}
#State("some state")
void testPact() {
}
}
Code -
https://github.com/nrworld4/pact-consumer-demo
https://github.com/nrworld4/pact-demo-provider
You aren't returning the values (name, price) from your provider state annotation in your provider test (it's currently doing nothing) so when Pact tries to replace the values dynamically in the request they are null.
Do you actually need them to be generated by the provider in the first place?
See
https://pactflow.io/blog/injecting-values-from-provider-states/ for a detailed example of how to use and fix.
Update
Could it be that you're double escaping the parameters?
In the example:
.queryParameterFromProviderState("accountNumber", "\${accountNumber}", "100")
In your code:
.valueFromProviderState("price", "\\${price}", 10.0)

How to generate mock server for pact consumer from contract json file?

I want to use contract file from provider to run tests against consumer.
I have
{
"provider": {
"name": "Provider"
},
"consumer": {
"name": "Consumer"
},
"interactions": [
{
"description": "Get data",
"request": {
"method": "Get",
"path": "/data/1"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"message": ""
}
},
"providerState": "state"
}
],
"metadata": {
"pact-specification": {
"version": "2.0.0"
},
"pact-jvm": {
"version": "3.5.6"
}
}
And want to use it to generate pact mock server like:
RequestResponsePact pact = new RequestResponsePact(mockServerDescriptionString);
Is it possible to do this?
No. But you can use the pact-stub-server or the pact-stub-service CLI

In swagger-editor can I control whether to send an empty parameter or not send the parameter

Swagger-editor sends optional array parameters even when they are empty.
Is there a way to specify in Swagger 2.0 to not send the optional parameter if it is an empty array?
The target of the request is intended to be a list of Cats and/or a list of Dogs - neither of which are required.
I was hoping that if the request contains only Cats, the caller would only provide a list of Cats, and not have to also send an empty list of Dogs.
The swagger-editor enforces the empty list.
POST http://example:9090/api/testpath HTTP/1.1
Content-Type: application/json
{
"Dogs": [
1
],
"Cats": []
}
I am not sure whether this would be a valid request.
POST http://example:9090/api/testpath HTTP/1.1
Content-Type: application/json
{
"Dogs": [
1
]
}
This is an example swagger specification
{
"swagger": "2.0",
"info": {
"title": "demo",
"version": "Draft 0.1.0"
},
"host": "example:9090",
"schemes": [
"http",
"https"
],
"basePath": "/api",
"produces": [
"application/json"
],
"paths": {
"/testpath": {
"post": {
"summary": "Request with a complex target\n",
"parameters": [
{
"name": "target",
"in": "body",
"required": true,
"description": "Array of collars and/or mobs to target with this request.",
"schema": {
"$ref": "#/definitions/TargetObjects"
}
}
],
"responses": {
"200": {
"description": "The request was accepted."
}
}
}
}
},
"definitions": {
"TargetObjects": {
"type": "object",
"description": "Target of a request may be one or more objects or different types.\n",
"properties": {
"Dogs": {
"description": "A list of Dogs.",
"type": "array",
"items": {
"type": "number",
"format": "int64"
}
},
"Cats": {
"description": "A list of Pets.",
"type": "array",
"items": {
"type": "number",
"format": "int64"
}
}
}
}
}
}

Using Pact.eachLike() when array contents vary for each item

Hi I have a Consumer test produced using Pact NPM https://www.npmjs.com/package/pact
I use the following code to generate a pact.json:
provider
.addInteraction({
state: 'test',
uponReceiving: 'a test,
withRequest: {
method: 'GET',
path: '/test'
},
willRespondWith: {
status: 200,
headers: { 'Content-Type': 'application/json' }
body: {
"company": like("My big company"),
"factories": eachLike({
"location": like("Sydney"),
"capacity": like(5)
},{min:1})
}
}
})
.then(function(){ done(); });
It generates the following testconsumer-testprovider.json file:
{
"consumer": {
"name": "TestConsumer"
},
"provider": {
"name": "TestProvider"
},
"interactions": [
{
"description": "a request for loans",
"providerState": "broker is logged in, list all loans",
"request": {
"method": "GET",
"path": "/test"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/vnd.hal+json"
},
"body": {
"company": "My big company",
"factories": [
{
"location": "Sydney",
"capacity": 5
}
]
},
"matchingRules": {
"$.headers.Content-Type": {
"match": "regex",
"regex": "application\\/.*json.*"
},
"$.body.company": {
"match": "type"
},
"$.body.factories": {
"min": 1
},
"$.body.factories[*].*": {
"match": "type"
},
"$.body.factories[*].location": {
"match": "type"
},
"$.body.factories[*].capacity": {
"match": "type"
}
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "3.0.0"
}
}
}
However when we test against the following provided output we get an error with the geographicCoords because it's an unexpected key/value:
{
"company": "My Company",
"factories": [
{
"location": "Sydney",
"capacity": 5
},
{
"location": "Sydney",
"geographicCoords": "-0.145,1.4445",
"capacity": 5,
}
]
}
So is there a was to allow unexpected key/values in arrays because we're only test for required key/values and we don't want out pact tests to fail in future when new values are added to our providers.
The scenario you are describing is supported, see https://github.com/pact-foundation/pact-js/tree/master/examples/e2e for an example.
If you were to remove, say the eligibility object and run the tests everything still works.
If you are still having troubles, please raise a defect on the pact-js repository and we'll get to the bottom of it.

Resources