Rest Assured - comparing the json path with another - java

I have json for example below
{"TestJson":{
"Result":"Passed",
"description":"Passed."},
"Students":[{
"Class":{
"Primary":"Yes"
},
"Course":{
"Enrolled":"yes",
"AccountNumber":"2387287382"
},
"AccountNumber":"2387287382",
"Paid":"Yes"
}]}
I am wondering how can I find a good solution for this.
What I currently do
.body("Students[0].Course.AccountNumber",equalTo("2387287382"))
.body("Students[0].AccountNumber",equalTo("2387287382"))
My test criteria is to check key Students[0].AccountNumber matches Students[0].Course.AccountNumber
I want to do in this way, but i am not able to find a solution something like
.body("Students[0].Course.AccountNumber",equalTo("Students[0].AccountNumber"))
The above wont work obviously, but that is how I want to compare. basically comparing the key with another key and they should match.
Is this doable?

One way to do it is:
String A =
given ().
when().
get/put/post({api/name})
.extract()
.path("Students[0].Course.AccountNumber");
String B =
given ().
when().
get/put/post({api/name})
.extract()
.path("Students[0].AccountNumber");
Assert.assertEquals(A, B);
Seems like this workaround is the only way to go.

See the Use the response to verify other parts of the response section of the rest-assured docs. You basically want to create a lambda implementing ResponseAwareMatcher<Response>. Something like this:
get("/x").then().body("href", response -> equalTo("http://localhost:8080/" + response.path("userId"));

Related

How to combine JSON values in the response using Java

I am currently working on a school project. We have a series of response templates in JSON format that will take values from the request and then return it accordingly in the response when run in postman.
e.g
Request:
{
"Application_id":123456
}
Response:
{ "Application_id: 123456, TIMESTAMP: 20220501}
I am able to get these values in the response but the issue I am running accross now is figuring out how to combine 2 values in the request into one like so:
Request:
{
"Application_id":123456
"user_id_first_six": 456789
"user_id_last_four": 1234
}
Expected Response:
{ "Application_id: 123456, TIMESTAMP: 20220501, combined_id:456789****1234}
what I have tried is to put combined_id : "user_id_first_six"+******+"user_id_last_four" but this doesnt work.
Apologies if I cant be more specific as there are portions that I have left out due to confidentiality issues.
The easiest way to achieve this in Java would be to use JSONObject. In your Request-Handler, add two parameters of Type JSONObject and then merge them:
jsonObj.putAll(jsonObj1)
Thanks all for the guidance. I basically did what Knu8 suggested and extracted the values using Matcher+Regex (<(.*)>)(\W*)(<(.*)>) and converted them to strings and then used StringBuilder to append all the components together.

Why my list is empty when I am parsing correct json response?

I am trying to print the ids from a JSON response. But I am not able to understand why I am getting a blank list. I have verified the JSONpath (SECTIONS_IDS_JSONPATH) from the online website and it is giving me correct results.
public static void main(String[] args) {
String SECTIONS_IDS_JSONPATH = "$.[*].instructionEvents[*].sectionId";
String sectionsData = "{\"sections\":[{\"id\":\"8da1cf5d-3150-4e11-b2af-338d1df20475\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":0,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[],\"instructionEvents\":[{\"id\":\"9d0c49e2-1579-43c3-b25a-2f85f551e62d\",\"sectionId\":\"8da1cf5d-3150-4e11-b2af-338d1df20475\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"monday\",\"wednesday\",\"friday\"],\"startTm\":\"2019-01-01T09:45:00-05:00\",\"endTm\":\"2024-12-01T10:45:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]},{\"id\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":20,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[{\"id\":\"c26572de-f9c8-4623-ba6a-79997b33f1c6\",\"sectionId\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"role\":\"primary\",\"persons\":[{\"id\":\"c1b50d79-5505-4a33-9316-b4b1f52c0ca3\",\"names\":[{\"firstName\":\"BanColoFac-1\",\"lastName\":\"CTester\",\"preferred\":true}]}]}],\"instructionEvents\":[{\"id\":\"af8fb500-29f5-4451-95d5-a11215298cd4\",\"sectionId\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"tuesday\",\"thursday\"],\"startTm\":\"2019-01-01T10:00:00-05:00\",\"endTm\":\"2024-12-01T10:50:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]},{\"id\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":20,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[{\"id\":\"808daae1-3ec6-47ec-9af0-5392199bdf78\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"role\":\"primary\",\"persons\":[{\"id\":\"793cc9b3-57c7-4a2d-8984-07a1fb6834a9\",\"names\":[{\"firstName\":\"Andrew\",\"lastName\":\"Adams\",\"preferred\":true}]}]}],\"instructionEvents\":[{\"id\":\"730b4206-684d-4413-bf20-9bec5c1dc900\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"tuesday\",\"thursday\"],\"startTm\":\"2019-01-01T10:00:00-05:00\",\"endTm\":\"2024-12-01T10:50:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"},{\"id\":\"8bc059ab-a8f8-4469-8e79-bbc71f7fa3fd\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"monday\",\"wednesday\",\"friday\"],\"startTm\":\"2019-05-26T09:00:00-04:00\",\"endTm\":\"2021-05-26T09:50:00-04:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]}]}";
List<String> ids = JsonPath.parse(sectionsData).read(SECTIONS_IDS_JSONPATH);
System.out.println(ids);
}
Alright, since this question might get delete if nothing else ever happens I better post this as an answer.
As explained by Andreas you should use JSONPath $.*[*].instructionEvents[*].sectionId instead. Quoting fromt the comment
The syntax $.[*] is undefined, I can't find any documentation/example
doing that. The JSONPath Online Evaluator [*based on
JSONPath-Plus implemented in JavaScript] treats it as $..[*], but the Java library treats
it differently. Since the outer part of the JSON is {"sections":[ ... ]}, you have an object, so you need a property selector (.prop or
.*). Once you've selected your property (.sections, or .*
since there's only one), the property is an array, so you need an
array selector ([2] or [*]). Hence you can use $.sections[*] or
$.*[*] to match all sections.
Indeed, looking at this massive JSONPath Comparision we can see that the syntax in question is not listed for any implementation.

WebTestClient check jsonPath against another jsonPath

I have this "content" response from which I need to assert some values.
WebTestClient.BodyContentSpec content = response.expectStatus().isOk()
.expectBody()
.jsonPath("$.path1").isEqualTo(value1);
If I want to assert some JSON paths with predefined values all is good.
But the tricky part comes when I wanna check if a JSON path is equal to another JSON path.
JsonPathAssertions jsonPath2 = bodyContentSpec.jsonPath("$.path2");
JsonPathAssertions jsonPath3 = bodyContentSpec.jsonPath("$.path3");
So my question is how can I assert the content of jsonPath2 against jsonPath3 using org.hamcrest.Matchers.greaterThanOrEqualTo?
I think you could use the value(Consumer) method:
for simple operations:
jsonPath2.value(v->jsonPath3.isEqualTo(v));
for using special Matchers:
jsonPath2.value(v->jsonPath3.value(Matchers.greaterThanOrEqualTo(v)));

Two rest api response diff using rest assured

I am trying to compare the rest API response of two environments. I am using rest assured to get the response back. The problem I am facing is that I get a hashmap back which has a couple of hashmaps.
I have tried flattening the map into one map but keep on missing a hierarchy when the response differs slightly
here is a sample of the rest response
{
programmes:[
{
episodenumber:21,
seasonnumber:5,
seasontitle:"program Season 5",
seasonuuid:"7aabb30e-39a1-48bb-8dca-38f732c9c982",
seriestitle:"programm",
seriesuuid:"f95caa09-8cd7-4e23-a88a-444f7932714d",
sy:"blah blah blah. (S5, ep 21)",
t:"blah blah Fathers",
trailer:false,
type:"programme",
uuid:"69b91264-37c9-4b2f-a515-b45805a58867",
uuidtype:"programme",
waystowatch:{
svod:[
{
ad:false,
added:1495800164,
at:"DD",
availendtime:1497729599,
broadcasttime:1495137600,
cgid:10053,
cgname:"blah",
channelname:"blah1 HD",
d:2880,
downloadlink:"oig://FFC27E94",
hardofhearing:false,
is3d:false,
providerid:"ab_st_hd",
providername:"blah HD",
s:true,
sid:4061,
size:2352611,
sy:"blah blah. (S5, ep 21)",
videotype:"HD"
}
}
] ps:255,
tc:3
}
I am using the guava diff lib and for that, i need a simple map. I know this might not be the best of doing this comparison but this is for a short duration and this is what I can come up with. My question is how do I either flatten this response to make one map which i can pass to
MapDifference<String, ?> diff = Maps.difference(test, test2);
or is there a better way to compare two responses in rest assured. I have to get both the response at runtime.
If you are open to evaluating other tools take a look at Karate because it has been designed to:
allow you to specify expected payloads in (simplified) JSON itself
enable you to perform a "deep equals" comparison of two JSON payloads
be flexible so that you do a contains if you only want to check a sub-set of fields
handle dynamic values by letting you mark those fields as to be ignored or use a fuzzy match
even let you handle arrays where the elements are JSON (not just primitives), and ignore the order if needed
Disclaimer: am dev.

Java API to implement query for script_fields in Elastic search

I have tried to find the answer of this question but couldn't find. The scenario is: I have to get one extra field which is the calculation of two fileds in the elastic search query result. For this purpose I am using script_fields.
"script_fields": {
"result": {
"script": "doc['feild1'].value / doc['field2'].value"
}
}
The query is working fine, and I am getting the correct result.
But now I have to implement the query in Java, I couldn't find any way to implement script_fields in Java.
Can somebody please help ?
Very simply using the addScriptField() method like this:
SearchResponse response = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("result", new Script(ScriptType.INLINE, "groovy", "doc['field1'].value / doc['field2'].value", Collections.emptyMap()))

Categories

Resources