Conditional check for Json array in Karate framework - json

Want to validate in Karate framework
For the below Json What I want to validate is,
if "isfilter_regex":0 then "msgtype": "##regex ^[A-Za-z0-9_.]-/*"
or if "isfilter_regex":1 then "msgtype": "#string"
(when isfilter_regex = 1 then msgtype must be a regular expression)
In my case number of candidate s in candidates array is 180+
I tried lot of things I ended up failing can anybody help me here?
{
"candidates":[
{
"candidate":{
"name":"Alex",
"category":[
{
"category_name":"APCMRQ",
"filters":[
{
"isfilter_regex":0,
"msgtype":"APCMRQ"
}
]
},
{
"category_name":"BIDBRQ",
"filters":[
{
"isfilter_regex":1,
"msgtype":"'(AMSCNQ(_[A-Za-z0-9]{1,3}){0,3})'"
}
]
}
]
}
}
]
}

I tried below way which works only when idex specified, but what to do if I want to do this check for entire array?,
* def msgRegexValue = response.candidates[150].candidate.category[0].filters[0].isfilter_regex
* def actualFilter = response.candidates[150].candidate.category[0].filters[0]
* def expectedFilter = actualFilter
* def withRegex =
"""
{
"isfilter_regex": 0,
"msgtype": '##regex ^[A-Za-z0-9_.]*-*/*'
}
"""
* def withoutRegex =
"""
{
"isfilter_regex": 1,
"msgtype": '##string'
}
"""
* def expected = msgRegexValue == 0 ? withRegex: withoutRegex
* match actualFilter == expected

Related

How to provide keys with special char in karate.filterKeys?

Response:
[
{
"key1":78,
"key2":"value2",
"key3": {
"obj.key1":"objValue1",
"obj.key2":1236527454,
}
},
{
"key1":89,
"key2":"value2",
"key3": {
"obj.key1":"objValue1",
"obj.key2":9885546755,
}
}
]
Expected Response:
[
{
"key1":32,
"key2":"value2",
"key3": {
"obj.key1":"objValue1",
"obj.key2":8985436,
}
},
{
"key1":36,
"key2":"value2",
"key3": {
"obj.key1":"objValue1",
"obj.key2":655431,
}
}
]
key1, obj.key2 are dynamic values that need to be ignored while comparing the rest of the JSON.
* match karate.filterKeys(response,['key1']) == karate.filterKeys(expectedResponse,['key1'])
It works as expected and ignores key1 while comparing results.
* match karate.filterKeys(response,['key1','key3["obj.key2"]') == karate.filterKeys(expectedResponse,['key1','key3["obj.key2"]'])
The above throws error. I also tried using:
* match karate.filterKeys(response,['key1',key3['obj.key2']) == karate.filterKeys(expectedResponse,['key1',key3['obj.key2']])
As that's normally how special char keys are used in karate, but again getting error.
Can someone please provide a way around for this problem?
I recommend a different approach since you have a complicated nesting and JSON that has horrible keys. Use JSON transforms to get the data in the "shape" you want, and then things become easy.
* def fun =
"""
function(x) {
var y = {};
y.key2 = x.key2;
y.key3 = {};
y.key3['obj.key1'] = x.key3['obj.key1'];
return y;
}
"""
* def temp = karate.map(response, fun)
* match each temp == { key2: 'value2', key3: { 'obj.key1': 'objValue1' } }

Optional field in JSON response

The query I run is going to return a response which I split into two schemas:
* def tagsSchema =
"""
{
"lifecycle-status": "#string",
"infrastructure-environment": "#string",
"managed-by": "#string",
"supported-by": "#string",
"operated-by": "#string"
}
"""
and this schema is integrated into the my content schema:
* def contentSchema =
"""
{
"phase": "##string",
"managedBy": "##string",
"assetId":"##string",
"isValid": ##boolean,
"name": "#string",
"supportedBy": "##string",
"links": '#[] linksSchema',
"ownedBy": "##string",
"cmdbInstanceId":"#string",
"tags": "##object? karate.match(_,tagsSchema).tags",
}
"""
The tagsSchema is optional which I have covered by the ##object. When I run the query now it fails as I do have additional values in tagsSchema.
getList.feature:159 - path: $[0].tags, actual: {"technicalreferant":"email1","billingowner":"xyz","responsibleManager":"email1","environment":"abc","application":"tbd","consumer":"cdr","cr":"12345678"}, expected: '##object? karate.match(_,tagsSchema).tags', reason: did not evaluate to 'true'
The issue is coming from the karate.match but there is no karate.contains. How do I have to modify the schema to avoid this error. The values in the tagsSchema are mandatory while the others can be created by the user at any time and we don't have a policy for them. I don't want to adjust the code every run-time and only rely on mandatory values.
I'm not sure why you see the need to use karate.match() and you need to read the documentation. Here's a simple example below:
* def innerSchema = { foo: '#string' }
* def outerSchema = { bar: '#string', baz: '##(innerSchema)' }
* def response1 = { bar: 'x' }
* match response1 == outerSchema
* def response2 = { bar: 'x', baz: { foo: 'y' } }
* match response2 == outerSchema

Parsing JSON using Groovy where array and multiple objects have no name to get list

new to groovy and coding in general. Trying to do the following:
(I have looked at many previous Q&As in stackoverflow but none of the solutions I found seem to work)
I have the following JSON from which I need to get a list/string of supplier names i.e. output should be something like : "supplier 1, supplier 2, supplier 3"
[
{
"id":217564,
"created-at":"2020-01-22T08:59:57+00:00",
"state":"submitted",
"supplier":
{
"name":"supplier 1"
}
},
{
"id":217565,
"created-at":"2020-01-22T09:00:00+00:00",
"state":"submitted",
"supplier":
{
"name":"supplier 2"
}
},
{
"id":217566,
"created-at":"2020-01-22T09:00:48+00:00",
"state":"submitted",
"supplier":
{
"name":"supplier 3"
}
}
]
I used the following groovy script to print out all the supplier names in a list:
import groovy.json.*;
#CustomScriptAction(
input = ['json_response'],
output = 'suppliers'
)
def CustomScriptAction14()
{
def object = new JsonSlurper().parseText(json_response.toString())
def suppliers = "No suppliers"
if(object != null && !object.isEmpty())
{
for(def i =0; i<object.size();i++)
{
suppliers = RString.of(object[i].'supplier'.name.toString());
}
}
return suppliers
}
I got the output: "supplier 3"
The issue is that this script is only giving me the last supplier in the loop instead of iterating through the entire loop and printing out all the suppliers. So I tried a different script:
import groovy.json.*;
#CustomScriptAction(
input = ['json_response'],
output = 'suppliers'
)
def CustomScriptAction14()
{
def object = new JsonSlurper().parseText(json_response)
def suppliers = object.findAll { it.value instanceof List }
.values()
.flatten()
.collect { [it.'supplier'.'name'] }
}
return suppliers
But with this I get a blank response.
What am I doing wrong?
Well this ended up working:
import groovy.json.*;
#CustomScriptAction(
input = ['json_response'],
output = 'suppliers'
)
def customScript()
{
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(json_response.toString())
suppliers = RString.of(object.'supplier'.'name'.toString())
}

