From 6a0271d9e154fca6895492d4917578f0a5ba6743 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Fri, 2 Jan 2026 19:34:17 +0700 Subject: [PATCH] feat: add perfume CRUD and audit feature tests and remove informational callouts from catalog index views --- .../studio/catalog/bottle/index.blade.php | 8 -- .../studio/catalog/perfume/index.blade.php | 8 -- .../studio/catalog/product/index.blade.php | 8 -- .../Studio/Catalog/Perfume/AuditTest.php | 38 +++++++++ .../Studio/Catalog/Perfume/CreateTest.php | 77 +++++++++++++++++++ .../Studio/Catalog/Perfume/EditTest.php | 67 ++++++++++++++++ .../Studio/Catalog/Perfume/IndexTest.php | 45 +++++++++++ 7 files changed, 227 insertions(+), 24 deletions(-) create mode 100644 tests/Feature/Studio/Catalog/Perfume/AuditTest.php create mode 100644 tests/Feature/Studio/Catalog/Perfume/CreateTest.php create mode 100644 tests/Feature/Studio/Catalog/Perfume/EditTest.php create mode 100644 tests/Feature/Studio/Catalog/Perfume/IndexTest.php diff --git a/resources/views/livewire/studio/catalog/bottle/index.blade.php b/resources/views/livewire/studio/catalog/bottle/index.blade.php index 7e6d1e0..d785446 100644 --- a/resources/views/livewire/studio/catalog/bottle/index.blade.php +++ b/resources/views/livewire/studio/catalog/bottle/index.blade.php @@ -14,14 +14,6 @@ class="text-sm">
- - Informasi - - Untuk melihat harga pembelian, silakan klik pada bagian harga. Untuk melakukan audit stok, - silakan klik pada nama outlet. - - -
diff --git a/resources/views/livewire/studio/catalog/perfume/index.blade.php b/resources/views/livewire/studio/catalog/perfume/index.blade.php index ea045b4..7f2c165 100644 --- a/resources/views/livewire/studio/catalog/perfume/index.blade.php +++ b/resources/views/livewire/studio/catalog/perfume/index.blade.php @@ -21,14 +21,6 @@ class="text-sm">
- - Informasi - - Untuk melihat harga pembelian, silakan klik pada bagian harga. Untuk melakukan audit stok, - silakan klik pada nama outlet. - - -
diff --git a/resources/views/livewire/studio/catalog/product/index.blade.php b/resources/views/livewire/studio/catalog/product/index.blade.php index 5dcfe57..2ddb5a6 100644 --- a/resources/views/livewire/studio/catalog/product/index.blade.php +++ b/resources/views/livewire/studio/catalog/product/index.blade.php @@ -21,14 +21,6 @@ class="text-sm">
- - Informasi - - Untuk melihat harga pembelian, silakan klik pada bagian harga. Untuk melakukan audit stok, - silakan klik pada nama outlet. - - -
diff --git a/tests/Feature/Studio/Catalog/Perfume/AuditTest.php b/tests/Feature/Studio/Catalog/Perfume/AuditTest.php new file mode 100644 index 0000000..223bd7e --- /dev/null +++ b/tests/Feature/Studio/Catalog/Perfume/AuditTest.php @@ -0,0 +1,38 @@ +setupUser(); + + $role = Role::firstOrCreate(['name' => 'Owner']); + Permission::firstOrCreate(['name' => 'view perfume']); + Permission::firstOrCreate(['name' => 'audit perfume']); + $role->givePermissionTo(['view perfume', 'audit perfume']); + $this->user->assignRole($role); +}); + +it('renders the perfume audit page correctly', function () { + $outlet = Outlet::factory()->create(); + $perfume = Perfume::factory()->create(); + + $this->actingAs($this->user) + ->get(route('studio.catalog.perfume.audit', ['outlet' => $outlet, 'perfume' => $perfume])) + ->assertOk() + ->assertSeeLivewire(Audit::class); +}); + +it('cannot access perfume audit without permission', function () { + $outlet = Outlet::factory()->create(); + $perfume = Perfume::factory()->create(); + $this->user->roles()->detach(); + $this->user->permissions()->detach(); + + $this->actingAs($this->user) + ->get(route('studio.catalog.perfume.audit', ['outlet' => $outlet, 'perfume' => $perfume])) + ->assertForbidden(); +}); diff --git a/tests/Feature/Studio/Catalog/Perfume/CreateTest.php b/tests/Feature/Studio/Catalog/Perfume/CreateTest.php new file mode 100644 index 0000000..a09e83a --- /dev/null +++ b/tests/Feature/Studio/Catalog/Perfume/CreateTest.php @@ -0,0 +1,77 @@ +setupUser(); + + $role = Role::firstOrCreate(['name' => 'Owner']); + Permission::firstOrCreate(['name' => 'view perfume']); + Permission::firstOrCreate(['name' => 'create perfume']); + $role->givePermissionTo(['view perfume', 'create perfume']); + $this->user->assignRole($role); +}); + +it('renders the perfume create page correctly', function () { + $this->actingAs($this->user) + ->get(route('studio.catalog.perfume.create')) + ->assertOk() + ->assertSeeLivewire(Create::class); +}); + +it('shows validation errors when fields are empty', function () { + Livewire::actingAs($this->user) + ->test(Create::class) + ->call('save') + ->assertHasErrors([ + 'form.name' => 'required', + 'form.sku' => 'required', + 'form.cost_price' => 'required', // Required for Owner + 'form.sale_price' => 'required', + 'form.category_ids' => 'required', + 'form.outlet_ids' => 'required', + ]); +}); + +it('can store a new perfume', function () { + $brand = Brand::factory()->create(); + $category = Category::factory()->create(); + $outlet = Outlet::factory()->create(); + + Livewire::actingAs($this->user) + ->test(Create::class) + ->set('form.name', 'Perfume A') + ->set('form.sku', 'SKU-Perfume-A') + ->set('form.brand_id', $brand->id) + ->set('form.cost_price', '50000') + ->set('form.sale_price', '100000') + ->set('form.concentration', Concentration::EAU_DE_PERFUME->value) + ->set('form.category_ids', [$category->id]) + ->set('form.outlet_ids', [$outlet->id]) + ->call('save') + ->assertHasNoErrors() + ->assertRedirect(route('studio.catalog.perfume.index', ['notification' => 'Parfum berhasil ditambahkan.'])); + + $this->assertDatabaseHas('perfumes', [ + 'name' => 'Perfume A', + 'sku' => 'SKU-Perfume-A', + 'cost_price' => 50000, + 'sale_price' => 100000, + ]); +}); + +it('cannot access perfume create without permission', function () { + $this->user->roles()->detach(); + $this->user->permissions()->detach(); + + $this->actingAs($this->user) + ->get(route('studio.catalog.perfume.create')) + ->assertForbidden(); +}); diff --git a/tests/Feature/Studio/Catalog/Perfume/EditTest.php b/tests/Feature/Studio/Catalog/Perfume/EditTest.php new file mode 100644 index 0000000..dea53b0 --- /dev/null +++ b/tests/Feature/Studio/Catalog/Perfume/EditTest.php @@ -0,0 +1,67 @@ +setupUser(); + + $role = Role::firstOrCreate(['name' => 'Owner']); + Permission::firstOrCreate(['name' => 'view perfume']); + Permission::firstOrCreate(['name' => 'update perfume']); + $role->givePermissionTo(['view perfume', 'update perfume']); + $this->user->assignRole($role); +}); + +it('renders the perfume edit page correctly', function () { + $perfume = Perfume::factory()->create(); + + $this->actingAs($this->user) + ->get(route('studio.catalog.perfume.edit', ['perfume' => $perfume])) + ->assertOk() + ->assertSeeLivewire(Edit::class); +}); + +it('can load data correctly into edit form', function () { + $perfume = Perfume::factory()->create(['name' => 'Old Name']); + + Livewire::actingAs($this->user) + ->test(Edit::class, ['perfume' => $perfume]) + ->assertSet('form.name', 'Old Name') + ->assertSet('form.perfume.id', $perfume->id); +}); + +it('can update a perfume', function () { + $perfume = Perfume::factory()->create(); + $category = Category::factory()->create(); + $outlet = Outlet::factory()->create(); + + Livewire::actingAs($this->user) + ->test(Edit::class, ['perfume' => $perfume]) + ->set('form.name', 'Updated Name') + ->set('form.category_ids', [$category->id]) + ->set('form.outlet_ids', [$outlet->id]) + ->call('save') + ->assertHasNoErrors() + ->assertRedirect(route('studio.catalog.perfume.index', ['notification' => 'Parfum berhasil diperbarui.'])); + + $this->assertDatabaseHas('perfumes', [ + 'id' => $perfume->id, + 'name' => 'Updated Name', + ]); +}); + +it('cannot access perfume edit without permission', function () { + $perfume = Perfume::factory()->create(); + $this->user->roles()->detach(); + $this->user->permissions()->detach(); + + $this->actingAs($this->user) + ->get(route('studio.catalog.perfume.edit', ['perfume' => $perfume])) + ->assertForbidden(); +}); diff --git a/tests/Feature/Studio/Catalog/Perfume/IndexTest.php b/tests/Feature/Studio/Catalog/Perfume/IndexTest.php new file mode 100644 index 0000000..6048b22 --- /dev/null +++ b/tests/Feature/Studio/Catalog/Perfume/IndexTest.php @@ -0,0 +1,45 @@ +setupUser(); + + $role = Role::firstOrCreate(['name' => 'Owner']); + Permission::firstOrCreate(['name' => 'view perfume']); + Permission::firstOrCreate(['name' => 'delete perfume']); + $role->givePermissionTo(['view perfume', 'delete perfume']); + $this->user->assignRole($role); +}); + +it('renders the perfume index page correctly', function () { + $this->actingAs($this->user) + ->get(route('studio.catalog.perfume.index')) + ->assertOk() + ->assertSeeLivewire(Index::class); +}); + +it('can delete a perfume', function () { + $perfume = Perfume::factory()->create(); + + Livewire::actingAs($this->user) + ->test(Index::class) + ->call('delete', $perfume->id) + ->assertHasNoErrors() + ->assertDispatched('refreshDatatable'); + + $this->assertSoftDeleted('perfumes', ['id' => $perfume->id]); +}); + +it('cannot access perfume index without permission', function () { + $this->user->roles()->detach(); + $this->user->permissions()->detach(); + + $this->actingAs($this->user) + ->get(route('studio.catalog.perfume.index')) + ->assertForbidden(); +});