F
Filament2w ago
Tom

#fileupload #test #pest

I have this FileUpload field:
Forms\Components\FileUpload::make('image')
->image()
->directory('images')
Forms\Components\FileUpload::make('image')
->image()
->directory('images')
and this test:
it('can replace an image', function () {
// Configure
Storage::fake('test');
FileUpload::configureUsing(function (FileUpload $component) {
$component
->preserveFilenames()
->disk('test');
});

// Initial
$filename = fake()->word().'.jpg';
$file = UploadedFile::fake()->image($filename)->storeAs('images', $filename, ['disk' => 'test']);

$recipe = Recipe::factory()->create(['image' => $file]);

expect($recipe->image)->toBe('images/'.$filename);

// Change
$newFilename = fake()->word.'-NEW.jpg';
$newFile = UploadedFile::fake()->image($newFilename);

livewire(EditRecipe::class, ['record' => $recipe->getRouteKey()])
->fillForm([
'title' => $recipe->title,
'description' => $recipe->description,
'image' => [$newFile],
])
->call('save')
->assertHasNoFormErrors();

$recipe->refresh();

// Assert
assertDatabaseHas(Recipe::class, [
'id' => $recipe->id,
'image' => 'images/'.$newFilename,
]);

Storage::disk('test')->assertExists('images/'.$newFilename);
Storage::disk('test')->assertMissing('images/'.$filename);
});
it('can replace an image', function () {
// Configure
Storage::fake('test');
FileUpload::configureUsing(function (FileUpload $component) {
$component
->preserveFilenames()
->disk('test');
});

// Initial
$filename = fake()->word().'.jpg';
$file = UploadedFile::fake()->image($filename)->storeAs('images', $filename, ['disk' => 'test']);

$recipe = Recipe::factory()->create(['image' => $file]);

expect($recipe->image)->toBe('images/'.$filename);

// Change
$newFilename = fake()->word.'-NEW.jpg';
$newFile = UploadedFile::fake()->image($newFilename);

livewire(EditRecipe::class, ['record' => $recipe->getRouteKey()])
->fillForm([
'title' => $recipe->title,
'description' => $recipe->description,
'image' => [$newFile],
])
->call('save')
->assertHasNoFormErrors();

$recipe->refresh();

// Assert
assertDatabaseHas(Recipe::class, [
'id' => $recipe->id,
'image' => 'images/'.$newFilename,
]);

Storage::disk('test')->assertExists('images/'.$newFilename);
Storage::disk('test')->assertMissing('images/'.$filename);
});
However, the test fails as the model retains the old filename. Has anyone solved this before?
Solution:
So with a little assistance from Copilot, I was able to get it working using the ->set() method. ```php livewire(EditRecipe::class, ['record' => $recipe->getRouteKey()]) ->fillForm([ 'title' => $recipe->title,...
Jump to solution
4 Replies
Vp
Vp2w ago
This is how I test for edit with file upload
it('can save', function () {
FileUpload::configureUsing(function (FileUpload $component) {
$component->preserveFilenames();
});

$formFilename = Str::random().'.jpg';
$formImage = UploadedFile::fake()->image($formFilename);

$blog = BlogFactory::new()->create();
$newData = BlogFactory::new()->make([
'image' => $formImage,
]);

livewire(BlogResource\Pages\EditBlog::class, [
'record' => $blog->getRouteKey(),
])
->fillForm([
'title' => $newData->title,
'slug' => $newData->slug,
'image.0' => $formImage,
...
])
->call('save')
->assertHasNoFormErrors()
->assertRedirect(BlogResource::getUrl());

expect($blog->refresh())
->title->toBe($newData->title)
->image->toBe("blogs/{$formFilename}")
...;
});
it('can save', function () {
FileUpload::configureUsing(function (FileUpload $component) {
$component->preserveFilenames();
});

$formFilename = Str::random().'.jpg';
$formImage = UploadedFile::fake()->image($formFilename);

$blog = BlogFactory::new()->create();
$newData = BlogFactory::new()->make([
'image' => $formImage,
]);

livewire(BlogResource\Pages\EditBlog::class, [
'record' => $blog->getRouteKey(),
])
->fillForm([
'title' => $newData->title,
'slug' => $newData->slug,
'image.0' => $formImage,
...
])
->call('save')
->assertHasNoFormErrors()
->assertRedirect(BlogResource::getUrl());

expect($blog->refresh())
->title->toBe($newData->title)
->image->toBe("blogs/{$formFilename}")
...;
});
Tom
TomOP2w ago
I didn't think to use dot notation on the image field. Unfortunately, this only works me if the resources doesn't have an existing image attached to it. Does your test still work if you assign an initial image to the $blog? Mine retains the original image path and won't save the path to the new one. (Although the file itself is being created).
Vp
Vp2w ago
My BlogFactory have fake()->imagepath() ? so i only test like this..
Solution
Tom
Tom2w ago
So with a little assistance from Copilot, I was able to get it working using the ->set() method.
livewire(EditRecipe::class, ['record' => $recipe->getRouteKey()])
->fillForm([
'title' => $recipe->title,
'description' => $recipe->description,
// 'image' => [$newFile],
])
->set('data.image', [$newFile])
->call('save')
->assertHasNoFormErrors();
livewire(EditRecipe::class, ['record' => $recipe->getRouteKey()])
->fillForm([
'title' => $recipe->title,
'description' => $recipe->description,
// 'image' => [$newFile],
])
->set('data.image', [$newFile])
->call('save')
->assertHasNoFormErrors();

Did you find this page helpful?