Unable to split the values in jsonobject in groovy

I'm new to groovy. I'm trying to split the values in json object in groovy but i cant seem to find a solution. Please find the sample code below
def inputFile = new File("C:\\graph.json")
def InputJSON = new JsonSlurper().parseFile(inputFile,'UTF-8')
InputJSON.each{println it}
def names = InputJSON.graph;
def name
for (int kk=0;kk<4;kk++)
{
name=names.JArray1[kk]
run.put(name.runid, name.rundetails);
println "test::"+name.runid+"--------------"+name.rundetails
}
graph.json
{
"graph": {
"JArray1": [
{
"runid": 1,
"rundetails":{
"01_Home":0.231,
"02_Login":0.561}
}
]
}
}
name.rundetails contains the below values
[01_Home:0.231, 02_Login:0.561]
I would like to split and add it as key and value in Hashmap like below format
Key:01_Home Value:0.231
Key:02_Login Value:0.561
How would i do that any advise on this would be helpful. Thanks in advance.
import groovy.json.*
def inputFile = new StringReader('''
{
"graph": {
"JArray1": [{
"runid": 1,
"rundetails": {
"01_Home": 0.231,
"02_Login": 0.561
}
}
]
}
}
''')
def json = new JsonSlurper().parse(inputFile)
json.graph.JArray1.each{run->
println "runid = ${run.runid}"
// at this point `run.rundetails` is a map like you want
println "details = ${run.rundetails}"
}
As I understand you need collection like:
[[Key:01_Home, Value:0.231], [Key:02_Login, Value:0.561]]
Then you may do:
println InputJSON.graph
.JArray1
.rundetails
.collectEntries{it}
.collect{[Key: it.key, Value: it.value]}

Get value of variable from json using jsonslurper

I have the following JSON code:
{
"TIMESTAMP":"2017-05-26-20.22.40.016000",
"dateTime":"2017-05-26H-20.22.4",
"AMUCCY1":"ADP",
"rates":[
{
"AMUCCY2":"AED",
"AMURAT":"1.000000000",
"AMUNXRT":0
},
{
"AMUCCY2":"AFA",
"AMURAT":"1.000000000",
"AMUNXRT":0
},
{
"AMUCCY2":"ALL",
"AMURAT":"1.000000000",
"AMUNXRT":0
},
{
"AMUCCY2":"AMD",
"AMURAT":"1.000000000",
"AMUNXRT":0
}
]
}
Is there quick way in groovy where I could loop through each of the 'rates' and get the value of, let's say 'AMUCCY2' ?
I tried doing this code:
jsonObj.rates.each {
def toCurrencyMap = jsonObj.rates.AMUCCY2
LOG.info "${toCurrencyMap}"
}
but the toCurrencyMap returns an array of all four values of this field. I only want to get each value; not all.
Any suggestions is appreciated.
You can try this:
jsonObj.rates.each {
println it.AMUCCY2
}
If you want list / array:
def result = jsonObj.rates.collect { it.AMUCCY2 }
println result