Codeception Laravel sendAjaxGetRequest return empty string - laravel-4

Do you know why this return an empty string
public function tryToTest3(AcceptanceTester $I)
{
$I->wantTo('To see a 200 status code and a json response');
$I->haveHttpHeader('Content-Type', 'application/json');
$I->sendAjaxGetRequest('/users',array());
$I->seeResponseCodeIs('200');
$I->seeResponseIsJson();// until here green bar
dd($I->grabResponse()); // empty string
}
Acceptance Tests (5) ----------------------------------------------------------------------------------------------------------------------------
Modules: PhpBrowser, AcceptanceHelper, Db, REST
-------------------------------------------------------------------------------------------------------------------------------------------------
Trying to try to test (LoginCest::tryToTest)
Scenario:
PASSED
Trying to try to test2 (LoginCest::tryToTest2)
Scenario:
PASSED
Trying to To see a 200 status code and a json response (LoginCest::tryToTest3)
Scenario:
* I have http header "Content-Type","application/json"
* I send ajax get request "/users",
[Response] 200
[Page] http://localhost/laravel/phpunit/public/users
[Cookies] []
[Headers] {"Date":["Thu, 31 Jul 2014 08:49:58 GMT"],"Server":["Apache/2.2.22 (Ubuntu)"],"X-Powered-By":["PHP/5.4.6-1ubuntu1.4"],"Vary":["Accept-Encoding"],"Content-Length":["120"],"Content-Type":["text/html"]}
* I see response code is "200"
* I see response is json
* I grab response
string(0) ""
NB
in my app/bootstrap/start.php I've got
if ((gethostname() === 'homestead') && (isset($_SERVER['REMOTE_ADDR'])) && ($_SERVER['REMOTE_ADDR'] === '127.0.0.1'))
{
dd('homestead');
$env = $app->detectEnvironment(['codeception' => ['homestead']]);
}
else
{
$env = $app->detectEnvironment(['local' => ['homestead']]);
}
homestead is never printed
while this print the actual response and print homestead
public function tryToTest3(AcceptanceTester $I)
{
$I->wantTo('To see a 200 status code and a json response');
$I->haveHttpHeader('Content-Type', 'application/json');
$I->sendGET('/users',array());
$I->seeResponseCodeIs('200');
$I->seeResponseIsJson();
dd($I->grabResponse()); // the good response
}
Scenario:
PASSED
Trying to To see a 200 status code and a json response (LoginCest::tryToTest3)
Scenario:
* I have http header "Content-Type","application/json"
* I send get "/users",
[Request] GET http://localhost/laravel/phpunit/public//users
[Response] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
[Headers] {"Date":["Thu, 31 Jul 2014 09:12:43 GMT"],"Server":["Apache/2.2.22 (Ubuntu)"],"X-Powered-By":["PHP/5.4.6-1ubuntu1.4"],"Cache-Control":["no-cache"],"Set-Cookie":["laravel_session=eyJpdiI6IjdxSVE3RzFEYUw4Q0VmbWNWTzlVVkE9PSIsInZhbHVlIjoiSXY5c2xZbVlmdTdSU1hjNTJuVU1cLzlkZXRwQmRGOEc2R3dscTBtY3JHRVwvR3V5TWM2K1BkVkpmdERDY3h0NkloU09CaUFNN0cwSk56TDBZbmhIOVVLZz09IiwibWFjIjoiNzE2YTlhZGEyMTIyZTdlODQ0ZjA0ZGEzZjE5NDg0MTBlMWNkY2IzMzRkN2NhNjEzOTg5ZTQ5NmRkNDU2OTE4MyJ9; expires=Thu, 31-Jul-2014 11:12:43 GMT; path=/; httponly"],"Transfer-Encoding":["chunked"],"Content-Type":["application/json"]}
[Status] 200
* I see response code is "200"
* I see response is json
* I grab response
string(52) "[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]"

try this instead of $I->grabResponse()
$response = $I->grabDataFromJsonResponse();

I have the same problem, but i think that in my case i have mistunderstood the testing tools.
In my case i was trying to test a JSON response provided by a controller that accepted AJAX POST requests.
I was trying to test that a successfull-style flash message is displayed to the user in a div, but as i wasn't able to test Javascript, i was looking for the JSON in the response. And then i reached your case when null is given as a JSON.
I tried with all the possible headers and combinations and then i reached this response in PHPtest.club and i think that it maybe can help you as it helped me.
It's about the difference between sendPOST and sendAjaxPostRequest, and then i realised that i was using in a wrong way the sendAjaxPostRequest.
http://phptest.club/t/what-is-the-difference-between-sendpost-and-sendajaxpostrequest/212
Basically:
sendAjaxXRequest is used to test an HTML response, so you should use, see, seeElement and those methods.
sendX is designed to work with JSON response and not with HTML, so you should use seeResponeIsJSON or all the other methods.
I hope to be helpful to you or someone else.
Greetings!
I'd like to say thanks to davert for such a meaningful response.

Related

