user = User::factory()->create(); }); function makeLivewireFile(string $name) { $file = UploadedFile::fake()->image($name, 100, 100); $tmpId = Str::random(32); $filename = $tmpId.'-'.base64_encode($file->getClientOriginalName()).'.'.$file->getClientOriginalExtension(); $path = "livewire-tmp/{$filename}"; Storage::disk('local')->putFileAs('livewire-tmp', $file, $filename); return [ 'tmpFilename' => $filename, 'name' => $file->getClientOriginalName(), 'extension' => $file->getClientOriginalExtension(), 'path' => storage_path("app/private/{$path}"), 'temporaryUrl' => url("livewire/preview-file/{$filename}"), 'size' => $file->getSize(), ]; } function mountEditComponent(User $user, Outlet $outlet) { return Livewire::actingAs($user)->test(Edit::class, ['outlet' => $outlet]); } it('renders page successfully', function () { $outlet = Outlet::factory()->operational()->create(); mountEditComponent($this->user, $outlet) ->assertViewIs('livewire.studio.master.outlet.form') ->assertViewHas('pageTitle', 'Ubah Outlet'); }); it('mounts days and sets form with outlet', function () { $outlet = Outlet::factory()->operational()->create(); $component = mountEditComponent($this->user, $outlet); $days = Day::cases(); expect($component->days)->toHaveCount(count($days)); expect($component->form->outlet->id)->toBe($outlet->id); }); it('prevents update when user is unauthorized', function () { $outlet = Outlet::factory()->operational()->create(); Gate::define('update outlet', fn () => false); mountEditComponent($this->user, $outlet) ->call('save') ->assertForbidden(); }); it('updates outlet successfully when authorized', function () { $permission = Permission::create(['name' => 'update outlet']); $this->user->givePermissionTo($permission); $outletModel = Outlet::factory()->operational()->create(); // model instance $outletData = Outlet::factory()->operational()->raw(); // data for update $facilities = Facility::factory()->count(5)->raw(); $featuredImage = makeLivewireFile('featured.jpg'); for ($i = 1; $i <= 5; $i++) { $images[] = makeLivewireFile("image{$i}.jpg"); } $openingHours = collect(Day::cases()) ->mapWithKeys(fn ($day) => [ $day->value => [ 'day' => $day->value, 'open_time' => fake()->time('H:i'), 'close_time' => fake()->time('H:i'), ], ]) ->toArray(); $data = array_merge($outletData, [ 'opening_hours' => $openingHours, 'facilities' => collect($facilities)->pluck('name')->toArray(), 'featured_image' => [$featuredImage], 'images' => $images, ]); mountEditComponent($this->user, $outletModel) ->set('form.name', $data['name']) ->set('form.phone_number', $data['phone_number']) ->set('form.address', $data['address']) ->set('form.landmark', $data['landmark']) ->set('form.maps_url', $data['maps_url']) ->set('form.opened_date', $data['opened_date']) ->set('form.status', $data['status']->value) ->set('form.opening_hours', $data['opening_hours']) ->set('form.facilities', $data['facilities']) ->set('form.featured_image', $data['featured_image']) ->set('form.images', $data['images']) ->call('save') ->assertHasNoErrors() ->assertRedirect(Index::class); $outletModel->refresh(); $this->assertDatabaseHas('outlets', [ 'id' => $outletModel->id, 'name' => $data['name'], 'phone_number' => $data['phone_number'], ]); $this->assertCount(1, $outletModel->getMedia('featured_image')); $this->assertCount(5, $outletModel->getMedia('images')); expect($outletModel->getFirstMedia('featured_image')->getPath())->toBeFile(); foreach ($outletModel->getMedia('images') as $media) { expect($media->getPath())->toBeFile(); } });