map(fn ($role) => Role::create(['name' => $role])); $this->user = User::factory() ->active() ->has(Employee::factory()) // ->has(Outlet::factory()->count(5)) ->create(); $this->user->roles()->attach($roles->pluck('id')); }); function createOutlet(array $attributes = []) { return Outlet::factory() ->has(OpeningHour::factory()->count(7)) ->has(Facility::factory()->count(5)) ->state(fn () => array_merge([ 'status' => fake()->randomElement(OutletStatus::cases()), ], $attributes)) ->create(); } function mountIndexComponent(User $user) { return Livewire::actingAs($user)->test(Index::class); } it('renders page successfully', function () { mountIndexComponent($this->user) ->assertViewIs('livewire.studio.master.outlet.index') ->assertViewHas('pageTitle', 'Outlet'); }); it('mounts outlets correctly', function () { $outlet = createOutlet(); mountIndexComponent($this->user) ->assertViewHas('outlets', function ($outlets) use ($outlet) { return collect($outlets)->contains( fn ($o) => $o['name'] === $outlet->name && $o['phone_number'] === $outlet->phone_number ); }); }); it('opens image modal when openImage is called', function () { $component = mountIndexComponent($this->user); $url = 'https://example.com/test.jpg'; $component->call('openImage', $url)->assertSet('imageUrl', $url); }); it('displays all outlets', function () { for ($i = 0; $i < 5; $i++) { createOutlet(); } $outletCount = Outlet::count(); $firstOutlet = Outlet::first(); mountIndexComponent($this->user) ->assertSee($firstOutlet->name) ->assertViewHas('outlets', fn ($outlets) => count($outlets) === $outletCount); }); it('deletes an outlet successfully', function () { $outlet = createOutlet(); mountIndexComponent($this->user) ->call('delete', $outlet) ->assertHasNoErrors(); $this->assertSoftDeleted('outlets', ['id' => $outlet->id]); }); it('filters outlets by search query', function () { $outlet1 = createOutlet(['name' => 'Outlet Jakarta']); $outlet2 = createOutlet(['name' => 'Outlet Bandung']); $outlet3 = createOutlet(['name' => 'Toko Surabaya']); $component = mountIndexComponent($this->user); expect(count($component->get('outlets')))->toBe(3); $component->set('search', 'Jakarta') ->assertSet('search', 'Jakarta'); expect(count($component->get('outlets')))->toBe(1); expect($component->get('outlets.0.name'))->toBe('Outlet Jakarta'); $component->set('search', 'Outlet') ->assertSet('search', 'Outlet'); expect(count($component->get('outlets')))->toBe(2); }); it('filters outlets by status', function () { $outlet1 = createOutlet(['status' => OutletStatus::OPERATIONAL]); $outlet2 = createOutlet(['status' => OutletStatus::UNDER_CONSTRUCTION]); $outlet3 = createOutlet(['status' => OutletStatus::TERMINATED]); $component = mountIndexComponent($this->user); expect(count($component->get('outlets')))->toBe(3); $component->set('status', [OutletStatus::OPERATIONAL->value]) ->assertSet('status', [OutletStatus::OPERATIONAL->value]); expect(count($component->get('outlets')))->toBe(1); expect($component->get('outlets.0.name'))->toBe($outlet1->name); $component->set('status', [ OutletStatus::OPERATIONAL->value, OutletStatus::UNDER_CONSTRUCTION->value, ]); expect(count($component->get('outlets')))->toBe(2); }); it('filters outlets by both search and status', function () { $outlet1 = createOutlet(['name' => 'Outlet A', 'status' => OutletStatus::OPERATIONAL]); $outlet2 = createOutlet(['name' => 'Outlet B', 'status' => OutletStatus::OPERATIONAL]); $outlet3 = createOutlet(['name' => 'Outlet C', 'status' => OutletStatus::UNDER_CONSTRUCTION]); $component = mountIndexComponent($this->user) ->set('search', 'Outlet') ->set('status', [OutletStatus::OPERATIONAL->value]); expect(count($component->get('outlets')))->toBe(2); }); it('loads outlet data with all required fields', function () { $outlet = createOutlet(); $component = mountIndexComponent($this->user); $outletData = $component->get('outlets.0'); expect($outletData)->toHaveKeys([ 'hash', 'name', 'phone_number', 'landmark', 'address', 'status', 'opening_hours', 'facilities', 'opened_date', 'opened_ago', 'closed_date', 'closed_ago', 'image', 'images', ]); expect($outletData['status'])->toHaveKeys(['label', 'color']); expect($outletData['name'])->toBe($outlet->name); expect($outletData['phone_number'])->toBe($outlet->phone_number); }); it('loads outlets ordered by latest', function () { $outlet1 = createOutlet(['name' => 'First']); sleep(1); $outlet2 = createOutlet(['name' => 'Second']); $component = mountIndexComponent($this->user); expect($component->get('outlets.0.name'))->toBe('Second'); expect($component->get('outlets.1.name'))->toBe('First'); });