How to verify types from response? - rest-assured

I have to check json response if it contains needed types. What do I mean:
{
"success": {
"anonym_id": 11156,
"has_empty_profile": false,
"token": "4690e404-cfec-4918-b555-2f0d84675eee",
"twins": [],
"uid": 7380
}
}
So I have to check that "anonym_id" is int(not a specific number like here 11156, but just int), "has_empty_profile" is boolean, "token" is string etc.
How to do that with rest assured?

Best way to do this is
JsonPath js1 = new JsonPath(new File(
"Your Json I stored in a file"));
assertTrue(js1.get("success.findAll {anonym_id -> anonym_id=11156}.has_empty_profile") instanceof Boolean);
assertTrue(js1.get("success.findAll {anonym_id -> anonym_id=11156}.token") instanceof String);

Related

Invalid Expression exception for JsonPath in RestAssured

We are using restassured for API automation in our project . I have sample response for which I tested JsonPath expression on https://www.jsonquerytool.com/. My Json expression is - $[*]['tags'][?(#.id==0)].
I am getting proper output when I tried expression on JsonQuerytool. But when I try same in below code , I get invalid expression message -
JsonPath jsonPathEvaluator = response.jsonPath();
ArrayList result = jsonPathEvaluator.get("$[*]['tags'][?(#.id==0)]");
Above code throws exception .
Can anyone tell me how can I programmatically query the response using JsonPathEvaluator ?
P.S - Response not pasted as it was very huge.
Since your issue is not in any particular query (expression does not matter) I'm answering using example from the link you provided.
RestAssured uses some special JsonPath library (which uses its own syntax in some cases) called GPath. So if you have json like this:
{
"key": "value",
"array": [
{
"key": 1
},
{
"key": 2,
"dictionary": {
"a": "Apple",
"b": "Butterfly",
"c": "Cat",
"d": "Dog"
}
},
{
"key": 3
}
]
}
And expect you would use query like this: $.array[?(#.key==2)].dictionary.a
Then for RestAssured case your query would be like this: array.findAll{i -> i.key == 2}.dictionary.a
So the complete code example would be:
public static void main(String[] args) {
JsonPath jsonPath = RestAssured
.get("http://demo1954881.mockable.io/gath")
.jsonPath();
List<String> resp = jsonPath.get("array.findAll{i -> i.key == 2}.dictionary.a");
System.out.println(resp);
}

ktor dynamic keys serialization and json preprosesing

Is there anyway in Ktor to alter a json before deserialization process? In the example below there is a json with dynamic keys in which i need to remove the "token" key as it is of a string type instead of an object type as the other keys.
When i urn the code i get the following error:
Exception in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Expected class kotlinx.serialization.json.JsonObject as the serialized body of shell.remoting.Market, but had class kotlinx.serialization.json.JsonLiteral
I'm not sure if there is another better way to do it. Any suggestion will be appreciated, thanks
object MarketMapSerializer :
JsonTransformingSerializer<Map<String, Market>>(MapSerializer(String.serializer(), Market.serializer())) {
override fun transformSerialize(element: JsonElement): JsonElement =
JsonObject(element.jsonObject.filterNot { (k, _) ->
k == "token"
})
}
#Serializable
data class Market(
val stations: List<Station>,
)
#Serializable
data class Station(
#JsonNames("iata_code")
val iataCode: String,
val destinations: List<String>,
)
fun main() {
val jsonString = """
{
"Republica Dominicana": {
"stations": [
{
"iata_code": "PUJ",
"destinations": [
"ADZ",
"BAQ",
"VVC"
]
}
]
},
"Brasil": {
"stations": [
{
"iata_code": "AJO",
"destinations": [
"ADZ",
"BAQ",
"VVC"
]
}
]
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkb3RSRVogQVBJIiwianRpIjoiYTVhZDM4NmYtOGViNy0yOWQ5LWZkMGYtM2Q3MzQwZmRhOGI2IiwiaXNzIjoiZG90UkVaIEFQSSJ9.V2YfXCt9r7Tzae9SYSoj-qIyxjRc9YoE2XPoIQQNI9U"
}
""".trimIndent()
println(
Json.decodeFromString(
MarketMapSerializer,
jsonString
)
)
}
Just replace transformSerialize with the transformDeserialize since you're doing deserialization.

Flutter Dio doesn't accept int value as queryParameters

I'm making a call using Dio that send some query parameters, using map constructor
response = await Dio().get(url, queryParameters: {
"apikey": publicKey,
"hash": hash,
"ts": timestamp,
"nameStartsWith": searchTerm
});
Everything works correctly, but when try to send a int value, Dio throw a error
response = await Dio().get(url, queryParameters: {
"apikey": publicKey,
"hash": hash,
"ts": timestamp,
"nameStartsWith": searchTerm,
"page" : 10
});
type 'int' is not a subtype of type 'Iterable < dynamic > '#0
And i can't just convert the int value to string, because api is expcting int type.
Any help ?
There is no such thing as an int type in an URL and therefore in query parameters.
An URL can only be a String.
Just convert it to String and be done.

How to get a sub-field of a struct type map, in the search response of YQL query in Vespa?

Sample Data:
"fields": {
"key1":0,
"key2":"no",
"Lang": {
"en": {
"firstName": "Vikrant",
"lastName":"Thakur"
},
"ch": {
"firstName": "维克兰特",
"lastName":"塔库尔"
}
}
}
Expected Response:
"fields": {
"Lang": {
"en": {
"firstName": "Vikrant",
"lastName":"Thakur"
}
}
}
I have added the following in my search-definition demo.sd:
struct lang {
field firstName type string {}
field lastName type string {}
}
field Lang type map <string, lang> {
indexing: summary
struct-field key {
indexing: summary | index | attribute
}
}
I want to write a yql query something like this (This doesn't work):
http://localhost:8080/search/?yql=select Lang.en from sources demo where key2 contains 'no';
My temporary workaround approach
I have implemented a custom searcher in MySearcher.java, through which I am able to extract the required sub-field and set a new field 'defaultLang', and remove the 'Lang' field. The response generated by the searcher:
"fields": {
"defaultLang": {
"firstName": "Vikrant",
"lastName":"Thakur"
}
}
I have written the following in MySearcher.java:
for (Hit hit: result.hits()) {
String language = "en"; //temporarily hard-coded
StructuredData Lang = (StructuredData) hit.getField("Lang");
Inspector o = Lang.inspect();
for (int j=0;j<o.entryCount();j++){
if (o.entry(j).field("key").asString("").equals(language)){
SlimeAdapter value = (SlimeAdapter) o.entry(j).field("value");
hit.setField("defaultLang",value);
break;
}
}
hit.removeField("Lang");
}
Edit-1: A more efficient way instead is to make use of the Inspectable interface and Inspector, like above (Thanks to #Jo Kristian Bergum)
But, in the above code, I am having to loop through all the languages to filter out the required one. I want to avoid this O(n) time-complexity and make use of the map structure to access it in O(1). (Because the languages may increase to 1000, and this would be done for each hit.)
All this is due to the StructuredData data type I am getting in the results. StructureData doesn't keep the Map Structure and rather gives an array of JSON like:
[{
"key": "en",
"value": {
"firstName": "Vikrant",
"lastName": "Thakur"
}
}, {
"key": "ch",
"value": {
"firstName": "维克兰特",
"lastName": "塔库尔"
}
}]
Please, suggest a better approach altogether, or any help with my current one. Both are appreciated.
The YQL sample query I guess is to illustrate what you want as that syntax is not valid. Picking a given key from the field Lang of type map can be done as you do in your searcher but deserializing into JSON and parsing the JSON is probably inefficient as StructuredData implements the Inspectable interface and you can inspect it directly without the need to go through JSON format. See https://docs.vespa.ai/documentation/reference/inspecting-structured-data.html

Reskit parse multiple type of data for the same field

I just want to ask if there is a way to parse the following field "mods" in Reskit:
post_count: false,
sitename: "Mercury",
mods: false,
admin_email: "maystro#test.com",
here mods has a boolean value and in the next example it has an object as a value:
post_count: false,
sitename: "Mercury",
mods: {
0: false,
author_blocks: {
enabled: {
placebo: "placebo"
},
disabled: {
2: "jbckmn",
placebo: "placebo"
}
},
backups: null,
smof_init: "Wed, 14 May 2014 18:53:58 +0000",
custom_logo: "",
custom_logo_height: "1",
custom_login_logo: "",
custom_login_logo_height: "1",
custom_favicon: ""
}
In the same JSON response we're receiving this type of data, sometimes mods has a boolean value and sometimes it has an object. Does anyone knows if there is a way to do a dynamic mapping using Restkit to handle such cases?
Thanks in advance
Indeed yes. You want to use an RKDynamicMapping, and return the actual mapping you want to use from that; something like:
RKDynamicMapping *dynamicMapping = [RKDynamicMapping new];
[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {
if ([representation valueForKey:#"MyKey"] isKindOfClass:[NSNumber class]])
{
return aMappingWhenTheFieldIsANumber;
}
else
{
return aMappingWhenTheFieldIsNotANumber;
}
}];
In this manner, you get to pick the mapping to use when you have the data in hand. Just check the data for the field type, and return a normal RKObjectMapping appropriate for the field types.

Resources