parfum/tests/Feature/Livewire/Studio/Master/User/CreateTest.php
Yoga Pangestu 2b5983fb2a fix(user): memperbaiki attach role dan mengubha tipe data prop gender ke int
- kasih otorisasi saat delete dan reset password
- memperbaiki testnya
- kasih kondisi untuk data kosong jangan di tampilkan di view
2025-12-10 08:36:29 +07:00

652 lines
22 KiB
PHP

<?php
use App\Enums\Gender;
use App\Enums\UserStatus;
use App\Livewire\Studio\Master\User\Create;
use App\Livewire\Studio\Master\User\Index;
use App\Models\Employee;
use App\Models\Outlet;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Hash;
use Livewire\Features\SupportTesting\Testable;
use Livewire\Livewire;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->user = User::factory()
->active()
->has(Employee::factory())
->create();
});
function mountCreateComponent(User $user): Testable
{
return Livewire::actingAs($user)->test(Create::class);
}
it('renders page successfully', function () {
mountCreateComponent($this->user)
->assertViewIs('livewire.studio.master.user.form')
->assertViewHas('pageTitle', 'Tambah Pegawai');
});
it('loads outlets and roles on mount', function () {
$outlet = Outlet::factory()->create();
$role = Role::create(['name' => 'Admin']);
$component = mountCreateComponent($this->user);
expect($component->outlets)->toBeArray();
expect($component->outlets)->toHaveKey($outlet->id);
expect($component->roles)->toBeArray();
expect($component->roles)->toHaveKey($role->id);
});
it('excludes developer role from roles list', function () {
Role::create(['name' => 'Developer']);
$adminRole = Role::create(['name' => 'Admin']);
$component = mountCreateComponent($this->user);
expect($component->roles)->not->toHaveKey(Role::where('name', 'Developer')->first()->id);
expect($component->roles)->toHaveKey($adminRole->id);
});
it('prevents create when user is unauthorized', function () {
Gate::define('create user', fn () => false);
mountCreateComponent($this->user)
->call('save')
->assertForbidden();
});
it('creates user successfully when authorized', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$outlet = Outlet::factory()->create();
$role = Role::create(['name' => 'Admin']);
$defaultPassword = config('myconfig.password_default');
mountCreateComponent($this->user)
->set('form.full_name', 'John Doe')
->set('form.username', 'johndoe')
->set('form.email', 'john@example.com')
->set('form.phone_number', '0812 3456 7890')
->set('form.base_salary', '5000000')
->set('form.birthdate', now()->subYears(25)->format('Y-m-d'))
->set('form.hire_date', now()->subMonths(6)->format('Y-m-d'))
->set('form.gender', Gender::MALE->value)
->set('form.status', UserStatus::ACTIVE->value)
->set('form.outlet_ids', [$outlet->id])
->set('form.role_ids', [$role->id])
->call('save')
->assertHasNoErrors()
->assertRedirect(Index::class);
$createdUser = User::where('email', 'john@example.com')->first();
expect($createdUser)->not->toBeNull()
->and($createdUser->username)->toBe('johndoe')
->and($createdUser->status)->toBe(UserStatus::ACTIVE)
->and(Hash::check($defaultPassword, $createdUser->password))->toBeTrue();
$this->assertDatabaseHas('employees', [
'user_id' => $createdUser->id,
'full_name' => 'John Doe',
'gender' => Gender::MALE,
]);
expect($createdUser->outlets)->toHaveCount(1)
->and($createdUser->roles)->toHaveCount(1)
->and($createdUser->referralCode)->not->toBeNull();
});
it('creates user with inactive status and sets resign date', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$outlet = Outlet::factory()->create();
$role = Role::create(['name' => 'Admin']);
$birthdate = now()->subYears(25)->format('Y-m-d');
$hireDate = now()->subMonths(6)->format('Y-m-d');
mountCreateComponent($this->user)
->set('form.full_name', 'Jane Doe')
->set('form.username', 'janedoe')
->set('form.email', 'jane@example.com')
->set('form.phone_number', '0812 3456 7891')
->set('form.base_salary', '4.500.000')
->set('form.birthdate', $birthdate)
->set('form.hire_date', $hireDate)
->set('form.gender', Gender::FEMALE->value)
->set('form.status', UserStatus::INACTIVE->value)
->set('form.outlet_ids', [$outlet->id])
->set('form.role_ids', [$role->id])
->call('save')
->assertHasNoErrors();
$createdUser = User::where('email', 'jane@example.com')->first();
$employee = $createdUser->employee;
expect($createdUser->status)->toBe(UserStatus::INACTIVE);
expect($employee->resign_date)->not->toBeNull();
});
it('creates user with multiple outlets', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$outlet1 = Outlet::factory()->create();
$outlet2 = Outlet::factory()->create();
$outlet3 = Outlet::factory()->create();
$role = Role::create(['name' => 'Admin']);
$birthdate = now()->subYears(25)->format('Y-m-d');
$hireDate = now()->subMonths(6)->format('Y-m-d');
mountCreateComponent($this->user)
->set('form.full_name', 'Multiple Outlet User')
->set('form.username', 'multioutlet')
->set('form.email', 'multi@example.com')
->set('form.phone_number', '0812 3456 7892')
->set('form.base_salary', '5.500.000')
->set('form.birthdate', $birthdate)
->set('form.hire_date', $hireDate)
->set('form.gender', Gender::MALE->value)
->set('form.status', UserStatus::ACTIVE->value)
->set('form.outlet_ids', [$outlet1->id, $outlet2->id, $outlet3->id])
->set('form.role_ids', [$role->id])
->call('save')
->assertHasNoErrors();
$createdUser = User::where('email', 'multi@example.com')->first();
expect($createdUser->outlets->count())->toBe(3);
expect($createdUser->outlets->pluck('id')->toArray())->toContain($outlet1->id, $outlet2->id, $outlet3->id);
});
it('creates user with multiple roles', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$outlet = Outlet::factory()->create();
$adminRole = Role::create(['name' => 'Admin']);
$leaderRole = Role::create(['name' => 'Leader']);
$birthdate = now()->subYears(25)->format('Y-m-d');
$hireDate = now()->subMonths(6)->format('Y-m-d');
mountCreateComponent($this->user)
->set('form.full_name', 'Multiple Role User')
->set('form.username', 'multirole')
->set('form.email', 'role@example.com')
->set('form.phone_number', '0812 3456 7893')
->set('form.base_salary', '6.000.000')
->set('form.birthdate', $birthdate)
->set('form.hire_date', $hireDate)
->set('form.gender', Gender::MALE->value)
->set('form.status', UserStatus::ACTIVE->value)
->set('form.outlet_ids', [$outlet->id])
->set('form.role_ids', [$adminRole->id, $leaderRole->id])
->call('save')
->assertHasNoErrors();
$createdUser = User::where('email', 'role@example.com')->first();
expect($createdUser->roles->count())->toBe(2);
expect($createdUser->roles->pluck('id')->toArray())->toContain($adminRole->id, $leaderRole->id);
});
it('validates required fields', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$component = mountCreateComponent($this->user);
// Don't set any required fields to ensure they're validated
$component->call('save')
->assertHasErrors([
'form.full_name',
'form.username',
'form.email',
'form.phone_number',
'form.base_salary',
'form.birthdate',
'form.hire_date',
'form.gender',
'form.outlet_ids',
'form.role_ids',
]);
});
it('validates full_name field max length', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', str_repeat('a', 101))
->call('save')
->assertHasErrors(['form.full_name']);
});
it('validates username field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->call('save')
->assertHasErrors(['form.username']);
});
it('validates username field alpha numeric', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.username', 'test-user@123')
->call('save')
->assertHasErrors(['form.username']);
});
it('validates username field min length', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.username', 'test')
->call('save')
->assertHasErrors(['form.username']);
});
it('validates username field max length', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.username', str_repeat('a', 21))
->call('save')
->assertHasErrors(['form.username']);
});
it('validates username field uniqueness', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$existingUser = User::factory()->create(['username' => 'existinguser']);
mountCreateComponent($this->user)
->set('form.username', 'existinguser')
->call('save')
->assertHasErrors(['form.username']);
});
it('validates email field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->call('save')
->assertHasErrors(['form.email']);
});
it('validates email field format', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.email', 'invalid-email')
->call('save')
->assertHasErrors(['form.email']);
});
it('validates email field max length', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.email', str_repeat('a', 90).'@example.com')
->call('save')
->assertHasErrors(['form.email']);
});
it('validates email field uniqueness', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$existingUser = User::factory()->create(['email' => 'existing@example.com']);
mountCreateComponent($this->user)
->set('form.email', 'existing@example.com')
->call('save')
->assertHasErrors(['form.email']);
});
it('validates phone_number field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->set('form.email', 'test@example.com')
->call('save')
->assertHasErrors(['form.phone_number']);
});
it('validates base_salary field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->set('form.email', 'test@example.com')
->call('save')
->assertHasErrors(['form.base_salary']);
});
it('validates birthdate field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->set('form.email', 'test@example.com')
->call('save')
->assertHasErrors(['form.birthdate']);
});
it('validates birthdate must be before 18 years ago', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$birthdate = now()->subYears(17)->format('Y-m-d');
mountCreateComponent($this->user)
->set('form.birthdate', $birthdate)
->call('save')
->assertHasErrors(['form.birthdate']);
});
it('validates hire_date field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->set('form.email', 'test@example.com')
->call('save')
->assertHasErrors(['form.hire_date']);
});
it('validates gender field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->set('form.email', 'test@example.com')
->call('save')
->assertHasErrors(['form.gender']);
});
it('validates gender field must be valid enum value', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.gender', 999) // Invalid enum value
->call('save')
->assertHasErrors(['form.gender']);
});
it('validates status field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->set('form.email', 'test@example.com')
->set('form.status', 99) // Invalid enum value
->call('save')
->assertHasErrors(['form.status']);
});
it('validates status field must be valid enum value', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.status', '99')
->call('save')
->assertHasErrors(['form.status']);
});
it('validates outlet_ids field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->set('form.email', 'test@example.com')
->call('save')
->assertHasErrors(['form.outlet_ids']);
});
it('validates outlet_ids must be array', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$this->expectException(TypeError::class);
mountCreateComponent($this->user)
->set('form.outlet_ids', 'not-array')
->call('save')
->assertHasErrors(['form.outlet_ids']);
});
it('validates outlet_ids minimum count', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.outlet_ids', [])
->call('save')
->assertHasErrors(['form.outlet_ids']);
});
it('validates outlet_ids must exist', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.outlet_ids', [99999])
->call('save')
->assertHasErrors(['form.outlet_ids.0']);
});
it('validates role_ids field required', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.full_name', 'Test User')
->set('form.username', 'testuser')
->set('form.email', 'test@example.com')
->call('save')
->assertHasErrors(['form.role_ids']);
});
it('validates role_ids must be array', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$this->expectException(TypeError::class);
mountCreateComponent($this->user)
->set('form.role_ids', 'not-array')
->call('save')
->assertHasErrors(['form.role_ids']);
});
it('validates role_ids minimum count', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.role_ids', [])
->call('save')
->assertHasErrors(['form.role_ids']);
});
it('validates role_ids must exist', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
mountCreateComponent($this->user)
->set('form.role_ids', [99999])
->call('save')
->assertHasErrors(['form.role_ids.0']);
});
it('creates employee code automatically', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$outlet = Outlet::factory()->create();
$role = Role::create(['name' => 'Admin']);
$birthdate = now()->subYears(25)->format('Y-m-d');
$hireDate = now()->subMonths(6)->format('Y-m-d');
mountCreateComponent($this->user)
->set('form.full_name', 'Employee Code Test')
->set('form.username', 'empcodetest')
->set('form.email', 'empcode@example.com')
->set('form.phone_number', '0812 3456 7894')
->set('form.base_salary', '4.000.000')
->set('form.birthdate', $birthdate)
->set('form.hire_date', $hireDate)
->set('form.gender', Gender::MALE->value)
->set('form.status', UserStatus::ACTIVE->value)
->set('form.outlet_ids', [$outlet->id])
->set('form.role_ids', [$role->id])
->call('save')
->assertHasNoErrors();
$createdUser = User::where('email', 'empcode@example.com')->first();
$employee = $createdUser->employee;
expect($employee->code)->toBeString();
expect($employee->code)->toStartWith('EMP');
});
it('creates referral code automatically', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$outlet = Outlet::factory()->create();
$role = Role::create(['name' => 'Admin']);
$birthdate = now()->subYears(25)->format('Y-m-d');
$hireDate = now()->subMonths(6)->format('Y-m-d');
mountCreateComponent($this->user)
->set('form.full_name', 'Referral Code Test')
->set('form.username', 'refcodetest')
->set('form.email', 'refcode@example.com')
->set('form.phone_number', '0812 3456 7895')
->set('form.base_salary', '4.500.000')
->set('form.birthdate', $birthdate)
->set('form.hire_date', $hireDate)
->set('form.gender', Gender::MALE->value)
->set('form.status', UserStatus::ACTIVE->value)
->set('form.outlet_ids', [$outlet->id])
->set('form.role_ids', [$role->id])
->call('save')
->assertHasNoErrors();
$createdUser = User::where('email', 'refcode@example.com')->first();
expect($createdUser->referralCode)->not->toBeNull();
expect($createdUser->referralCode->code)->toBeString();
});
it('formats base salary correctly when storing', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$outlet = Outlet::factory()->create();
$role = Role::create(['name' => 'Admin']);
$birthdate = now()->subYears(25)->format('Y-m-d');
$hireDate = now()->subMonths(6)->format('Y-m-d');
mountCreateComponent($this->user)
->set('form.full_name', 'Salary Format Test')
->set('form.username', 'salarytest')
->set('form.email', 'salary@example.com')
->set('form.phone_number', '0812 3456 7896')
->set('form.base_salary', '5.500.000')
->set('form.birthdate', $birthdate)
->set('form.hire_date', $hireDate)
->set('form.gender', Gender::MALE->value)
->set('form.status', UserStatus::ACTIVE->value)
->set('form.outlet_ids', [$outlet->id])
->set('form.role_ids', [$role->id])
->call('save')
->assertHasNoErrors();
$createdUser = User::where('email', 'salary@example.com')->first();
$employee = $createdUser->employee;
expect($employee->base_salary)->toBe(5500000);
});
it('allows nullable address field', function () {
$permission = Permission::create(['name' => 'create user']);
$this->user->givePermissionTo($permission);
$outlet = Outlet::factory()->create();
$role = Role::create(['name' => 'Admin']);
$birthdate = now()->subYears(25)->format('Y-m-d');
$hireDate = now()->subMonths(6)->format('Y-m-d');
mountCreateComponent($this->user)
->set('form.full_name', 'No Address Test')
->set('form.username', 'noaddresstest')
->set('form.email', 'noaddress@example.com')
->set('form.phone_number', '0812 3456 7897')
->set('form.base_salary', '4.000.000')
->set('form.birthdate', $birthdate)
->set('form.hire_date', $hireDate)
->set('form.address', null)
->set('form.gender', Gender::MALE->value)
->set('form.status', UserStatus::ACTIVE->value)
->set('form.outlet_ids', [$outlet->id])
->set('form.role_ids', [$role->id])
->call('save')
->assertHasNoErrors();
$createdUser = User::where('email', 'noaddress@example.com')->first();
$employee = $createdUser->employee;
expect($employee->address)->toBeNull();
});