Matching values from response to values from DB - karate

My response looks as follows :
{
"data":[
{
"foo":bar1
"user_email":"user#user.com",
"user_id":1
},
{
"foo":bar2
"user_email":"user#user.com",
"user_id":1
}
]
}
* def DBOutput = #fetching values from DB
* match response.data[*].foo contains [DBOutput1[0][0],DBOutput1[1][0]]
DBOutput1 has data as follows : [["bar1"],["bar2"]]
This match fails, for some reasons value passed into the expected list in match statement is DBOutput1[0][0]
This is the error I am getting actual: ["bar1","bar2"], expected: 'DBOutput1[0][0]',

You have some seriously malformed JSON in your example above. The below snippet works, just paste it into a new Scenario:
* def response =
"""
{
"data":[
{
"foo": "bar1",
"user_email":"user#user.com",
"user_id":1
},
{
"foo": "bar2",
"user_email":"user#user.com",
"user_id":1
}
]
}
"""
* match response.data[*].foo contains ['bar1', 'bar2']
Now it is up to you to fix your test, without knowing what your DBOutput is no one can help further.

I iterated over the DBoutput and stored them in a new array list. I then matched the response to the list and it worked.
match response.data[*].foo contains ListFromDB

Related

Matching dynamic keys in karate

I am trying to match a JSON array with a predefined expected json. The problem is that one of the key values in actual JSON is a set of strings delimited by "|". Here is how it looks :
actualJSON = [
{
"a": "varA",
"mix: "X|Y|Z",
},
{
"b": "B",
"c": "C"
} ]
expectedJSON = [
{
"a": "varA",
"mix: "Y|Z|X",
},
{
"b": "B",
"c": "C"
} ]
Issue here is the mix key that represents a set of strings and the value can be any combination of "X|Y|Z" without any specific order like "Z|Y|X" etc. When the value of mix is Y|Z|X then
* match actualJSON contains expectedJSON
works fine but in other cases it fails as expected. Is there a way to do the matching when key value is dynamic?
My first suggestion is as far as possible to write tests where the response is 100% predictable and don't waste time on these weird cases. Also refer: https://stackoverflow.com/a/50350442/143475
That said this is easy to do if you write a JS function:
* def response = { foo: 'X|Y|Z' }
* def hasXyz = function(x){ return x.includes('X') && x.includes('Y') && x.includes('Z') }
* match response == { foo: '#? hasXyz(_)' }
I leave it to you to figure out better logic if you want. Refer: https://github.com/karatelabs/karate#self-validation-expressions

Karate json key list variable assignment

New to Karate, and JSON, for that matter, but I've got a variable like:
response {
entries {
products [
{
names [
"Peter Parker",
"Tony Stark",
"Captain America"
]
},
{
names [
"Thomas Tinker",
"Jimmy Johnson",
"Mama Martha"
]
}
]
}
}
match each response.entries.products[*].names returns a list like:
["Peter Parker","Tony Stark","Captain America","Thomas Tinker","Jimmy Johnson","Mama Martha"]
But I'd like to assign that output to a variable, such as:
* def variable = response.entries.products[*].names
that would hold a similar value. When I use the above line, I get the following error:
Expected an operand but found *
Is it possible to achieve that, or something similar? If so, how?
Thanks!
Yes, there is syntax for that:
* def variable = $response.entries.products[*].names
Read the docs: https://github.com/intuit/karate#get

Adding new key-value pair into json using karate

