Prophet
Prophet

Reputation: 33361

Rest Assured response - validating nodes matching the same path

In my tests a have a responses like this:

{
    "commands": [
        {
            "type": "com.our.identity.patch",
            "value": [
                {
                    "op": "add",
                    "path": "/claims/gTwfQubKEl4r",
                    "value": [
                        "vcvWxlsLKV35"
                    ]
                },
                {
                    "op": "add",
                    "path": "/claims/Jmq6zrG7LKoJ",
                    "value": [
                        "iiMQoOWKu2OI"
                    ]
                }
            ]
        }
    ]
}

Where gTwfQubKEl4r and vcvWxlsLKV35 are key - value pair.
The same about Jmq6zrG7LKoJ and iiMQoOWKu2OI key - value pair.
The response can include many key - value pairs.
I need to be able to validate if some key and value are presented in the response or not.
I use restassured java so I know I can use a path like commands.value.path to get the key and commands.value.value to get the value with these methods I wrote:

public String getValueFromResponseBody(Response res, String key){
    return res.body().jsonPath().getString(key);
}
public void validateParameterValueInResponseBodyEquals(Response res, String param, String expectedValue){
    String value = getValueFromResponseBody(res,param);
    Assert.assertEquals(value,expectedValue);
}

Where passed param is parameter path inside the response like commands.value.path.
But I think this will bring me the first node inside the response body matching the passed path while I need to check against all the nodes inside the response matching that path.
Is it possible?

Upvotes: 0

Views: 818

Answers (1)

lucas-nguyen-17
lucas-nguyen-17

Reputation: 5917

I think this will bring me the first node inside the response body matching the passed path while I need to check against all the nodes inside the response matching that path

No, it get all that match. Since commands node and value node are both array, so it will produce a list of list.

List<List<String>> lists = JsonPath.from(res).getList("commands.value.path");
[[/claims/gTwfQubKEl4r, /claims/Jmq6zrG7LKoJ]]

List<String> list = JsonPath.from(res).getList("commands[0].value.path")
[/claims/gTwfQubKEl4r, /claims/Jmq6zrG7LKoJ]

String str = JsonPath.from(res).getString("commands[0].value[0].path");
/claims/gTwfQubKEl4r

Solution:

To get all the path in one query, you just need to make List<List<String>> --> List<String>. You could try flatMap in stream or use another way.

List<List<String>> lists = JsonPath.from(res).getList("commands.value.path");
List<String> flat = lists.stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());
flat.forEach(System.out::println);
/claims/gTwfQubKEl4r
/claims/Jmq6zrG7LKoJ

One more option:

You can use JsonPath (com.jayway.jsonpath.JsonPath)

List<String> list = JsonPath.read(res, "$..path");
list.forEach(System.out::println);
/claims/gTwfQubKEl4r
/claims/Jmq6zrG7LKoJ

Upvotes: 1

Related Questions