-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[v8.52.0] Invalid JSON was returned from the route. #38178
Comments
Laravel currently can't make assertions on
|
if (is_null($decodedResponse) || $decodedResponse === false) { |
The $decodedResponse === false
expression is checking for Illuminate\Testing\AssertableJsonString
's constructor assigning false
to property AssertableJsonString@decoded
:
framework/src/Illuminate/Testing/AssertableJsonString.php
Lines 39 to 47 in 49ee16b
if ($jsonable instanceof JsonSerializable) { | |
$this->decoded = $jsonable->jsonSerialize(); | |
} elseif ($jsonable instanceof Jsonable) { | |
$this->decoded = json_decode($jsonable->toJson(), true); | |
} elseif (is_array($jsonable)) { | |
$this->decoded = $jsonable; | |
} else { | |
$this->decoded = json_decode($jsonable, true); | |
} |
But in this API response, HTTP response body string false
is JSON false
that should be transformed to PHP bool value false
.
v8.52.0 changes causing the exception
The exception is now occurring because v8.52.0 started showing JSON response validation errors in test output on a status code mismatch. Introduced by #38088, a custom PHPUnit feedback message string is computed when asserting the status code integer match like 200 HTTP OK.
So this new code:
framework/src/Illuminate/Testing/TestResponse.php
Lines 194 to 200 in 7bd4e6d
if ($this->baseResponse->headers->get('Content-Type') === 'application/json') { | |
$json = $this->json(); | |
if (isset($json['errors'])) { | |
return $this->statusMessageWithErrors($expected, $actual, $json); | |
} | |
} |
Is now attempting to decode the response body JSON string on status code assertions before any assert*Json()
methods are called.
Possible framework code fix
A potential fix would be to add a new AssertableJsonString
method:
class AssertableJsonString implements ArrayAccess, Countable
{
// ...
public function hasInvalidJson()
{
return $this->decoded === null || (
$this->decoded === false && $this->json !== 'false' && ! (
$this->$json instanceof Jsonable && $jsonable->toJson() === false
)
);
}
}
Then make TestResponse@decodeResponseJson()
only throw an exception when that returns true.
I'm not sure why false
is being checked since json_decode() returns null
upon parse failure. But the decodeResponseJson()
method infers that the AssertableJsonString
constructor accepting $jsonable
value JsonSerializable@jsonSerialize() === false
is an error condition.
Edit: Looking at when decodeResponseJson()
was added, its false
checks seem to be rooted in making assertions on associative array payloads. 5f4a991 You can't make key/value assertions on a false
payload. The method was later used by other JSON assertion methods where the false
error check doesn't make sense.
https://github.com/laravel/framework/compare/8.x...derekmd:assert-status-doesnt-fail-on-json-false?expand=1 will at least fix Before submitting I'll wait on today's #38189 to be merged to avoid Git conflicts. |
Description:
This code work on v8.51.0, but fail on v8.52.0
Steps To Reproduce:
On any controller:
On testing:
The text was updated successfully, but these errors were encountered: