I just upgraded my app from Laravel v8 to v9. Now I'm having an issue with the following code throwing this error:
League\Flysystem\UnableToRetrieveMetadata : Unable to retrieve the file_size for file at location: test_file.xlsx.
My controller:
<?php
namespace App\Http\Controllers\Reports;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
class ReportDownloadController extends Controller
{
/**
* Handle the incoming request.
*
* @param string $path
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function __invoke(string $path): \Symfony\Component\HttpFoundation\StreamedResponse
{
return Storage::disk('temp')->download($path, request()->query('filename'));
}
}
The relevant test:
/** @test */
public function it_returns_a_file_download_with_the_provided_filename_presented_to_the_user()
{
$this->withoutExceptionHandling();
Storage::fake('temp');
$fakeFile = UploadedFile::fake()->create('test_file.xlsx');
Storage::disk('temp')->put('test_file.xlsx', $fakeFile);
$response = $this->actingAs($this->user)
->getJson(route('reports.download', ['path' => 'test_file.xlsx', 'filename' => 'Appropriate.xlsx']));
$response->assertDownload('Appropriate.xlsx');
}
I know Flysystem was updated to v3, but I can't seem to figure out how to resolve this issue.
I even created an empty Laravel 9 app to test with the following code and still get the same error, so I don't think it is my app.
public function test_that_file_size_can_be_retrieved()
{
Storage::fake('local');
$fakeFile = UploadedFile::fake()->create('test_file.xlsx', 10);
Storage::disk('local')->put('test_file.xlsx', $fakeFile);
$this->assertEquals(10, (Storage::disk('local')->size('test_file.xlsx') / 1024));
}
What am is missing?
CodePudding user response:
I've had the same problem when switching from Laravel 8 to Laravel 9.
The error Unable to retrieve the file_size was actually thrown because it couldn't find the file at all at the path provided.
In my case, it turned out that the path that was provided to the download function started with a /
, which wasn't cause for problem with Flysystem 2 but apparently is with Flysystem 3.
Given the tests you're showing it doesn't look like it's the issue here but maybe this will help anyway.
CodePudding user response:
So it turns out my test was broken all along. I should have been using $fakeFile->hashName() and I had the filename where I should have had '/' for the path in my Storage::put().
Here are the corrected tests that pass as expected:
/** @test */
public function it_returns_a_file_download_with_the_provided_filename_presented_to_the_user()
{
$this->withoutExceptionHandling();
Storage::fake('temp');
$fakeFile = UploadedFile::fake()->create('test_file.xlsx');
Storage::disk('temp')->put('/', $fakeFile);
$response = $this->actingAs($this->user)
->getJson(route('reports.download', ['path' => $fakeFile->hashName(), 'filename' => 'Appropriate.xlsx']));
$response->assertDownload('Appropriate.xlsx');
}
and
public function test_that_file_size_can_be_retrieved()
{
Storage::fake('local');
$fakeFile = UploadedFile::fake()->create('test_file.xlsx');
Storage::disk('local')->put('/', $fakeFile);
$this->assertEquals(0, Storage::disk('local')->size($fakeFile->hashName()));
}
Thanks, @yellaw. Your comment about it not being able to find the file at the path provided helped me realize I had done something stupid.