Skip to content
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

Form submit integration tests fail after PSR request changes #48828

Closed
pjordaan opened this issue Oct 26, 2023 · 7 comments
Closed

Form submit integration tests fail after PSR request changes #48828

pjordaan opened this issue Oct 26, 2023 · 7 comments
Assignees

Comments

@pjordaan
Copy link

pjordaan commented Oct 26, 2023

Laravel Version

10.29

PHP Version

8.1

Database Driver & Version

No response

Description

A few of my integration tests in my project failed with 10.29, no issues in 10.28. I use PSR request in my controllers for being framework agnostic.

I also have a few integration tests that test a form submit. A form submit POST body does not contain JSON, but url encoded (http_build_query). It seems that after the fix for #48696 an error is thrown on getPayload() as it tries to parse the url encoded POST body as JSON.

It could be this should be fixed in symfony/symfony since this issue is related to getPayload() not checking content types.

Steps To Reproduce

Make an integration tests and use a POST body with http_build_query and not JSON. The content-type header should be application/x-www-form-urlencoded. The controller it is testing is using ServerRequestInterface as typehint.

@timacdonald
Copy link
Member

@pjordaan could you please let us know the error is you are seeing?

Also wondering if this might already have been fixed in: #48823

@pjordaan
Copy link
Author

pjordaan commented Oct 27, 2023

No, it was not the fix in #48823. The problem is that it calls $illuminateRequest->getPayload()->all(), but the POST body is not JSON and getPayload() is not checking if the body is JSON.

I'll come up with my stacktrace in a minute

@pjordaan
Copy link
Author

Ok I removed the conflict 10.29 from composer.json and run composer update and run the tests again to get a stacktrace:

Symfony\Component\HttpFoundation\Exception\JsonException: Could not decode request body.

./project/vendor/symfony/http-foundation/Request.php:1530
./project/vendor/laravel/framework/src/Illuminate/Routing/RoutingServiceProvider.php:142
./project/vendor/laravel/framework/src/Illuminate/Support/helpers.php:432
./project/vendor/laravel/framework/src/Illuminate/Routing/RoutingServiceProvider.php:143
./project/vendor/laravel/framework/src/Illuminate/Container/Container.php:908
./project/vendor/laravel/framework/src/Illuminate/Container/Container.php:795
./project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:955
./project/vendor/laravel/framework/src/Illuminate/Container/Container.php:731
./project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:940
./project/vendor/laravel/framework/src/Illuminate/Routing/ResolvesRouteDependencies.php:85
./project/vendor/laravel/framework/src/Illuminate/Routing/ResolvesRouteDependencies.php:50
./project/vendor/laravel/framework/src/Illuminate/Routing/ResolvesRouteDependencies.php:30
./project/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:60
./project/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:40
./project/vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
./project/vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
./project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:799
./project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:141
./project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:116
./project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:800
./project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:777
./project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:741
./project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:730
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:200
./project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:141
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php:31
./project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php:40
./project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27
./project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php:99
./project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180
./project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:116
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:175
./project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:144
./project/packages/integration-tests/src/Applications/Laravel/LaravelTestApplication.php:124

@pjordaan
Copy link
Author

I got a response from the issue I made in the symfony/symfony repository. Request::getPayload() assumes that the property Request::$request contains the form submit input. For some reason it is not. This implies $app->make('request') did not fill it in. $request and will run the fallback where it decodes

@pjordaan
Copy link
Author

I found out what the issue was. The issue is not found in Laravel. So I close my issue.

@driesvints
Copy link
Member

@pjordaan what was the issue?

@pjordaan
Copy link
Author

pjordaan commented Nov 2, 2023

@driesvints I hope I'm clear because it is linked to many packages (Laravel, symfony http foundation and symfony psr bridge):

in my integration test I was creating a PSR server request object. The PSR server request object has a body and proper content-type header, but the parsed body was not filled in. The symfony bridge fills in $request->request for form submits by reading the request parsed body (which was not filled in). The getPayload method of Request assumes $request->request is not empty if it's a form submit and assumes it's JSON otherwise. Only if you convert a PSR server request object to a symfony/laravel Request object you can get the request object in this state. I fixed it in my test by parsing the body manually.

It would never happen in an actual application!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants