JSON ResponseSchemaValidation in Karate - karate

"totalRows": 1,
"colDefs": [
{
"entityAttributeId": "acctNm",
"headerName": "Account Name",
"field": "2",
"entityPath": "",
"entityId": "account"
},
{
"entityAttributeId": "acctId",
"headerName": "Account ID",
"field": "1",
"entityPath": "",
"entityId": "account"
}
],
"rowData": [
{
"1": "1939",
"2": "Bay Pond Partners",
"rowMeta": {
"account": {
"acctInstrumentId": "0025-1939",
"acctId": "1939"
}
}
}
]
}
I have following response from a filter query. As the filter should return only one value, that I am validating with this :
And match GetDataSet_Response contains {"totalRows": 1}
The filter is based on Acctid. Now, I need to validate acctID value and entire json schema. How can I do it in KARATE?

In Schema you can define a
The data type of values which you are expecting but don't know the exact values.
Write an expected condition for your data.
Define the variable of data or hardcode data which you already know.
Ignore few data which don't bother.
break down your JSON and create multiple logical schemas(From your JSON you can have a separate schema for "colDefs" and "rowData")
and many more options for complex validations.
I am not sure about your exact requirement, I have tried to create a schema that might suit your requirement.
{
"colDefs": [
{
"entityAttributeId": "acctNm",
"entityId": "account",
"entityPath": "",
"field": "2",
"headerName": "Account Name"
},
{
"entityAttributeId": "acctId",
"entityId": "account",
"entityPath": "",
"field": "1",
"headerName": "Account ID"
}
],
"rowData": [
{
"1": "#string",
"2": "#string",
"rowMeta": {
"account": {
"acctId": "#(acctID)",
"acctInstrumentId": "#string"
}
}
}
],
"totalRows": 1
}
You can store schema in a JSON file / define it directly in your script and match it with your response
assume we stored this schema in a file filterResponseSchema.json
YourFilter.feature
* def acctID = "1939"
# call your filter request
* def myFilterSchema = read('filterResponseSchema.json')
* match response == myFilterSchema
Note:
i) make sure there is a variable name "acctID" before calling this schema so that karate will embed that value to you JSON schema.
ii) my assumption for your "colDefs" values will be always the same, so I hardcoded it.
Karate documentation covers a good amount of example for Schema validation
I suggest you read this for more insights.

Related

Get the value from the response based on a condition and store it to a variable

I would like to get the value from the response based on a condition and store it to a variable.
In the below JSON, I would like to store the value when the name matches to something I prefer. Is there a way to achieve this using Karate API?
{
"results": [
{
"name": "Sample1",
"email": "sample1#text.com",
"id": "U-123"
},
{
"name": "Sample2",
"email": "sample2#text.com",
"id": "U-456"
},
{
"name": "Sample3",
"email": "sample3#text.com",
"id": "U-789"
}
]
}
So after reading the comment, my interpretation is to "find" the id where name is Sample2. Easy, just use a filter() operation, refer the docs: https://github.com/karatelabs/karate#jsonpath-filters
Instead of using a filter, I'm using the JS Array find() method as a very concise example below:
* def response =
"""
{ "results": [
{ "name": "Sample1", "email": "sample1#text.com", "id": "U-123" },
{ "name": "Sample2", "email": "sample2#text.com", "id": "U-456" },
{ "name": "Sample3", "email": "sample3#text.com", "id": "U-789" }
]
}
"""
* def id = response.results.find(x => x.name == 'Sample2').id
* match id == 'U-456'
Take some time to understand how it works. Talk to someone who knows JS if needed.

API testing : Dynamic payload and dynamic assertions [duplicate]

I want to construct a complex POJO during run time based on the scenario .
In the below sample request structure consider addresses.line1 as mandatory field
And I dont have to pass the other fields everytime but need to do on test cases basis.
{
"site": [{
"code": "string",
"mrn": "string"
}
],
"email": ["string"],
"addresses": [{
"line1": "string",
"line2": "string",
"city": "string",
"state": "string",
"postalCode": "string"
}
],
"names": [{
"first": "string",
"middle": "string",
"last": "string",
"suffix": "string"
}
]
}
Ex:
For TestCase#1 I need only below JSON:
{
"addresses": [{
"line1": "string"
}
]
}
Where as for TestCase#2 I need below JSON
{
"email": ["string"],
"addresses": [{
"line1": "string",
"line2": "string"
}
],
"names": [{
"first": "string",
"last": "string"
}
]
}
I referred https://github.com/intuit/karate/blob/master/karate-demo/src/test/java/demo/outline/examples.feature
but the example was pretty straight forward with replaceable values.
I was looking for something like #JsonInclude(JsonInclude.Include.NON_DEFAULT)
Karate is designed to completely avoid POJO-s and give you complete control over creating and modifying complex JSON. So I suggest you temporarily forget about POJO-s and Java, else you won't get the best out of Karate.
There are a few ways to do this, but here is one. First store the complex JSON in a file, called main.json
Then creating the different variants is simple:
Background:
* def main = read('main.json')
Scenario: one
* def payload = karate.filterKeys(main, 'addresses')
Scenario: two
* def payload = main
* remove payload.site
I suggest you read the docs on reading files for more ideas, look out for embedded expressions.
Also see: https://stackoverflow.com/a/51896522/143475

