I want to write a TestScenario in Behat for a POST Method that takes an Object as input.
Feature: Testing The ChildController Endpoint
Scenario: Trying to create an Child by POSTing vars with an existing Id
Given that I want to make a new "Child"
And the request is sent as JSON
And its "screening_id" is "999888777666"
And his "first_name" is "John"
And his "last_name" is "Doe"
And his "birth_date" is "1979-01-01"
And his "gender" is "m"
When I request "/v1/child"
Then the response status code should be 409
And the response should be JSON
And the response has a "error" property
My Method is like:
/**
* Child Endpoint v1
*
* #url POST child/
* #status 201
*
* #param Child $child JSON data
* #return application/json
* #throws RestException
*/
function insertChild(Child $child){......}
My JSON Object that I pass looks like this:
{
"child": {
"screening_id": "",
"first_name": "",
"last_name": "",
"birth_date": "",
"gender": ""
}
}
Now... when I make a request with Postman with only:
{
"screening_id": "",
"first_name": "",
"last_name": "",
"birth_date": "",
"gender": ""
}
it works fine.
But when I'm running the Behat Test, it says that I specified an invalid value for 'child' and I get:
"error": {
"code": 400,
"message": "Bad Request: Invalid value specified for 'child'. Expecting an item of type `v1\\models\\Child`"
}
It works from everywhere without specifying the 'child' only from BeHat not.
Solution is to change the order of things in your behat feature file
It works this way because of the way RestContext.php bootstrap file is defined.
Currently what you have and the test result
Feature: Testing The ChildController Endpoint
Scenario: Trying to create an Child by POSTing vars with an existing Id # features/test.feature:3
Given that I want to make a new "Child" # RestContext::thatIWantToMakeANew()
And the request is sent as JSON # RestContext::theRequestIsSentAsJson()
And its "screening_id" is "999888777666" # RestContext::thatItsStringPropertyIs()
And his "first_name" is "John" # RestContext::thatItsStringPropertyIs()
And his "last_name" is "Doe" # RestContext::thatItsStringPropertyIs()
And his "birth_date" is "1979-01-01" # RestContext::thatItsStringPropertyIs()
And his "gender" is "m" # RestContext::thatItsStringPropertyIs()
When I request "/v1/child" # RestContext::iRequest()
| POST /behat_test/v1/child HTTP/1.1
| Host: localhost
| User-Agent: Guzzle/3.1.2 curl/7.43.0 PHP/5.6.15
| Content-Type: application/json; charset=utf-8
| Content-Length: 2
|
| []
| HTTP/1.1 400 Bad Request
| Date: Sun, 20 Dec 2015 04:21:56 GMT
| Server: Apache/2.4.16 (Unix) PHP/5.5.30
| X-Powered-By: Luracast Restler v3.0.0rc5
| Vary: Accept
| Cache-Control: no-cache, must-revalidate
| Expires: 0
| Content-Language: en
| Content-Length: 468
| Connection: close
| Content-Type: application/json; charset=utf-8
|
| {
| "error": {
| "code": 400,
| "message": "Bad Request: Invalid value specified for `child`. Expecting an item of type `Child`"
| },
If you look closely the request is sending only an empty array
| POST /behat_test/v1/child HTTP/1.1
| Host: localhost
| User-Agent: Guzzle/3.1.2 curl/7.43.0 PHP/5.6.15
| Content-Type: application/json; charset=utf-8
| Content-Length: 2
|
| []
Fix is to move And the request is sent as JSON below all property definitions. See below
Feature: Testing The ChildController Endpoint
Scenario: Trying to create an Child by POSTing vars with an existing Id # features/test.feature:3
Given that I want to make a new "Child" # RestContext::thatIWantToMakeANew()
And its "screening_id" is "999888777666" # RestContext::thatItsStringPropertyIs()
And his "first_name" is "John" # RestContext::thatItsStringPropertyIs()
And his "last_name" is "Doe" # RestContext::thatItsStringPropertyIs()
And his "birth_date" is "1979-01-01" # RestContext::thatItsStringPropertyIs()
And his "gender" is "m" # RestContext::thatItsStringPropertyIs()
And the request is sent as JSON # RestContext::theRequestIsSentAsJson()
When I request "/v1/child" # RestContext::iRequest()
| POST /behat_test/v1/child HTTP/1.1
| Host: localhost
| User-Agent: Guzzle/3.1.2 curl/7.43.0 PHP/5.6.15
| Content-Type: application/json; charset=utf-8
| Content-Length: 108
|
| {"screening_id":"999888777666","first_name":"John","last_name":"Doe","birth_date":"1979-01-01","gender":"m"}
Related
I have faced a problem with providing param into GET method.
I have the next URL
https://test.com/api/v1/account/?include[]=tickers&include[]=holdings&include[]=views
How to provide parameter along with empty square brackets as param in GET method in my example?
I saw https://github.com/karatelabs/karate/blob/master/karate-demo/src/test/java/demo/search/dynamic-params.feature , but didnt find my solution(
If you see Karate encoding it as %5B%5D that is actually the correct behavior: https://stackoverflow.com/a/59977660/143475
You can actually try this on httpbin.org and see for yourself that the server is able to decode it correctly. If your server cannot, it is most likely a bug.
* url 'https://httpbin.org/anything'
* param include[] = 'tickers'
* method get
See server response:
1 > GET https://httpbin.org/anything?include%5B%5D=tickers
1 > Host: httpbin.org
1 > Connection: Keep-Alive
1 > User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
1 > Accept-Encoding: gzip,deflate
17:17:10.925 [main] DEBUG com.intuit.karate - response time in milliseconds: 1528
1 < 200
1 < Date: Tue, 07 Feb 2023 11:47:10 GMT
1 < Content-Type: application/json
1 < Content-Length: 436
1 < Connection: keep-alive
1 < Server: gunicorn/19.9.0
1 < Access-Control-Allow-Origin: *
1 < Access-Control-Allow-Credentials: true
{
"args": {
"include[]": "tickers"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept-Encoding": "gzip,deflate",
"Host": "httpbin.org",
"User-Agent": "Apache-HttpClient/4.5.14 (Java/17.0.6)",
"X-Amzn-Trace-Id": "Root=1-63e23a3e-4004ea8e65dba95003ec150e"
},
"json": null,
"method": "GET",
"url": "https://httpbin.org/anything?include[]=tickers"
}
That said you can move everything to the URL:
* url `https://httpbin.org/anything?include[]=tickers`
* method get
And if you still need to parameterize things, you can, see: https://stackoverflow.com/a/75061809/143475
I'm sending requests to the Google safe browsing API. I believe I'm following their documentation correctly. I've tried regenerating my key.
I'm sending the request below
POST https://safebrowsing.googleapis.com/v4/threatMatches:find?key=AIxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx HTTP/1.1
User-Agent: Fiddler
Host: safebrowsing.googleapis.com
Content-Length: 511
{
"client": {
"clientId": "yourcompanyname",
"clientVersion": "1.5.2"
},
"threatInfo": {
"threatTypes": ["MALWARE", "SOCIAL_ENGINEERING"],
"platformTypes": ["WINDOWS"],
"threatEntryTypes": ["URL"],
"threatEntries": [
{"url": "http://www.urltocheck1.org/"},
{"url": "http://malware.testing.google.test"},
{"url": "http://www.urltocheck2.org/"},
{"url": "http://www.urltocheck3.com/"}
]
}
}
And getting back an empty response which is not what I'm expecting with the URLs supplied and following their example.
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Date: Wed, 08 Sep 2021 15:05:59 GMT
Server: scaffolding on HTTPServer2
Cache-Control: private
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Accept-Ranges: none
Vary: Accept-Encoding
Content-Length: 3
{}
https://transparencyreport.google.com/safe-browsing/search?url=malware.testing.google.test
https://developers.google.com/safe-browsing/v4/lookup-api
You need to pass API key
You need to pass MALWARE url": "http://www.urltocheck1.org/"
if it is not malware it will show empty. try the following url
https://testsafebrowsing.appspot.com/s/malware.html with your code. please search and test with other maleware site
I have written an api test using karate framework. While doing a post call it's converting the value of email field from TEST#ABC.COM to TEST%40ABC.COM.
Here are few lines from log
1 > Content-Type: application/x-www-form-urlencoded; charset=UTF-8
1 > User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_221)
email=TEST%40ABC.COM&checkDigit=&brandName=
This is correct as per the HTTP spec: https://stackoverflow.com/a/53638335/143475
You can see for yourself, try this:
* url 'http://httpbin.org'
* path 'anything'
* form field username = 'john#smith.com'
* form field password = 'secret'
* method post
Result:
1 > Accept-Encoding: gzip,deflate
1 > Connection: Keep-Alive
1 > Content-Length: 41
1 > Content-Type: application/x-www-form-urlencoded; charset=UTF-8
1 > Host: httpbin.org
1 > User-Agent: Apache-HttpClient/4.5.12 (Java/1.8.0_231)
username=john%40smith.com&password=secret
But when you see the response, you can see the server handled it correctly, look at the form in the JSON:
1 < 200
1 < Access-Control-Allow-Credentials: true
1 < Access-Control-Allow-Origin: *
1 < Connection: keep-alive
1 < Content-Length: 555
1 < Content-Type: application/json
1 < Date: Tue, 07 Apr 2020 13:11:58 GMT
1 < Server: gunicorn/19.9.0
{
"args": {},
"data": "",
"files": {},
"form": {
"password": "secret",
"username": "john#smith.com"
},
"headers": {
"Accept-Encoding": "gzip,deflate",
"Content-Length": "41",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Host": "httpbin.org",
"User-Agent": "Apache-HttpClient/4.5.12 (Java/1.8.0_231)",
"X-Amzn-Trace-Id": "Root=1-5e8c7c1e-affe121cae9f4b20399b0884"
},
"json": null,
"method": "POST",
"origin": "49.206.10.30",
"url": "http://httpbin.org/anything"
}
I'm trying to create the path for the Odata URL in Karate.
The path looks like: '/opu/odata/srt/ZQ_SRV/ZQ_BI_Q001(OPT_1='0013076036',OPT_To='0013076036')/Results'
It seems like Karate can't read special characters like round brackets () and ' '. And it cuts the url after opu/odata/srt/ZQ_SRV/ZQ_BI_Q001 right before the round brackets starts. And the rest of the url (OPT_1='0013076036',OPT_To='0013076036')/Results looks like a text.
I've tried to use %28 for ( and 29% for ) and %27 for ' but it didn't help.
P.S.When running the same url in Postman the call went successfully
Running the test url:
Background:
* url "https://httpbin.org/anything/opu/odata/srt/ZQ_SRV/ZQ_BI_Q001(OPT_1='0013076036',OPT_To='0013076036')/Results"
Scenario: test check
* method get
Try building the url fully by hand and don't use param or path:
* url "http://myhost/opu/odata/srt/ZQ_SRV/ZQ_BI_Q001(OPT_1='0013076036',OPT_To='0013076036')/Results"
If that still doesn't work, it is likely your server does not handle encoded URL-s correctly which could be a bug: https://stackoverflow.com/a/54477346/143475
EDIT: just try these 2 lines to prove there is nothing wrong with Karate / or see this simpler example: https://stackoverflow.com/a/67068873/143475
* url "https://httpbin.org/anything/opu/odata/srt/ZQ_SRV/ZQ_BI_Q001(OPT_1='0013076036',OPT_To='0013076036')/Results"
* method get
This is the result:
Running com.intuit.karate.junit4.dev.TestRunner
23:11:06.404 [main] DEBUG com.intuit.karate - request:
1 > GET https://httpbin.org/anything/opu/odata/srt/ZQ_SRV/ZQ_BI_Q001(OPT_1='0013076036',OPT_To='0013076036')/Results
1 > Accept-Encoding: gzip,deflate
1 > Connection: Keep-Alive
1 > Host: httpbin.org
1 > User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_231)
23:11:08.154 [main] DEBUG com.intuit.karate - response time in milliseconds: 1745.46
1 < 200
1 < Access-Control-Allow-Credentials: true
1 < Access-Control-Allow-Origin: *
1 < Connection: keep-alive
1 < Content-Type: application/json
1 < Date: Wed, 22 Jan 2020 17:41:07 GMT
1 < Referrer-Policy: no-referrer-when-downgrade
1 < Server: nginx
1 < X-Content-Type-Options: nosniff
1 < X-Frame-Options: DENY
1 < X-XSS-Protection: 1; mode=block
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept-Encoding": "gzip,deflate",
"Host": "httpbin.org",
"User-Agent": "Apache-HttpClient/4.5.5 (Java/1.8.0_231)"
},
"json": null,
"method": "GET",
"origin": "49.206.14.183, 49.206.14.183",
"url": "https://httpbin.org/anything/opu/odata/srt/ZQ_SRV/ZQ_BI_Q001(OPT_1='0013076036',OPT_To='0013076036')/Results"
}
Resolved issue by putting * method get instead of When method GET
Then status 200
I got the Google API for Objective C for using Cloud Storage Module from below path.
Google API Objective-C Client
Unluckily the api didn't provide any Sample Code for Cloud Storage so I tried to do it myself but I couldn't be successful. Below is what I am doing
I enabled my billing for Cloud Storage from Google API Console
I made a bucket with name "ahs_test"
I made a Client ID for installed applications
I got successful with Outh2.0 with the library available at upper SVN Path. After doing this I wrote below code and get below error message
Note that After reading Google Cloud Storage I am sort of sure that I have to send the "x-goog-project-id" in my request header but I am wondering that this API's code doesn't do anything like that. ( I might be doing some mistake so leaving this for getting any sort of help.. Thanks in Advance...)
// Code....
GTLServiceStorage *service = self.storageService
GTLQueryStorage *query = [GTLQueryStorage queryForBucketsGetWithBucket:#"ahs_test"];
_fileListTicket = [service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
GTLStorageBuckets *bucketList,
NSError *error) {
}];
// Error Message I get (Detailed from loger)
storage.buckets.get
2012-12-30 07:11:30 +0000
Request: POST https://www.googleapis.com/rpc?prettyPrint=false
Request headers:
Accept: application/json-rpc
Authorization: Bearer _snip_
Cache-Control: no-cache
Content-Type: application/json-rpc; charset=utf-8
User-Agent: com.example.DriveSample/1.0 google-api-objc-client/2.0 MacOSX/10.8 (gzip)
Request body: (128 bytes)
{
"jsonrpc" : "2.0",
"method" : "storage.buckets.get",
"id" : "gtl_3",
"params" : {
"bucket" : "ahs_test",
"max-results" : 150
},
"apiVersion" : "v1beta1"
}
Response: status 200
Response headers:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Length: 132
Content-Type: application/json; charset=UTF-8
Date: Sun, 30 Dec 2012 07:10:44 GMT
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Pragma: no-cache
Server: GSE
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Response body: (168 bytes)
{
"error" : {
"message" : "Access Not Configured",
"data" : [
{
"reason" : "accessNotConfigured",
"message" : "Access Not Configured",
"domain" : "usageLimits"
}
],
"code" : 403
},
"id" : "gtl_3"
}
The Google API library uses the Cloud Storage JSON API, which isn't enabled by default. Please check to see if it is enabled in the Google APIs console.