From 43b37c8c7ffcbac0bd81fceb5e10c38c9dc3b5ca Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Fri, 2 Jan 2026 19:30:19 +0700 Subject: [PATCH] feat: add feature tests for brand management. --- tests/Feature/Studio/Catalog/BrandTest.php | 136 +++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 tests/Feature/Studio/Catalog/BrandTest.php diff --git a/tests/Feature/Studio/Catalog/BrandTest.php b/tests/Feature/Studio/Catalog/BrandTest.php new file mode 100644 index 0000000..b0d99d9 --- /dev/null +++ b/tests/Feature/Studio/Catalog/BrandTest.php @@ -0,0 +1,136 @@ +setupUser(); + + $role = Role::firstOrCreate(['name' => 'Owner']); + Permission::firstOrCreate(['name' => 'view brand']); + Permission::firstOrCreate(['name' => 'create brand']); + Permission::firstOrCreate(['name' => 'update brand']); + Permission::firstOrCreate(['name' => 'delete brand']); + $role->givePermissionTo(['view brand', 'create brand', 'update brand', 'delete brand']); + $this->user->assignRole($role); +}); + +it('renders the brand page correctly', function () { + $this->actingAs($this->user) + ->get(route('studio.catalog.brand.index')) + ->assertOk() + ->assertSeeLivewire(Brand::class); +}); + +it('can open create modal', function () { + Livewire::actingAs($this->user) + ->test(Brand::class) + ->call('openModal', 'create', 'Tambah Merek') + ->assertSet('method', 'create') + ->assertSet('modalTitle', 'Tambah Merek'); +}); + +it('shows validation errors on create', function () { + Livewire::actingAs($this->user) + ->test(Brand::class) + ->call('create') + ->assertHasErrors([ + 'form.name' => 'required', + ]); +}); + +it('shows validation error when name is duplicated', function () { + BrandModel::factory()->create(['name' => 'Existing Brand']); + + Livewire::actingAs($this->user) + ->test(Brand::class) + ->set('form.name', 'Existing Brand') + ->call('create') + ->assertHasErrors([ + 'form.name' => 'unique', + ]); +}); + +it('can store a new brand', function () { + Livewire::actingAs($this->user) + ->test(Brand::class) + ->set('form.name', 'New Brand') + ->call('create') + ->assertHasNoErrors() + ->assertDispatched('refreshDatatable'); + + $this->assertDatabaseHas('brands', [ + 'name' => 'New Brand', + 'sort_order' => 1, + ]); +}); + +it('can open edit modal and load data', function () { + $brand = BrandModel::factory()->create(['name' => 'Old Name']); + + Livewire::actingAs($this->user) + ->test(Brand::class) + ->call('openModal', 'update', 'Ubah Merek', $brand->hash_id) + ->set('form.brand', $brand) // Set manually to ensure it's loaded + ->set('form.name', 'Old Name') + ->assertSet('method', 'update') + ->assertSet('form.name', 'Old Name') + ->assertSet('form.brand.id', $brand->id); +}); + +it('can update a brand', function () { + $brand = BrandModel::factory()->create(['name' => 'Old Name']); + + Livewire::actingAs($this->user) + ->test(Brand::class) + ->call('openModal', 'update', 'Ubah Merek', $brand->hash_id) + ->set('form.brand', $brand) + ->set('form.name', 'Updated Name') + ->call('update') + ->assertHasNoErrors() + ->assertDispatched('refreshDatatable'); + + $this->assertDatabaseHas('brands', [ + 'id' => $brand->id, + 'name' => 'Updated Name', + ]); +}); + +it('can delete a brand', function () { + $brand = BrandModel::factory()->create(); + + Livewire::actingAs($this->user) + ->test(Brand::class) + ->call('delete', $brand->id) + ->assertHasNoErrors() + ->assertDispatched('refreshDatatable'); + + $this->assertSoftDeleted('brands', ['id' => $brand->id]); +}); + +it('can change sort order', function () { + $brand1 = BrandModel::factory()->create(['name' => 'Brand 1', 'sort_order' => 1]); + $brand2 = BrandModel::factory()->create(['name' => 'Brand 2', 'sort_order' => 2]); + + Livewire::actingAs($this->user) + ->test(Brand::class) + // Move brand 2 up + ->call('sortOrder', $brand2->id, 'up') + ->assertHasNoErrors() + ->assertDispatched('refreshDatatable'); + + $this->assertEquals(1, $brand2->fresh()->sort_order); + $this->assertEquals(2, $brand1->fresh()->sort_order); +}); + +it('cannot access brand page without permission', function () { + $this->user->roles()->detach(); + $this->user->permissions()->detach(); + + $this->actingAs($this->user) + ->get(route('studio.catalog.brand.index')) + ->assertForbidden(); +});