Behat-Laravel-Extension
Behat-Laravel-Extension copied to clipboard
UploadedFile is invalid
Hi,
I am not sure if this is a right place to ask about it but when trying to test file upload I am getting an validation failure when Illuminate\Validation\Validator::validateAttribute
is called.
I have an FormRequest with rules as follow:
return [
'name' => [
'required',
'max:100',
],
'images.*' => [
mimes:jpeg,png,jpg,gif,svg.
max:2048'
],
'description' => 'max:256',
];
I traced the problem to the Symfony\Component\HttpFoundation\File\UploadedFile::isValid
function which return false. It class have an option to set an UploadedFile to test mode but it seems that the test flag is not preserve from my FeatureContext.
I am using UploadedFile::fake()->image('test.png')
to generate a test image with a test flag but the flag is not preserve when the request is made.
can you try not using the facade to do the test setting. I think this example might help https://github.com/alnutile/recipes/blob/master/features/bootstrap/ProfileImageDomainContext.php
@alnutile @laracasts @JeffreyWay I'm having the same problem, I'm dumping what isValid is parsing it gets parsed 2 times during the request for some reason.
1st time: test flag is set to true, error = 0 (fine, it should pass) 2nd time: test flag is set to false (?), error = 0. Ends with the error message 'The file "iLean.pdf" was not uploaded due to an unknown error.'
$pathToFile = base_path('features/fixtures/iLean.pdf');
$files = [
'file' => new \Illuminate\Http\UploadedFile($pathToFile, 'iLean.pdf', filesize($pathToFile), 'application/pdf', null, true)
];
$this->sendRequest('post', $uri, [], $files);
│ string(4) "test"
│ bool(true)
│ string(5) "error"
│ int(0)
│ string(4) "test"
│ bool(false)
│ string(5) "error"
│ int(0)
│ string(4) "file"
│ string(62) "The file "iLean.pdf" was not uploaded due to an unknown error."
│ object(stdClass)#5447 (1) {
│ ["file"]=>
│ array(1) {
│ [0]=>
│ string(19) "validation.uploaded"
│ }
│ }
I never actually managed to fix this problem. What I found out is that the test flag is not preserved when the request is created and send. When the request is being created it is recreating a file object but its not preserving the test flag.
Allright, so I've found the bottleneck.
There's a Illuminate\Http\Concerns\InteractsWithInput
trait, this is used to build the input data that gets validated in form requests.
This happens in convertUploadedFiles(array $files)
.
It loops over the files and creates a new UploadedFile
, ignoring the $testing private property.
I've overwritten it in the form request that was giving me trouble:
protected function convertUploadedFiles(array $files)
{
return array_map(function ($file) {
if (is_null($file) || (is_array($file) && empty(array_filter($file)))) {
return $file;
}
return is_array($file)
? $this->convertUploadedFiles($file)
: UploadedFile::createFromBase($file, in_array(env('APP_ENV'), ['behat', 'testing']));
}, $files);
}
It's strange though, since normally (if I go through the code) it should just copy the provided UploadFile object instead of creating a new one.
@happyDemon is this a patch you want to sumbit for me to roll in?