Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

saqueib's avatar

unable to test filesystem temporaryUrl

  • Laravel Version: 5.5.11
  • PHP Version: 7.1
  • Database Driver & Version: MySQL

Description:

I have written some test to verify that a file exists on s3 and download when tried to test Storage::disk('s3')->temporaryUrl($url, $urlExpires); It gives 500 error with this msg but the code works when test by the browser.

This driver does not support creating temporary URLs

Steps To Reproduce:

Test

Storage::fake('s3');

// Create attachment
$attachment = Attachment::create([
    'name' => 'PDF Doc',
    'url' => Storage::disk('s3')->put(
        'attachments', 
        UploadedFile::fake()->create('document.pdf'), 
    1000)
]);

Storage::disk('s3')->assertExists($attachment->url);
...
$this->actingAs($user)
    ->get(route('attachments.download', $attachment->id))
    ->assertRedirect()
// it fails with with 500

Implementaion

$url = Attachment::find($id)->url;

if( Storage::disk('s3')->exists($url) ) {
    // link expiration time
    $urlExpires = Carbon::now()->addMinutes(10);

    try {
        $tempUrl = Storage::disk('s3')->temporaryUrl($url, $urlExpires);
        return redirect($tempUrl);
    } catch ( \Exception $e ) {
        // Unable to test temporaryUrl, its giving driver dont support it issue.
        return response($e->getMessage());
    }
}

One more question? Is there any way to customize the URL generated by temporaryUrl(), problem is downloaded filename is some random string rlbPsVUhqubaXGoEQk96wjPXfQTqurJvNgVjRMZ8.doc which is not very good, I like to customize the name of file to something like project-details.doc etc ?

0 likes
6 replies
youkaihiei's avatar

In FilesystemAdapter.php I added the following to the beginning of the temporaryUrl() method (line 463):

if (env('APP_ENV') === 'testing') {
    return $path;
}

The Storage::fake('s3'); stuff just creates a local disk with the name you give it which is why the temporary url bit throws the error in testing (the local adapter doesn't have a temporaryUrl() method). Probably not a good or long term fix, but it works.

Kamui's avatar

Only FilesystemAdapter.php I can find is a core file of Laravel, in my vendors folder - so editing that is a really, really bad idea, short or long term.

jdavidbakr's avatar

Here is how I just use facade mocking. I don't usually use Storage::fake() as in my experience it is kind of limited (as this post illustrates)

        Storage::shouldReceive('temporaryUrl')
            ->once()
            ->with($document->location, Mockery::any())
            ->andReturn('file-location');
korridor's avatar

I had the same problem and came up with the following solution:

$fakeFilesystem = Storage::fake('somediskname');
$proxyMockedFakeFilesystem = Mockery::mock($fakeFilesystem);
$proxyMockedFakeFilesystem->shouldReceive('temporaryUrl')
    ->andReturn('http://some-signed-url.test');
Storage::set('somediskname', $proxyMockedFakeFilesystem);

Now Storage::disk('somediskname')->temporaryUrl('somefile.png', now()->addMinutes(20)) returns http://some-signed-url.test and I can actually store files in the temporary filesystem that Storage::fake() provides without any further changes.

8 likes

Please or to participate in this conversation.