My payload looks like this :
{
"override_source": "DS",
"property_code": "0078099",
"stay_date": "2018-11-26T00:00:00.000000",
"sku_prices": [
],
"persistent_override": false
}
There is an array dblist ["2","3"] , it would consists of numbers from 1 to 4. Based on the elements present in the list, I want to add key-values {"sku_price":"1500","sku_code":"2"} to my payload. I am using the following code :
* eval if(contains("3",dblist)) karate.set('pushRatesFromDS.sku_prices[]','{ "sku_price": "1500","sku_code":"3" }')
When I execute my feature file, I do not get any errors but, key-values are not added to my payload. However if I move this code to a new feature file and call it, key-value pairs get added to my payload. The code in my new feature file looks like : * set pushRatesFromDS.sku_prices[] = { "sku_price": "1500","sku_code":"2" }
Try this:
* def foo =
"""
{
"override_source": "DS",
"property_code": "0078099",
"stay_date": "2018-11-26T00:00:00.000000",
"sku_prices": [
],
"persistent_override": false
}
"""
* eval karate.set('foo', '$.sku_prices[]', { foo: 'bar' })

How to assert substring in karate framework

I am getting an array of URLs as a response. I want to check that each URL from the array contains a specific word.
How can I check this in karate framework?
My response is :
response {
"docs":[{
"url":"http://url/1.com"
"title": "some title"
},{
"url":"http://url/2.com"
"title":"ABC"
}]
}
}
Now I want to check that each url field value contains word 'url'.How can I check this as match each $.response.docs.url contains 'url' does not work for me.
Please refer to the match each syntax. Here is an example:
* def response = [ 'http://url-one.com', 'http://url-two.com', ]
* match each response contains 'url'
EDIT - after question was edited. Here is your working example:
* def response =
"""
{
"docs":[
{
"url":"http://url/1.com",
"title":"some title"
},
{
"url":"http://url/2.com",
"title":"ABC"
}
]
}
"""
* def urls = $response.docs[*].url
* match each urls contains '/url/'

Pentaho: Getting only one in row from JSON input file

I am getting one JSON file from SFTP and trying it to insert into oracle but in the preview section i am getting only one row and only one row inserting into table. I already tried to modify to number to preview rows to 10000 but nothing working out.
{"postal_code":"XX","build_id":"XX","categories":[],"closed":false,"closed_reasons":[],"email":["XX"],"external_link":{"facebook":[],"yelp":[""]},"hq":false,"location":{"lat":xxxxx,"lon":xxxxx},"metro":"Cxxxxx, IL","naics_codes":[{"category_code":"XX","category_description":"XX"},{"category_code":"XX","category_description":"xxxxx "},{"category_code":"XX","category_description":"xxxxx "},{"category_code":xxxxx","category_description":"XX"}],"name":"XX","place_id":"XX","place_ids":["xxx","xx"],"sic_codes":[{"category_code":"XX","category_description":"XX"},{"category_code":"XX","category_description":"XX"}]}
Your example json is:
{
"postal_code":"XX",
"build_id":"XX",
"categories":[],
"closed":false,
"closed_reasons":[],
"email":["XX"],
"external_link":{
"facebook":[],
"yelp":[""]
},
"hq":false,
"location":{
"lat":xxxxx,
"lon":xxxxx
},
"metro":"Cxxxxx, IL",
"naics_codes":[
{
"category_code":"XX",
"category_description":"XX"
},
{
"category_code":"XX",
"category_description":"xxxxx "
},
{
"category_code":"XX",
"category_description":"xxxxx "
},
{
"category_code":xxxxx",
"category_description":"XX"
}
],
"name":"XX",
"place_id":"XX",
"place_ids":["xxx","xx"],
"sic_codes":[
{
"category_code":"XX",
"category_description":"XX"
},
{
"category_code":"XX",
"category_description":"XX"
}
]
}
So, if that's the total values in the response you're getting from the SFTP server, Pentaho is behaving well, because it's only one record. If you want PDI to recognize the fields inside that json, and split it's content, you need to specify the path to each field on the "Path" field available on the "Fields" tab on the "Json Input" step.
Try using the input json file as follows:
{
"data" : [
{"key":"val","key":"val"},
{"key":"val","key":"val"},
{"key":"val","key":"val"},
{"id":"666","name":"jnit"}
]
}