Search code examples
laravellaravel-livewire

How to get the hashed name of a file that was uploaded with Laravel Livewire in the tests


I am trying to write a test for the following Livewire component that uploads an image:

use Livewire\Component;
use Livewire\WithFileUploads;

class UploadImage extends Component
{
    use WithFileUploads;

    public $image;

    public function save()
    {
        $this->validate([
            'image' => 'image|mimes:jpg,jpeg',
        ]);

        $storedImage = $this->image->store('images'); // returns e.g. "images/PznpCCFUUDjZuZRDEAGpsr7SxV2qIM2dEsZ3l0zO.jpeg"

        // save $storedImage as the name in the images table 
    }
}

The test below fails because the file is saved to the disk and db with the hashed name and not test.jpg. How do I get the hashed name that was created by Livewire for the image in the test?

The $storedImage in the component is not the same as the $image->hashName() in the test

/** @test **/
function it_can_upload_an_image() {
    Storage::fake();

    $image = UploadedFile::fake()->image('test.jpeg');

    Livewire::test(UploadImage::class)
        ->set('image', $image)
        ->call('save');

    $this->assertDatabaseHas('images', [
        'name' => "images/{$image->hashName()}",
    ]);

    Storage::assertExists("images/{$image->hashName()}");
}

Solution

  • I found the answer in the source code's tests here. The solution is so simple 🤦‍♂️

    Add a public property to the component for the $storedImage so that it can be accessed in the tests.

    e.g.

    use Livewire\Component;
    use Livewire\WithFileUploads;
    
    class UploadImage extends Component
    {
        use WithFileUploads;
    
        public $image;
    
        public $storedImage;
    
        public function save()
        {
            $this->validate([
                'image' => 'image|mimes:jpg,jpeg',
            ]);
    
            $this->storedImage = $this->image->store('images');
    
            // save $storedImage as the name in the images table 
        }
    }
    

    Now the hashed name can be accessed from the test like:

    /** @test **/
    function it_can_upload_an_image() {
        Storage::fake();
    
        $image = UploadedFile::fake()->image('test.jpeg');
    
        $storedImage = Livewire::test(UploadImage::class)
            ->set('image', $image)
            ->call('save')
            ->get('storedImage');
    
        $this->assertDatabaseHas('images', [
            'name' => $storedImage,
        ]);
    
        Storage::assertExists($storedImage);
    }