It looks like the issue you're encountering is related to the paths being different in your test environment compared to your actual application. When using Storage::fake('public'), the paths might not align as expected. Here’s a step-by-step solution to ensure your test works correctly:
-
Ensure the Event is Dispatched: Since you are faking events, you need to ensure that the
ProfileImageUpdatedevent is dispatched correctly. -
Check the Path Consistency: Ensure that the paths used in your listener and test are consistent.
-
Use the Correct Disk: Make sure you are using the same disk in both your listener and your test.
Here’s an updated version of your test:
public function test_old_avatar_will_be_deleted(): void
{
$user = User::factory()->create();
$userData = [
'first_name' => 'John',
'last_name' => 'Doe',
'email' => '[email protected]',
'phone_number' => '0656881180',
'avatar' => UploadedFile::fake()->image('avatar.png', 100, 100)
];
Storage::fake('public');
Event::fake();
// First profile update
$this->actingAs($user)->patch('/profile', $userData);
$user->refresh();
$oldAvatar = $user->avatar;
$this->assertTrue(Storage::disk('public')->exists($oldAvatar));
// Second profile update with a new avatar
$userData['avatar'] = UploadedFile::fake()->image('profile.png', 100, 100);
$this->actingAs($user)->patch('/profile', $userData);
$user->refresh();
// Ensure the old avatar is deleted and the new one exists
$this->assertNotSame($oldAvatar, $user->avatar);
$this->assertFalse(Storage::disk('public')->exists($oldAvatar));
$this->assertTrue(Storage::disk('public')->exists($user->avatar));
// Ensure the event was dispatched
Event::assertDispatched(ProfileImageUpdated::class, function ($event) use ($oldAvatar) {
return $event->oldProfileImage === $oldAvatar;
});
}
Explanation:
- Storage::fake('public'): This ensures that the storage disk is faked for the test environment.
- Event::fake(): This fakes the event dispatching.
-
Event::assertDispatched: This ensures that the
ProfileImageUpdatedevent was dispatched with the correct old avatar path.
Listener Update:
Ensure your listener is correctly handling the storage disk:
namespace App\Listeners;
use App\Events\ProfileImageUpdated;
use Illuminate\Support\Facades\Storage;
class DeleteOldProfileImage
{
/**
* Handle the event.
*/
public function handle(ProfileImageUpdated $event): void
{
$image = $event->oldProfileImage;
if ($image === config('users.default_avatar')) {
return;
}
Storage::disk('public')->delete($image);
}
}
Conclusion:
By ensuring the paths are consistent and the event is correctly dispatched and handled, your test should now correctly assert that the old avatar is deleted when a new one is uploaded.