Want to assert that the values are not duplicated in the list - karate

I'm asserting a response like this using karate.
"Ids": ["123456","123456","123457"]
Now I want to assert that my list doesn't contain the duplicate values (If there is a duplicate value, it should fail the test-case), is there any in built function which is supported by Karate or is there any JS who does the trick?

Here you go: https://github.com/karatelabs/karate#karate-distinct
* def response = ["123456","123456","123457"]
* match response == karate.distinct(response)

Related

Karate match two json files(expected json and API response) irrespective of the order of array elements

Expected Response:
{"data":{
{"assignments":[{"locationId":"1186755","locationName":"X.11.11"},{"locationId":"1186756","locationName":"X.11.12"}]}}}
Response:
{"data":{
{"assignments":[{"locationId":"1186756","locationName":"X.11.12"},{"locationId":"1186755","locationName":"X.11.11"}]}}}
I saw a SO post stating to use karate.sort(response, x=>x.locationId), when i tried it's giving me empty response. Is there any simple way i can achieve do the comparison of whole response file irrespective of order?
Note: I even tried contains only, but it's failing the assertion.
Just use contains deep: https://stackoverflow.com/a/64373344/143475
* def response = {"assignments":[{"locationId":"1186755","locationName":"X.11.11"},{"locationId":"1186756","locationName":"X.11.12"}]}}}
* match response contains deep {"assignments":[{"locationId":"1186756","locationName":"X.11.12"},{"locationId":"1186755","locationName":"X.11.11"}]}}}

Testing Comma separated values in a field, at a time , in karate

I am testing an email API
In the the payload, I have to pass multiple values in the "to" field.
This essentially means, I need to test the functionality of sending an email to more than one recipient in Karate framework.
Is it possible to read multiple values at a time for a field in Karate?
Please help.
This has nothing much to do with Karate, but since Karate supports JS:
* def before = 'foo,bar,baz'
* def after = before.split(',')
* match after == ['foo', 'bar', 'baz']

How do use fuzzy matching validation for either a non-present key or an empty array?

In karate version 0.9.6 I used the following match statement in a .feature file and it worked for validating the value to be an empty array or a key that was not present.
def example = {}
match example.errors == '##[0]'
In 1.0 the documentation example suggests that this should check for the key being present and null or an empty array and testing this fails with a validation error that the value is not present.
From https://karatelabs.github.io/karate/#schema-validation
# should be null or an array of strings
* match foo == '##[] #string'
This appears to be an undocumented breaking change from pre-1.0 to 1.0.
My question is: how do I construct a validator to cover this case correctly when the key is allowed to be absent but if it is present it must be an empty array?
I've found an undesirable solution for now but am leaving this open in case someone has a better answer.
I'm validating the entire parent object with a minimal schema:
Replace
match $.errors == '##[0]'
With
* match $ == { data: '#object', extensions: '##object', errors: '##[0]' }
While more brittle and verbose it is technically working.
This indeed looks like an in-intended breaking change. Here is another workaround:
* def example = {}
* def expected = example.errors ? '#[0]' : '#notpresent'
* match example.errors == expected
I see you have opened an issue here: https://github.com/karatelabs/karate/issues/1825
EDIT: this might be an improvement over the workaround you came up with in your answer:
* match example contains { errors: '##[0]' }

How to check a length of array in Karate framework?

I have 2 different response from the REST Api as below
1. {"type":null,"title":"Request is invalid","status":"BAD_REQUEST","detail":"Please correct request and try again.","invalidParams":[{"name":"create.arg0.name","reason":"Name is required"}]}
2. {"type":null,"title":"Unicode char u0000 is not allowed","status":"BAD_REQUEST","detail":"Unicode char u0000 is not allowed"}
I wanna write a condtion where if invalidParams present in respose, then compare the contents of array. If not, invalidParams should be null/undefined.
Scenario Outline: Create Asset Model with missing name and status
Given url modelsUrl
And request somedata
When method POST
Then status 400
Then assert response.type == null
Then match response.status == 'BAD_REQUEST'
Then match (response.invalidParams != undefined && response.invalidParams[0].reason contains <reason>) OR (response.invalidParams == undefined)
But comparing against null/undefied & length also not working. How to handle this scenario in Karate? Normal Javascript is not working.
To check if a member exists or to check an array's length you should use assert, not match. I would also recomend breaking your last statement into multiple assertions for transparency.
here are some examples given a response with an array named 'arr':
check array length
...
And assert response.arr.length == 1
...
check array is present
...
And assert response.arr != null
...
check array is absent
...
And assert response.arr == null
...
reference: https://intuit.github.io/karate/#payload-assertions
based on the link shared by riiich, the recommended approach is to do the following for an array length = 2
match response == '#[2]'

Karate - get all specific field values from a response

On karate 0.6.0, the following code returned an array with all the ids:
def get = call read('wishlist-products-get.feature') id
def wishlist = get.response.wishlist_products
ids = wishlist[*].product_info.id
now on version 0.9.0 the same returns the following error:
wishlist[*].product_info.id, :1:9 Expected an operand but found *
Can someone tell me what change?
Thanks!
You must use the get keyword to save the results of a JsonPath expression as described in the docs.
* def ids = get wishlist[*].product_info.id