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();
+});