- kasih return type - ubah array to collection di audit - mengubah waktu refresh tabel menjadi 30 detik
119 lines
3.5 KiB
PHP
119 lines
3.5 KiB
PHP
<?php
|
|
|
|
use App\Models\Employee;
|
|
use App\Models\Perfume;
|
|
use App\Models\User;
|
|
use Database\Seeders\RolePermissionSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Livewire\Livewire;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
$this->seed(RolePermissionSeeder::class);
|
|
|
|
$this->user = User::factory()
|
|
->active()
|
|
->has(Employee::factory())
|
|
->create();
|
|
|
|
$this->ownerRole = Role::where('name', 'Owner')->first();
|
|
$this->user->roles()->attach($this->ownerRole->id);
|
|
});
|
|
|
|
function mountPerfumeIndexComponent(User $user)
|
|
{
|
|
return Livewire::actingAs($user)->test(\App\Livewire\Studio\Catalog\Perfume\Index::class);
|
|
}
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Index Component Rendering & Basic Functionality
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
it('renders perfume index page successfully', function () {
|
|
mountPerfumeIndexComponent($this->user)
|
|
->assertViewIs('livewire.studio.catalog.perfume.index')
|
|
->assertViewHas('pageTitle', 'Parfum');
|
|
});
|
|
|
|
it('displays perfumes correctly', function () {
|
|
Perfume::factory()->count(3)->create();
|
|
|
|
// Just check that the component renders without errors and has perfumes
|
|
$component = mountPerfumeIndexComponent($this->user);
|
|
$component->assertViewIs('livewire.studio.catalog.perfume.index');
|
|
expect(Perfume::count())->toBe(3);
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Delete Perfume Tests
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
it('deletes perfume successfully when authorized', function () {
|
|
$perfume = Perfume::factory()->create([
|
|
'name' => 'Perfume to Delete',
|
|
]);
|
|
|
|
mountPerfumeIndexComponent($this->user)
|
|
->call('delete', $perfume)
|
|
->assertHasNoErrors()
|
|
->assertDispatched('refreshDatatable');
|
|
|
|
$this->assertSoftDeleted('perfumes', [
|
|
'id' => $perfume->id,
|
|
]);
|
|
});
|
|
|
|
it('prevents perfume deletion when unauthorized', function () {
|
|
$this->ownerRole->revokePermissionTo('delete perfume');
|
|
|
|
$perfume = Perfume::factory()->create();
|
|
|
|
mountPerfumeIndexComponent($this->user)
|
|
->call('delete', $perfume)
|
|
->assertForbidden();
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Authorization Edge Cases
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
it('handles unauthorized user with revoked permissions', function () {
|
|
// Revoke all perfume permissions
|
|
$this->ownerRole->revokePermissionTo(['delete perfume']);
|
|
|
|
// Define gates to return false
|
|
Gate::define('delete perfume', fn () => false);
|
|
|
|
$perfume = Perfume::factory()->create();
|
|
|
|
// Test delete
|
|
mountPerfumeIndexComponent($this->user)
|
|
->call('delete', $perfume)
|
|
->assertForbidden();
|
|
});
|
|
|
|
it('handles user with partial permissions correctly', function () {
|
|
// Remove owner role and create a user with limited permissions
|
|
$this->user->roles()->detach();
|
|
$limitedRole = Role::create(['name' => 'Limited User']);
|
|
$this->user->roles()->attach($limitedRole->id);
|
|
|
|
// Give only some permissions but not delete
|
|
$limitedRole->givePermissionTo([]);
|
|
|
|
$perfume = Perfume::factory()->create();
|
|
|
|
// Should not be able to delete
|
|
mountPerfumeIndexComponent($this->user)
|
|
->call('delete', $perfume)
|
|
->assertForbidden();
|
|
});
|