How to compare two JSON fields in RestAssured and Hamcrest? - rest-assured

I'm using RestAssured and Hamcrest to functional test our Back-end API and I'd like to know if there's any way to compare two distinct JSON fields inside the body method, or any equivalent.
For example, given the JSON response below:
[
{ name: "Foo", age: 25 },
{ name: "Bar", age: 30 }
]
And given the code below, with a little excerpt of an invalid source code line that exposes what I'm trying to achieve:
given()
.when()
.get("/my-endpoint")
.then()
.body("[0].age", lessThan("[1].age")); // Invalid code just to show what I need to do
How can I achieve the goal exposed above in a clean way?

I think I have found the best way of doing it. It's quite simple actually.
I just need to:
given()
.when()
.get("/my-endpoint")
.then()
.body("[0].age", resp -> lessThan(resp.path("[1].age"));

Related

How come KSQLDB push query outputs chunked json?

I'm new to KsqlDB so I might be missing something obvious. My question is related to the chunked JSON output of a never-ending push-query not being valid JSON. Let me elaborate.
In short, my setup is as follows. From a typescript/node process I've created a push query on a ksql stream as such:
CREATE STREAM events (id VARCHAR, timestamp VARCHAR, location VARCHAR, events ARRAY<VARCHAR>) WITH (kafka_topic='mytopic', value_format='json', partitions=1);
The push query itself is created as a long-running REST stream (using axios):
const response = await axios.post(
`http://ksqldb-server:8088/query-stream`,
{
sql: `SELECT * FROM events EMIT CHANGES;`,
streamsProperties: {}
},
{
headers: {
'Content-Type': 'application/vnd.ksql.v1+json',
Accept: 'application/vnd.ksql.v1+json',
},
responseType: 'stream',
}
);
This works. When run, I first get the header row:
[{"header":{"queryId":"transient_EVENTS_2815830975103425962","schema":"`ID` STRING, `TIMESTAMP` STRING, `LOCATION` STRING, `EVENTS` ARRAY<STRING>"}}
Followed by new rows coming in one-by-one based on real-world events:
{"row":{"columns":["b82baad7-a87e-4617-b18a-1782b4cb49ce","2022-05-16 08:03:03","Home",["EventA","EventD"]]}},\n
Now, if this query would ever complete it would probably end up as valid JSON when concatenated together (although the header row is missing a , at the end). Since it's a push query however, it never completes and as such I won't receive the closing ] - which means it will never be valid JSON. Also, I'm looking to process events in real-time, otherwise I could have written a pull query instead.
My expectations were that each new row would be parseble by itself using JSON.parse(). Instead, I've ended up having to JSON.parse(data.slice(0, -2)) to get rid of the additional ,\n. However, it does not feel right to put this into production.
What is the rational behind outputting chunked JSON on push queries? It seems an illogical format to me for any use-case.
And is there a way to alter the output of ksql events to what I would expect? Maybe some header or attribute I'm missing?
Thanks for your insights!
You explicitly set application/vnd.ksql.v1+json as your desired response format in the headers:
headers: {
'Content-Type': 'application/vnd.ksql.v1+json',
Accept: 'application/vnd.ksql.v1+json',
},
application/vnd.ksql.v1+json means that the complete response will be a valid JSON doc.
As you pointed out, this is impractical as the push query never completes. You should remove the headers or set them explicitly to the default application/vnd.ksqlapi.delimited.v1. application/vnd.ksqlapi.delimited.v1 means that the every returned row is going to be valid JSON.
See https://docs.ksqldb.io/en/latest/developer-guide/ksqldb-rest-api/streaming-endpoint/#executing-pull-or-push-queries for more details.

Swapping Rails 4 ParamsParser removes params body

I'm trying to follow this solution to add a params parser to my rails app, but all that happens is that I now get the headers but no parameters from the body of the JSON request at all. In other words, calling params from within the controller returns this:
{"controller"=>"residences", "action"=>"create",
"user_email"=>"wjdhamilton#wibble.com",
"user_token"=>"ayAJ8kDUKjCiy1r1Mxzp"}
but I expect this as well:
{"data"=>{"type"=>"residences",
"attributes"=>{"name-number"=>"The Byre",
"street"=>"Next Door",
"town"=>"Just Dulnain Bridge",
"postcode"=>"PH1 3SY",
"country-code"=>""},
"relationships"=>{"residence-histories"=>{"data"=>nil},
"occupants"=>{"data"=>nil}}}}
Here is my initializer, which as you can see is almost identical to the one in the other post:
Rails.application.config.middleware.swap(
::ActionDispatch::ParamsParser, ::ActionDispatch::ParamsParser,
::Mime::Type.lookup("application/vnd.api+json") => Proc.new { |raw_post|
# Borrowed from action_dispatch/middleware/params_parser.rb except for
# data.deep_transform_keys!(&:underscore) :
data = ::ActiveSupport::JSON.decode(raw_post)
data = {:_json => data} unless data.is_a?(::Hash)
data = ::ActionDispatch::Request::Utils.deep_munge(data)
# Transform dash-case param keys to snake_case:
data = data.deep_transform_keys(&:underscore)
data.with_indifferent_access
}
)
Can anyone tell me where I'm going wrong? I'm running Rails 4.2.7.1
Update 1: I decided to try and use the Rails 5 solution instead, the upgrade was overdue anyway, and now things have changed slightly. Given the following request:
"user_email=mogwai%40balnaan.com
&user_token=_1o3Kpzo4gTdPC2bivy
&format=json
&data[type]=messages&data[attributes][sent-on]=2014-01-15
&data[attributes][details]=Beautiful+Shetland+Pony
&data[attributes][message-type]=card
&data[relationships][occasion][data][type]=occasions
&data[relationships][occasion][data][id]=5743
&data[relationships][person][data][type]=people
&data[relationships][person][data][id]=66475"
the ParamsParser middleware only receives the following hash:
"{user":{"email":"mogwai#balnaan.com","password":"0h!Mr5M0g5"}}
Whereas I would expect it to receive the following:
{"user_email"=>"mogwai#balnaan.com", "user_token"=>"_1o3Kpzo4gTdPC2b-ivy", "format"=>"5743", "data"=>{"type"=>"messages", "attributes"=>{"sent-on"=>"2014-01-15", "details"=>"Beautiful Shetland Pony", "message-type"=>"card"}, "relationships"=>{"occasion"=>{"data"=> "type"=>"occasions", "id"=>"5743"}}, "person"=>{"data"=>{"type"=>"people", "id"=>"66475"}}}}, "controller"=>"messages", "action"=>"create"}
The problem was caused by the tests that I had written. I had not added the Content-Type to the requests in the tests, and had not explicitly converted the payload to JSON like so (in Rails 5):
post thing_path, params: my_data.to_json, headers: { "Content-Type" => "application/vnd.api+json }
The effects of this were twofold: Firstly, since params parsers are mapped to specific media types then withholding the media type meant that rails assumed its default media type (in this case application/json) so the parser was not used to process the body of the request. What confused me was that it still passed the headers to the parser. Once I fixed that problem, I was then faced with the body in the format of the request above. That is where the explicit conversion to JSON is required. I could have avoided all of this if I had just written accurate tests!

Post Method with NSDictionary Values using Swift

I'm completely new toSwift. I need to hit a Post Method webservice with NSDictionary parameters & get the JSON response. I tried usingAlamofire & also NSMutableUrlRequest. Nothing seems to workout for me. I either get 'JSON text did not start with array or object and option to allow fragments not set' error or 'Undefined Variable' response from the server. The same service works fine when I try using Objective-C. As I said earlier, I am completely new toSwift & need your assistance.
My base url: http://myofficeit.in/bizfeed/webservices/client.php
Parameter I wanna Pass:
Parameter =
{
UserName = xyz;
deviceModel = iPhone;
deviceToken = "949264bc cd9c6c851ee64cc74db9078770dd7d971618ec20ce91d2e6eb9f155e";
emailid = "xyz#gmail.com";
location = Asia;
userMobileNo = 1234567890;
};
functionName = register;
The code I used for hitting the service is: http://pastebin.com/aaT4uhS7
Thanks
you can use like
let param: [String:AnyObject] = [
"UserName": iPhone,
"deviceToken": "949264bc cd9c6c851ee64cc74db9078770dd7d971618ec20ce91d2e6eb9f155e",
"emailid": "xyz#gmail.com",
"location": Asia,
"userMobileNo": 1234567890
]
Alamofire.request(.POST, "http://myofficeit.in/bizfeed/webservices/client.php/register", parameters: param).responseJSON { (req, res, json, error) in
print(req)
print(res)
print(json)
print(error)
}
for sample request in Alamofire
As broad as your question is, the broad will be my answer:
The first thing to do, is to get a clear idea about the web service API, which also requires a basic knowledge of the HTTP protocol. So, what you need to understand is, what the server expects in HTTP terminology.
You eventually will find out, how the server will expect its "parameters". Note, that there is no term like "parameters" in the HTTP protocol. So, you need to map them into something the HTTP protocol provides.
Most likely, in a POST request, "parameters" are transferred as the body of the HTTP message, as a content-type which is application/x-www-form-urlencoded, multipart/form-data or application/json.
According to the needs of the server, and with your basic knowledge of HTTP and NSURLSession, NSURLComponents etc., you compose the URL and the body of the request, set Content-Type header and possibly other headers and you are ready to go.
How this eventually looks like is given in the answer of #AnbyKarthik, which used Alamofire, and a command that composes a POST request whose parameters are send in the body whose content-type is x-www-form-urlencoded.

restkit google maps

I'm using RestKit v0.20.0-pre6 for iOS. My input is JSON from a service running on Google App Engine. This is what is being returned from the service:
{
action:"NOP",
payload:null,
timeStamp:new Date(1359427714679),
type:null
}
This is the error I'm getting displayed from RestKit in the output window:
E restkit.network:RKResponseMapperOperation.m:240
Failed to parse response data: Loaded an unprocessable response (200) with content type 'application/json'
It is choking when NSJSONSerialization is called to parse the data. I'm sure it is the line that contains new Date(1359427714679), but I am unsure on how to parse this line. The RestKit documentation mentions writing your own formatter, but I'm unclear on how to do this.
Any insight on how to solve this issue would be much appreciated.
You've got a couple of problems with your JSON here. Firstly, your keys need to be in inverted commas "". Secondly, your web service needs to provide the timestamp as a string.
Try ISO8601 format, e.g.
{
"action" :"NOP",
"payload" : null,
"timeStamp" : "1901-12-13T20:45:52+00:00",
"type": null
}
You can check that your JSON is valid by pasting it into an online validator such as http://www.jslint.com/.

RoR: to_json on an array of hashes

I have an array of hashes in a Rails action which i return to client in json format:
{"msg": "Got report data.Check 'report' json object. ", "success": true, "reports": "[{\"total_transfers\": 0, \"total_keywords\": 0, \"keyword\": \"plum\", \"total_duration\":1464.0, \"total_calls\": 22, \"total_sms\": 0, \"avg_duration\": 67,\"total_email\": 0}]"}
In action i do: return reports.to_json but as you can see it does not look like valid json (why the escape characters?)
In client side js code, i do reports.length and get 163??? when it should say 1 because there is only one "report" in the reports array.
As you can see "reports" is one big string, instead of an array of a hash which you'd expect (163 is the length of the string, and this is why you can see escape characters). Which json library are you using with rails? What kind of object is your array of hash exactly? It might not have the to_json method implemented...
Alternatively you might try to convert your repsonse to yaml first, from that getting json is easier.
reports_array_object = eval("(" + reports + ")");
sweet!!!!

Resources