Only structured queries are supported FIRESTORE API REST

I am trying to run a query with the rest api but I canĀ“t get it to work, I am sending this body in json:
"structuredQuery": {
"where": {
"fieldFilter": {
"field": {
"fieldPath": "total"
},
"op": "EQUAL",
"value": {
"integerValue": "10",
}
}
},
"from": [{
"collectionId": "Total"
}]
}
I am just testing if querys work, I have a collection called Total with documents, and these documents have a field called total that is an integer value. I am using a POST request with the following URL:
"https://firestore.googleapis.com/v1/projects/MY_PROJECT_NAME/databases/(default)/documents:runQuery"
and I am getting this error:
[{
"error": {
"code": 400,
"message": "only structured queries are supported",
"status": "INVALID_ARGUMENT"
}
}]
The CollectionSelector in your structured query is missing the allDescendants field.
If you check this documentation you can see that this field is a flag which can either be true or false but not null, so you have to set this in the query otherwise it will not work.
Also you need to add the select clause to add all fields you want to get as a result of the query or keep it empty to return all fields.
Finally in the said documentation you can check that there is a proper order that should be respected, in which the from must be declared before where. So if you change your structured query to the following:
"structuredQuery": {
"from": [{
"collectionId": "Total"
"allDescendants": false
}],
"select": { "fields": [] },
"where": {
"fieldFilter": {
"field": {
"fieldPath": "total"
},
"op": "EQUAL",
"value": {
"integerValue": "10",
}
}
}
}
It will work as expected.

Microsoft adaptive card choiceset iteration

i have a adaptive card choice set like below, as you can see am trying to get the value under title from a variable which is an array, is there a way i can iterate the choice set automatically because i don't know how many values the array has i want to show all the values inside the array in the choice set title
{
"type" : "Input.ChoiceSet",
"isMultiSelect": true,
"id": "myColor",
"style": "compact",
"value": "1",
"choices": [
{
"title": vars.responsedata.items[0].topic,
"value": "1"
},
{
"title": vars.responsedata.items[1].topic,
"value": "2"
},
{
"title": "Recording 3 sample",
"value": "3"
}
]
}
You can use the map() function.
Example in DataWeave:
{
choices: vars.responsedata.items map {
title: $.topic,
value: $$
}
}

Apache Nifi: UpdateRecord replace child values

I'm trying to use UpdateRecord 1.9.0 processor to modify a JSON but it does not replace the values as I want.
this is the source message
{
"type": "A",
"ids": [{
"id": "1",
"value": "abc"
}, {
"id": "2",
"value": "def"
}, {
"id": "3",
"value": "ghi"
}
]
}
and the wanted output
{
"ids": [{
"userId": "1",
}, {
"userId": "2",
}, {
"userId": "3",
}
]
}
I have configured the processor as follows
processor config
Reader:
reader
Schema registry:
schema
writer:
writer
And it works, the output is a JSON without the field 'type' and the ids have the field 'userId' instead 'id' and 'value'.
To fill the value of userId, I defined the replace strategy and the property to replace:
strategy
But the output is wrong. The userId is always filled with the id of the last element in the array:
{
"ids": [{
"userId": "3"
}, {
"userId": "3"
}, {
"userId": "3"
}
]
}
I think the value of the expression is ok because if I try to replace only one record it works fine (/ids[0]/userId, ..id)
Nifi docs has a really similar example (example 3):
https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi/nifi-standard-nar/1.7.1/org.apache.nifi.processors.standard.UpdateRecord/additionalDetails.html
But it does not work for me.
What am I doing wrong?
thanks
Finally I have used JoltJSONTransform processor instead UpdateRecord
JoltJSONTransform
template:
[
{
"operation": "shift",
"spec": {
"ids":{
"*":{
"id": "ids[&1].userId"
}
}
}
}
]
Easier than UpdateRecord