I'm trying to test my update action method in a controller where a fake image needs to be created and uploaded to test if the update action method is working. So, I create fake image using UploadedFile::make()->image('imageName.jpeg') and it is validated before being saved as usual. But my test is failing throwing the validation errors for the image saying the "imageName" must be an image and of the specific mime type as set in the rules for validation. Can anyone tell me what I'm doing wrong. Any help much appreciated Below is the code:
The route:
Route::patch('/update/{icon}', [ProductIconController::class,'update'])->name('updateIcon')
->missing(function (Request $request){
return Redirect::back()->with('failed', 'Icon not found!');
});
The controller :
public function update(UpdateIconRequest $request, ProductIcon $icon)
{
$attributes = $request->validated();
if($request->hasFile('iconImage') || $request->hasFile('iconHoverImage')){
if($request->hasFile('iconImage')){
$inputType = 'iconImage';
$file = $request->file('iconImage');
if(Storage::exists('images/product_icons/'.$icon->image)){
$deleted = Storage::delete('images/product_icons/'.$icon->image);
}
$icon->image = $this->saveImage($file, $attributes, $inputType);
}
if($request->hasFile('iconHoverImage')){
$inputType = 'iconHoverImage';
$file = $request->file('iconHoverImage');
if(Storage::exists('images/product_icons/'.$icon->image_hover)){
$deleted = Storage::delete('images/product_icons/'.$icon->image_hover);
}
$icon->image_hover = $this->saveImage($file, $attributes, $inputType);
}
}
$icon->name = $attributes['name']; //make it unique
$icon->ordering = $attributes['order'];
$icon->status = $attributes['status'];
$icon->modified = now();
$icon->trash = null;
$saveSuccess = $icon->save();
if($saveSuccess){
return redirect()->route('icons')->with('success', 'Icon has been Updated');
}
else{
return redirect()->route('icons')->with('failed', 'Some error occured ! </br>Icon was not updated.');
}
}
Inside the UpdateIconRequest class:
public function rules()
{
return [
'name' =>['required', 'string', 'min:3', 'max:80',
Rule::unique('product_icons','name')->ignore($this->route('icon')->id)], //route('icon') is parameter of route update/{icon}
'order' => ['required','numeric','min:1','max:120'],
'status' => ['required', 'numeric'],
'iconImage' => ['image','mimes:png,jpeg,svg','max:2048'],
'iconHoverImage' => ['image','mimes:png,jpeg,svg','max:2048'],
];
}
Inside the update.blade.php file :
<form action="{{route('updateIcon', ['icon'=> $icon->id])}}" method="post" enctype="multipart/form-data" id="iconUpdateForm">
@csrf
@method('PATCH')
---other input fields --
<div class="col-span-1">
<input type="radio" name="status" id="no" value="no" {{$icon->status==0?'checked':''}} class="py-1">
<label for="no">Inactive</label>
</div>
@foreach ($errors->get('status') as $message)
<p class="text-red-600">{{$message}}</p>
@endforeach
</div>
<div class="grid grid-cols-12 px-4 py-6 border-b text-xs">
<div class="col-span-2 font-semibold leading-4 text-gray-700/90">
<div>Image</div>
</div>
<div class="col-span-6 space-x-4 border-2 border-gray-700 p-4">
<label for="thumbImg" class="button-15" role="button">Update Icon Image +</label>
@if (empty($icon->image))
<p class="text-xs inline-block text-red-500">Please select Icon Image (Required)<span class="text-red-500"> *</span></p>
@endif
<input type="file" id="thumbImg" name="iconImage" class="px-2 py-1 text-lg bg-blue-100 text-gray-500 hidden" accept=".jpg, .jpeg, .png .svg" required value="{{ old('iconImage') }}"/>
<div class="fileImgContainer p-2 mt-2 border-2 border-gray-300 bg-gray-200 space-y-2 mb-3">
<p class="head1 text-xs text-red-400">Please select images for Icon</p>
<div class="preview flex flex-wrap gap-3">
@if (!empty($icon->image))
<div class="flex flex-col w-[200px] relative p-2 rounded-xl bg-gray-300">
<div class="h-8 w-8 bg-gray-100/70 text-xl text-gray-600 rounded-full flex justify-center items-center align-middle hover:cursor-pointer"><i class="fa-solid fa-check"></i></div>
<img src="{{asset('storage/images/product_icons/'.$icon->image)}}" alt="" class="object-contain h-[160px] w-[180px] mt-1">
</div>
@endif
</div>
</div>
@foreach ($errors->get('iconImage') as $message)
<p class="text-red-600">{{$message}}</p>
@endforeach
</div>
</div>
<div class="grid grid-cols-12 px-4 py-6 border-b text-xs">
<div class="col-span-2 font-semibold leading-4 text-gray-700/90">
<div>Hover Image</div>
</div>
<div class="col-span-6 space-x-4 border-2 border-gray-700 p-4">
<label for="thumbHoverImg" class="button-15" role="button">Update Icon Image +</label>
@if (empty($icon->image_hover))
<p class="text-xs inline-block text-red-500">Please select Icon Image (Required)<span class="text-red-500"> *</span></p>
@endif
<input type="file" id="thumbHoverImg" name="iconHoverImage" class="px-2 py-1 text-lg bg-blue-100 text-gray-500 hidden" accept=".jpg, .jpeg, .png .svg" required value="{{ old('iconHoverImage')}}"/>
<div class="fileImgContainer p-2 mt-2 border-2 border-gray-300 bg-gray-200 space-y-2 mb-3">
<p class="head1 text-xs text-red-400">Please select hover images for Icon</p>
<div class="preview flex flex-wrap gap-3">
@if (!empty($icon->image_hover))
<div class="flex flex-col w-[200px] relative p-2 rounded-xl bg-gray-300">
<div class="h-8 w-8 bg-gray-100/70 text-xl text-gray-600 rounded-full flex justify-center items-center align-middle hover:cursor-pointer"><i class="fa-solid fa-check"></i></div>
<img src="{{asset('storage/images/product_icons/'.$icon->image_hover)}}" alt="" class="object-contain h-[160px] w-[180px] mt-1">
</div>
@endif
</div>
</div>
</div>
@foreach ($errors->get('iconHoverImage') as $message)
<p class="text-red-600">{{$message}}</p>
@endforeach
</div>
</form>
And finally the test class code:
public function test_user_can_update_ProductIcon(){
$updatedImage1 = UploadedFile::fake()->image('abcde.jpeg');
$updatedHoverImage1 = UploadedFile::fake()->image('abcde1.jpeg');
//test the route with the productIcon id
$response = $this->patch(route('updateIcon', [
'icon'=>2,
'name' =>'Updated Test Name',
'status' => 'yes',
'order' => 112,
'iconImage' => $updatedImage1,
'iconHoverImage' => $updatedHoverImage1
]));
$response->assertStatus(302);
$response->assertRedirectToRoute('icons');
$response->assertSessionHas('success');
}
The errors that is being thrown when the above test fails:
FAIL Tests\Feature\ProductIconTest
✓ user can access crud pages for product icon
✓ user can create product icon
⨯ user can update product icon
! user can update product icon image → This test did not perform any assertions D:\Web Design\Website\watergaterestaurant\tests\Feature\ProductIconTest.php:101
---
• Tests\Feature\ProductIconTest > user can update product icon
Failed asserting that two strings are equal.
The following errors occurred during the last request:
The icon image must be an image.
The icon image must be a file of type: png, jpeg, svg.
The icon hover image must be an image.
The icon hover image must be a file of type: png, jpeg, svg.
at D:\Web Design\Website\watergaterestaurant\tests\Feature\ProductIconTest.php:97
93▕ 'iconImage' => $updatedImage1,
94▕ 'iconHoverImage' => $updatedHoverImage1
95▕ ]));
96▕ $response->assertStatus(302);
➜ 97▕ $response->assertRedirectToRoute('icons');