Invalid Response - JSON & Laravel 5. 6

In my code below is a json response that i am trying to access its element. When i get the description from the response, i get an error. Below is the structure of the response
How do i get the description from the response ? I am only able to get success by $response->success
Response
{"description":["My Description Is Here"],"success":true}
When i validate the json, it is actually a valid json. What could i be doing wrong ?
Code
$response = {"description":["My Description Is Here"],"success":true}
if ($response->state == true) {
$message = $response->detail;
} else {
//do something here
}
You are trying to work with JSON in PHP. But at first you have to decode it into object:
$response = json_decode('{"description":["My Description Is Here"],"success":true}');

Power Query call to google.webmaster.api , Post, request problem

I call the google.webmasters.api via Power-Query(M) and managed to configure the oath2 and made my first successfull call to get & list.
Now i try to call the /searchAnalytics/query? which is working only with Post.
This always responds in a 400 error. Formating of the Query or the Url is not working correctly.
Here some additional Infomations:
Power Query - Reference
Google Webmaster Api - Reference
PowerBi Community
format Date different:
body = "{ ""startDate"": ""2019-01-01"", ""endDate"": ""2019-02-02"" }",
to
body = "{ ""startDate"": ""2019/01/01"", ""endDate"": ""2019/02/02"" }",
let
body = "{ ""startDate"": ""2019-01-01"", ""endDate"": ""2019-02-02"" }",
AccessTokenList = List.Buffer(api_token),
access_token = AccessTokenList{0},
AuthKey = "Bearer " & access_token,
url = "https://www.googleapis.com/webmasters/v3/sites/https%3A%2F%2Fxxxxxxxxx.xxx/searchAnalytics/query?",
Response = Web.Contents(url, [Headers=[Authorization=AuthKey, ContentType="application/json", Accept="application/json"], Content=Text.ToBinary(body) ]),
JsonResponse = Json.Document(Response)
in
Response
getting a 400 and is shows as 400 call in Gooogle-Api Overview
Any Ideas whats wrong?
Thx
Ensure request headers are valid. Server expects Content-Type header, not ContentType.
The documentation (https://developers.google.com/webmaster-tools/search-console-api-original/v3/searchanalytics/query#try-it) suggest requests should be something like:
POST https://www.googleapis.com/webmasters/v3/sites/[SITEURL]/searchAnalytics/query HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
Content-Type: application/json
{}
So seems like main takeaways are:
HTTP POST method must be used
Web.Contents documentation (https://learn.microsoft.com/en-us/powerquery-m/web-contents) suggests including the Content field in the options record to change request from GET to POST.
URL must be valid
You haven't provided your actual URL, so you'll have to validate it for yourself. I would get rid of the trailing ? in your url (as you aren't including a query string -- and even if you were, you should pass them to the Query field of the options record instead of building the query string yourself).
Headers (Authorization, Accept, Content-Type) should be valid/present.
Build your headers in a separation expression. Then pass that expression to the Headers field of the options record. This gives you the chance to review/inspect your headers (to ensure they are as intended).
Body should contain valid JSON to pass to the API method.
Creating valid JSON via manual string concatenation is liable to error. Using Json.FromValue (https://learn.microsoft.com/en-us/powerquery-m/json-fromvalue) seems a better approach.
All in all, your M code might look something like:
let
// Some other code is needed here, in which you define the expression api_token
AccessTokenList = List.Buffer(api_token),
access_token = AccessTokenList{0},
AuthKey = "Bearer " & access_token,
requestHeaders = [Authorization = AuthKey, #"Content-Type" = "application/json", Accept = "application/json"],
parametersToPost = [startDate = "2019-01-01", endDate = "2019-02-02"], // Can include other parameters here e.g. dimensions, as mentioned in Search Console API documentaton.
jsonToPost = Json.FromValue(parametersToPost, TextEncoding.Utf8), // Second argument not required (as is default), but just be explicit until you've got everything working.
url = "https://www.googleapis.com/webmasters/v3/sites/https%3A%2F%2Fxxxxxxxxx.xxx/searchAnalytics/query", // Uri.EscapeDataString function can be use for URL encoding
response = Web.Contents(url, [Headers=requestHeaders, Content=jsonToPost])
in
response
Untested (as I don't have an account or API credentials).

Spring + Angular: How to parse ResponseEntity in angular?

I'm using Spring Boot to create an API that needs to be consumed in Angular 4. Spring and Angular are on different ports.
The problem is that Spring's ResponseEntity raises an error in Angular.
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity getFlow(#PathVariable int id) {
Flow flow = flowService.findById(id);
return new ResponseEntity(flow, HttpStatus.FOUND);
}
Now, I can perfectly use Postman to test the API and it works.
But when I make a request from Angular, it returns an error:
Strangely, it returns an error alongside the requested object.
Now, the cause of the problem is that the Spring Boot application returns a ResponseEntity and not a normal object (like String), and Angular doesn't know how to interpret it. If the controller returns just a Flow object, it works.
How can it be solved using ResponseEntity? Or, how else can I send the object alongside the HTTP status code?
Also, in #RequestMapping put produces = "application/json", and in get request in angular, add http options :
const httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json',
'Content-Type': 'application/json'
})
};
So your get request looks like this:
this.http.get(url, httpOptions)
As per the document mentioned here
https://docs.angularjs.org/api/ng/service/$http
A response status code between 200 and 299 is considered a success status and will result in the success callback being called. Any response status code outside of that range is considered an error status and will result in the error callback being called. Also, status codes less than -1 are normalized to zero. -1 usually means the request was aborted, e.g. using a config.timeout. Note that if the response is a redirect, XMLHttpRequest will transparently follow it, meaning that the outcome (success or error) will be determined by the final response status code.
As you are sending an instance of ResponseEntity(HttpStatus.Found) whose Http status code is 302 which doesnt fall under the success range thats why error callback is called.
Try returning the content like this
return new ResponseEntity(flow, HttpStatus.OK);

How can I return a response to an AngularJS $http POST to Sinatra?

I am able to successfully POST from AngularJS to my Sinatra route such that I get a "200" Status.
When I inspect in Chrome, I see the request payload as follows:
{"input":"testing"}
But response is empty.
Here is how I am POST-ing:
$http({
method: "POST",
url: "http://floating-beyond-3787.herokuapp.com/angular",
/*url: "https://worker-aws-us-east-1.iron.io/2/projects/542c8609827e3f0005000123/tasks/webhook?code_name=botweb&oauth=LOo5Nc0x0e2GJ838_nbKoheXqM0",*/
data: {input: $scope.newChat}
})
.success(function (data)
{
// $scope.chats.push(data);
$scope.chats.push($scope.newChat)
// if successful then get the value from the cache?
})
.error(function (data)
{
$scope.errors.push(data);
});
};
$scope.newChat = null
Chrome under Request Payload shows it properly -- as above.
When I check the logs in Heroku where I run my Sinatra app, I can't tell if I am properly processing the request payload. And I'm definitely not getting anything in the Response:
post '/angular' do
puts "params: #{params}"
puts params[:input]
puts #json = JSON.parse(request.body.read)
return RestClient.post 'https://worker.io' {:send => params[:input]}
end
My expectation is:
The Sinatra app can receive the payload :input
It can successfully post to my worker on iron.io
It can return something back in the Response to Angular JS along with Success.
Is this possible and if so, how?
Possibly you are running into a case where the request.body has already been read further up the chain before hitting your route.
Try the following
request.body.rewind
request_payload = JSON.parse request.body.read
This is a fairly common issue encountered in Sinatra so if this addresses your issue you may want to put it in a before filter.
before do
request.body.rewind
#request_payload = JSON.parse request.body.read
end
Also the following will not work with a JSON payload.
params[:input]
The params[:field] style works if the Content-Type is application/x-www-form-urlencoded to allow accessing form data in a traditional web application style. It also works to pull params off a parameterized route; something like the following.
post '/angular/:data'
puts params[:data]
# Do whatever processing you need in here
# assume you created a no_errors var to track problems with the
# post
if no_errors
body(json({key: val, key2: val2, keyetc: valetc}))
status 200
else
body(({oh_snap: "An error has occurred!"}).to_json) # json(hash) or hash.to_json should both work here.
status 400 # Replace with your appropriate 4XX error here...
end
end
Something I did recently was to use this last style post 'myroute/:myparam and then Base64 encode a JSON payload on the client side and send it in the URL :myparam slot. This is a bit of a hack and is not something I would recommend as a general practice. I had a client application that could not properly encode the JSON data + headers into the request body; so this was a viable workaround.

MultiJson::LoadError: 795: unexpected token when trying to parse incoming body request

I'm losing my sanity trying to parse an incoming request on a Sinatra app.
This is my spec
payload = File.read("./spec/support/fixtures/payload.json")
post "/api/v1/verify_payload", { :payload => payload }
last_response.body.must_equal payload
where is simply spec/support/fixtures/payload.json
{"ref":"refs/heads/master"}
My route looks like
post '/verify_payload' do
params = MultiJson.load(request.body.read, symbolize_keys: true)
params[:payload]
end
And running the spec I get the following error:
MultiJson::LoadError: 795: unexpected token at 'payload=%7B%22ref%22%3A%22refs%2Fheads%2Fmaster%22%7D'
I have tried to parse the body request in different ways without luck.
How can I make the request valid JSON?
THANKS
If you want to send a JSON-encoded POST body, you have to set the Content-Type header to application/json. With Rack::Test, you should be able to do this:
post "/api/v1/verify_payload", payload, 'CONTENT_TYPE' => 'application/json'
Alternatively:
header 'Content-Type' => 'application/json'
post '/api/v1/verify_payload'
More info here: http://www.sinatrarb.com/testing.html
The problem it is that you are passing a ruby hash, that is not well formated, you should pass a json object.
Something like this, should work:
post "/api/v1/verify_payload", { :payload => payload.to_json }

Resources