I'm working on a legacy code and trying to use tests to cover the code for later refactoring. In one controller there's a piece of code like this:
return redirect()->route('login')->withErrors(['invalid credentials']);
Here are my assertions for the test:
$response->assertRedirect(route('login'));
$response->assertSessionHasErrors([
0 => 'invalid credentials'
]);
But the problem is I get the following output:
Session missing error: 'invalid credentials'
Failed asserting that false is true.
Any idea how can I get this done?
Looking at the source code of assertSessionHasErrors() I think it cannot be done with your use case. The problem is the unnamed array in your withErrors(...) method. I see two options for you:
Change your legacy application into:
return redirect()->route('login')->withErrors(['error' => 'invalid credentials']);
Afterwards you can run your test like so:
$response->assertRedirect(route('login'));
$response->assertSessionHasErrors([
'error' => 'invalid credentials'
]);
If you cannot change your legacy application you could use this:
$response->assertRedirect(route('login'));
$this->assertEquals(session('errors')->getBag('default')->first(),'invalid credentials');
I am using Firebase JWT in one of my SLIM framework apps for RESTFul api. But all the JWT errors occur as slim app error rather than throwing back json errors ,which i can return to user.
Like in image below
Can you help how can i display JWT errros in json format ,so that my restful api return that json error to user.
If you need to output error as JSON, you need to handle the exception. For example:
try {
//do something when everything is OK
} catch (\Firebase\JWT\SignatureInvalidException $e) {
return $response->withJson(
(object) [
'error' => true,
'code' => $e->getCode(),
'message' => $e->getMessage()
],
500
);
}
I use laravel 5.4. When in my tests I do something like:
$this->get("/api/test")->assertStatus(422)->assertJson([
"status" => "ok"
]);
I get an HttpException when status code is 422, even though I'm totally ready for this -- and I'm even expecting it. My problem is that exception prevents my asserts, so that assertJson just doesn't work.
$this->expectException(HttpException::class) doesn't help since it catches this exception and stops, so this begins to pass:
$this->expectException(HttpException::class)
$this->get("/api/test")->assertStatus(422)->assertJson([
"status" => "ok"
]);
$this->assertTrue(false);
I see I can catch this exception myself, but then I won't be able to apply my asserts to the response in an easy way. How can I work around that trouble?
The validation errors only get converted to json response on a json or ajax request. Try this.
$this->getJson("/api/test")->assertStatus(422)->assertJson([
"status" => "ok"
]);
I have below code in error.php, which is triggered using App::abort(404, $error) in my controller. Still my response status code is 200(ok). I tried with various error codes like 400, 403
// NotFoundException handler
App::error(function(NotFoundException $e)
{
$default_message = 'The requested resource was not found';
return Response::json(array(
'error' => $e->getMessage() ?: $default_message,
), 404);
});
For anyone still googling this problem:
I was struggling with this problem for hours. For me the problem was caused by an issue with one of my controllers.
Check all of your controllers and make sure there are no spaces in front of the <?php tag. The <?php tag should be the very first thing in the file. A single space in front of the <?php tag in any of your controllers that are routed as such:
Route::controller('example', 'ExampleController');
Will cause all status codes to be 200.
I believe, regardless, you should receive a 404 response, so there might be something else happening that's the result of code not included in your question.
That being said, the Exception class that is thrown for 404 is NotFoundHttpException rather than NotFoundException.
Since Laravel 4 uses Symfony's HttpKernal, that Exception is here.
You can see here where App::abort() throws NotFoundHttpException when a 404 is triggered.
Therefore, your code should look like:
// NotFoundHttpException handler
App::error(function(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e)
{
$default_message = 'The requested resource was not found';
return Response::json(array(
'error' => $e->getMessage() ?: $default_message,
), 404);
});
Important: This will only fire for a 404 status, as that's the corresponding code to NotFoundHttpException. Other status codes return other Exception classes. To capture all HTTP status error codes exceptions, type hint for HttpException like so:
// HttpException handler
App::error(function(\Symfony\Component\HttpKernel\Exception\HttpException $e)
{
return Response::json(array(
'error' => $e->getMessage(),
), $e-> getStatusCode());
});
Lastly, consider using a bit of Content Negotiation when deciding to return JSON or HTML.
The solution didn't worked for me, so in case anyone is still looking for an answer, I thought it be best to put it here instead of creating another question.
After some time I had this problem too, in my app/Exceptions/Handler.php I had:
if ($e instanceof ModelNotFoundException) {
if ($request->ajax()) {
return response()
->json(['error' => ['No results']])
->header('status', 422);
}
}
This worked in my local environment, however, in the homolog environment (which reproduces the production environment, just to be clear) it didn't returned the correct status code.
After another look I started looking at Laravel's docs, and I changed the call to the following:
return response()
->json(['error' => ['No results.']], 422);
And that did the trick. Hope this can help.
In my case I found some space in front of <?php
Remove dump & other print functions
I was actively debugging when I noticed this issue. It was caused because I had dump(...) calls in the code at that time.
When I removed all my debug dump calls, the status code was correctly 404 again (using abort(404).
try
{
$client = new \SoapClient($wsdlUrl, array(
'cache_wsdl' => 0, 'exceptions' => true, 'trace' => true));
$client->getPage($parameter);
}
catch(\Exception $e)
{
die("exception");
}
Okay this is what executes the SOAP request. $wsdlUrl holds the WSDLs URL and $parameter keeps an XML document.
And everything works like a charm!
Now I just add few more nodes to the XML document in $parameter and I get a fatal error.
This is not so weird necessarily, but what is weired is the combination of following three observations:
1) exceptions is set to true .... but no Exception is thrown / this was b/c I forgot to place a backslash before Exception in the catch statement.
2) instead an error is logged:
PHP Fatal error: SoapClient::SoapClient():
'uri' option is required in nonWSDL mode in /var/w[...]
3) but the WSDL url is provided and of course valid, as all works again just fine after skipping the adding of the new nodes. they don't affect the wsdl parameter.
Okay, I tracked down the source of the problem. There is no satisfying answer really to that question but few things to learn! :)
The important thing is that the request has been sent and processed by the SOAP server.
But the server responds with an error.
So, obviously, even though a fatal error regarding no wsdl and no connection parameter is triggered doesn't mean no request has been sent - which is very counter logical in my opinion b/c if no wsdl is provided and no connection params as well, then how could the request be executed?
EDIT
There is another bug in the code. I forgot to place a backslash before Exception! Without it's not referring to the Exception class.
Then an exception is thrown and caught.