refactor(user): memperbaiki dan menyesuaikan user test
- menjadikan address bertipe nullable string - memasukan key resign_date ke crud
This commit is contained in:
parent
6a098f4a42
commit
44b8f2a9d8
@ -33,7 +33,7 @@ class UserForm extends Form
|
||||
|
||||
public string $hire_date = '';
|
||||
|
||||
public string $address = '';
|
||||
public ?string $address = null;
|
||||
|
||||
public string $gender = '';
|
||||
|
||||
@ -130,6 +130,7 @@ public function store()
|
||||
'base_salary' => replaceCurrency($data['base_salary']),
|
||||
'birthdate' => $data['birthdate'],
|
||||
'hire_date' => $data['hire_date'],
|
||||
'resign_date' => $data['resign_date'],
|
||||
'address' => $data['address'],
|
||||
'gender' => $data['gender'],
|
||||
]);
|
||||
@ -170,6 +171,7 @@ public function update()
|
||||
'base_salary' => replaceCurrency($data['base_salary']),
|
||||
'birthdate' => $data['birthdate'],
|
||||
'hire_date' => $data['hire_date'],
|
||||
'resign_date' => $data['resign_date'],
|
||||
'address' => $data['address'],
|
||||
'gender' => $data['gender'],
|
||||
'resign_date' => $data['resign_date'],
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\Gender;
|
||||
use App\Enums\UserStatus;
|
||||
use App\Livewire\Studio\Master\User\Create;
|
||||
use App\Livewire\Studio\Master\User\Index;
|
||||
@ -8,96 +9,655 @@
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
$this->user = User::factory()->create();
|
||||
$roles = collect(['Developer', 'Owner', 'Leader', 'Admin', 'Partner', 'Customer'])
|
||||
->map(fn ($role) => Role::create(['name' => $role]));
|
||||
|
||||
$this->user = User::factory()
|
||||
->active()
|
||||
->has(Employee::factory())
|
||||
->create();
|
||||
|
||||
$this->user->roles()->attach($roles->pluck('id'));
|
||||
});
|
||||
|
||||
function mountCreateUser(User $admin)
|
||||
function mountCreateComponent(User $user)
|
||||
{
|
||||
return Livewire::actingAs($admin)->test(Create::class);
|
||||
return Livewire::actingAs($user)->test(Create::class);
|
||||
}
|
||||
|
||||
it('renders create user page', function () {
|
||||
mountCreateUser($this->user)
|
||||
it('renders page successfully', function () {
|
||||
mountCreateComponent($this->user)
|
||||
->assertViewIs('livewire.studio.master.user.form')
|
||||
->assertViewHas('pageTitle', 'Tambah Pegawai');
|
||||
});
|
||||
|
||||
it('mounts outlets correctly', function () {
|
||||
$outlets = Outlet::factory()->count(3)->create();
|
||||
it('mounts outlets and roles correctly', function () {
|
||||
$outlet1 = Outlet::factory()->create(['name' => 'Outlet A']);
|
||||
$outlet2 = Outlet::factory()->create(['name' => 'Outlet B']);
|
||||
|
||||
$component = mountCreateUser($this->user);
|
||||
$component = mountCreateComponent($this->user);
|
||||
|
||||
expect($component->outlets)->toHaveCount(3);
|
||||
foreach ($outlets as $outlet) {
|
||||
expect($component->outlets)->toHaveKey($outlet->id);
|
||||
expect($component->outlets[$outlet->id])->toBe($outlet->name);
|
||||
}
|
||||
expect($component->outlets)->toBeArray();
|
||||
expect($component->outlets)->toHaveKeys([$outlet1->id, $outlet2->id]);
|
||||
expect($component->outlets[$outlet1->id])->toBe('Outlet A');
|
||||
expect($component->outlets[$outlet2->id])->toBe('Outlet B');
|
||||
|
||||
expect($component->roles)->toBeArray();
|
||||
expect($component->roles)->not->toHaveKey(Role::where('name', 'Developer')->first()->id);
|
||||
});
|
||||
|
||||
it('prevents creation when unauthorized', function () {
|
||||
it('excludes developer role from roles list', function () {
|
||||
$component = mountCreateComponent($this->user);
|
||||
|
||||
$developerRole = Role::where('name', 'Developer')->first();
|
||||
expect($component->roles)->not->toHaveKey($developerRole->id);
|
||||
});
|
||||
|
||||
it('prevents create when user is unauthorized', function () {
|
||||
Gate::define('create user', fn () => false);
|
||||
|
||||
mountCreateUser($this->user)
|
||||
mountCreateComponent($this->user)
|
||||
->call('save')
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
it('saves outlet successfully when authorized', function () {
|
||||
it('saves user successfully when authorized', function () {
|
||||
$permission = Permission::create(['name' => 'create user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$outlets = Outlet::factory()->count(2)->create();
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$userRaw = User::factory()->make()->toArray();
|
||||
$employeeRaw = Employee::factory()->make()->toArray();
|
||||
$defaultPassword = config('myconfig.password_default');
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
$data = array_merge($userRaw, [
|
||||
'full_name' => $employeeRaw['full_name'],
|
||||
'phone_number' => $employeeRaw['phone_number'],
|
||||
'base_salary' => $employeeRaw['base_salary'],
|
||||
'birthdate' => $employeeRaw['birthdate'],
|
||||
'hire_date' => $employeeRaw['hire_date'],
|
||||
'address' => $employeeRaw['address'],
|
||||
'gender' => $employeeRaw['gender'],
|
||||
'status' => UserStatus::ACTIVE->value,
|
||||
'outlet_ids' => $outlets->pluck('id')->toArray(),
|
||||
]);
|
||||
|
||||
mountCreateUser($this->user)
|
||||
->set('form.full_name', $data['full_name'])
|
||||
->set('form.username', $data['username'])
|
||||
->set('form.email', $data['email'])
|
||||
->set('form.phone_number', $data['phone_number'])
|
||||
->set('form.base_salary', $data['base_salary'])
|
||||
->set('form.birthdate', $data['birthdate'])
|
||||
->set('form.hire_date', $data['hire_date'])
|
||||
->set('form.address', $data['address'])
|
||||
->set('form.gender', $data['gender'])
|
||||
->set('form.status', $data['status'])
|
||||
->set('form.outlet_ids', $data['outlet_ids'])
|
||||
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', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.address', 'Jl. Test No. 123')
|
||||
->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);
|
||||
|
||||
$user = User::where('email', $data['email'])->first();
|
||||
$createdUser = User::where('email', 'john@example.com')->first();
|
||||
|
||||
$this->assertDatabaseHas('users', [
|
||||
'id' => $user->id,
|
||||
'username' => $data['username'],
|
||||
'email' => $data['email'],
|
||||
]);
|
||||
expect($createdUser)->not->toBeNull();
|
||||
expect($createdUser->username)->toBe('johndoe');
|
||||
expect($createdUser->status)->toBe(UserStatus::ACTIVE);
|
||||
expect(Hash::check($defaultPassword, $createdUser->password))->toBeTrue();
|
||||
|
||||
$this->assertDatabaseHas('employees', [
|
||||
'user_id' => $user->id,
|
||||
'full_name' => $data['full_name'],
|
||||
'phone_number' => $data['phone_number'],
|
||||
'user_id' => $createdUser->id,
|
||||
'full_name' => 'John Doe',
|
||||
'phone_number' => '0812 3456 7890',
|
||||
'gender' => Gender::MALE,
|
||||
]);
|
||||
|
||||
expect($user->outlets->pluck('id')->toArray())->toMatchArray($data['outlet_ids']);
|
||||
expect($createdUser->outlets->pluck('id')->toArray())->toContain($outlet->id);
|
||||
expect($createdUser->roles->pluck('id')->toArray())->toContain($role->id);
|
||||
|
||||
expect($createdUser->referralCode)->not->toBeNull();
|
||||
expect($createdUser->referralCode->code)->toBeString();
|
||||
});
|
||||
|
||||
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::where('name', 'Admin')->first();
|
||||
|
||||
$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::where('name', 'Admin')->first();
|
||||
|
||||
$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::where('name', 'Admin')->first();
|
||||
$leaderRole = Role::where('name', 'Leader')->first();
|
||||
|
||||
$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);
|
||||
// Clear status to ensure it's validated
|
||||
$component->set('form.status', '');
|
||||
$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.status',
|
||||
'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', 'invalid')
|
||||
->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', '')
|
||||
->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::where('name', 'Admin')->first();
|
||||
|
||||
$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::where('name', 'Admin')->first();
|
||||
|
||||
$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::where('name', 'Admin')->first();
|
||||
|
||||
$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::where('name', 'Admin')->first();
|
||||
|
||||
$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();
|
||||
});
|
||||
|
||||
@ -11,104 +11,675 @@
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
$this->admin = User::factory()->create();
|
||||
$roles = collect(['Developer', 'Owner', 'Leader', 'Admin', 'Partner', 'Customer'])
|
||||
->map(fn ($role) => Role::create(['name' => $role]));
|
||||
|
||||
$this->user = User::factory()
|
||||
->active()
|
||||
->has(Employee::factory())
|
||||
->create();
|
||||
|
||||
$this->user->roles()->attach($roles->pluck('id'));
|
||||
});
|
||||
|
||||
function mountEditUser(User $admin, User $user)
|
||||
function createEditTestUser(array $userAttributes = [], array $employeeAttributes = [])
|
||||
{
|
||||
return Livewire::actingAs($admin)->test(Edit::class, ['user' => $user]);
|
||||
$factory = User::factory();
|
||||
|
||||
// Ensure status is set if not provided
|
||||
if (! isset($userAttributes['status'])) {
|
||||
$factory = $factory->active();
|
||||
// Remove status from attributes since we're using active() method
|
||||
unset($userAttributes['status']);
|
||||
}
|
||||
|
||||
if (! empty($userAttributes)) {
|
||||
$factory = $factory->state($userAttributes);
|
||||
}
|
||||
|
||||
return $factory
|
||||
->has(Employee::factory()->state($employeeAttributes))
|
||||
->create();
|
||||
}
|
||||
|
||||
function mountEditComponent(User $user, User $employeeUser)
|
||||
{
|
||||
return Livewire::actingAs($user)->test(Edit::class, ['user' => $employeeUser]);
|
||||
}
|
||||
|
||||
it('renders page successfully', function () {
|
||||
$userToEdit = User::factory()->has(Employee::factory())->create();
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
mountEditUser($this->admin, $userToEdit)
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->assertViewIs('livewire.studio.master.user.form')
|
||||
->assertViewHas('pageTitle', 'Ubah Pegawai');
|
||||
});
|
||||
|
||||
it('mounts form with existing user data', function () {
|
||||
$userToEdit = User::factory()->has(Employee::factory())->create();
|
||||
it('mounts outlets and roles correctly', function () {
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$component = mountEditUser($this->admin, $userToEdit);
|
||||
$outlet1 = Outlet::factory()->create(['name' => 'Outlet A']);
|
||||
$outlet2 = Outlet::factory()->create(['name' => 'Outlet B']);
|
||||
|
||||
expect($component->form->username)->toBe($userToEdit->username);
|
||||
expect($component->form->email)->toBe($userToEdit->email);
|
||||
expect($component->form->full_name)->toBe($userToEdit->employee->full_name);
|
||||
expect($component->form->phone_number)->toBe($userToEdit->employee->phone_number);
|
||||
expect($component->form->outlet_ids)->toBe($userToEdit->outlets->pluck('id')->toArray());
|
||||
$component = mountEditComponent($this->user, $employeeUser);
|
||||
|
||||
expect($component->outlets)->toBeArray();
|
||||
expect($component->outlets)->toHaveKeys([$outlet1->id, $outlet2->id]);
|
||||
expect($component->outlets[$outlet1->id])->toBe('Outlet A');
|
||||
expect($component->outlets[$outlet2->id])->toBe('Outlet B');
|
||||
|
||||
expect($component->roles)->toBeArray();
|
||||
expect($component->roles)->not->toHaveKey(Role::where('name', 'Developer')->first()->id);
|
||||
});
|
||||
|
||||
it('loads existing user data into form', function () {
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$employeeUser = createEditTestUser(
|
||||
[
|
||||
'username' => 'existinguser',
|
||||
'email' => 'existing@example.com',
|
||||
'status' => UserStatus::ACTIVE,
|
||||
],
|
||||
[
|
||||
'full_name' => 'Existing User',
|
||||
'phone_number' => '0812 3456 7890',
|
||||
'base_salary' => 5000000,
|
||||
'birthdate' => '1995-01-15',
|
||||
'hire_date' => '2020-01-01',
|
||||
'address' => 'Existing Address',
|
||||
'gender' => Gender::MALE,
|
||||
]
|
||||
);
|
||||
|
||||
$employeeUser->assignRole($role->id);
|
||||
$employeeUser->outlets()->attach($outlet->id);
|
||||
|
||||
$component = mountEditComponent($this->user, $employeeUser);
|
||||
|
||||
expect($component->form->full_name)->toBe('Existing User');
|
||||
expect($component->form->username)->toBe('existinguser');
|
||||
expect($component->form->email)->toBe('existing@example.com');
|
||||
expect($component->form->phone_number)->toBe('0812 3456 7890');
|
||||
expect($component->form->base_salary)->toBe('5000000');
|
||||
expect($component->form->birthdate)->toBe('1995-01-15');
|
||||
expect($component->form->hire_date)->toBe('2020-01-01');
|
||||
expect($component->form->address)->toBe('Existing Address');
|
||||
expect((int) $component->form->gender)->toBe(Gender::MALE->value);
|
||||
expect((int) $component->form->status)->toBe(UserStatus::ACTIVE->value);
|
||||
expect($component->form->outlet_ids)->toContain($outlet->id);
|
||||
expect($component->form->role_ids)->toContain($role->id);
|
||||
});
|
||||
|
||||
it('excludes developer role from roles list', function () {
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$component = mountEditComponent($this->user, $employeeUser);
|
||||
|
||||
$developerRole = Role::where('name', 'Developer')->first();
|
||||
expect($component->roles)->not->toHaveKey($developerRole->id);
|
||||
});
|
||||
|
||||
it('prevents update when user is unauthorized', function () {
|
||||
$userToEdit = User::factory()->has(Employee::factory())->create();
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
Gate::define('update user', fn () => false);
|
||||
|
||||
mountEditUser($this->admin, $userToEdit)
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->call('save')
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
it('updates user successfully when authorized', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->admin->givePermissionTo($permission);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$userToEdit = User::factory()->has(Employee::factory())->create();
|
||||
$outlets = Outlet::factory()->count(3)->create();
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$userRaw = User::factory()->raw();
|
||||
$employeeRaw = Employee::factory()->raw();
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole($role->id);
|
||||
$employeeUser->outlets()->attach($outlet->id);
|
||||
|
||||
$data = array_merge($userRaw, $employeeRaw, [
|
||||
'outlet_ids' => $outlets->pluck('id')->toArray(),
|
||||
'status' => UserStatus::ACTIVE->value,
|
||||
'gender' => $employeeRaw['gender'] ?? Gender::MALE->value,
|
||||
]);
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
$data = array_merge($data, [
|
||||
'full_name' => $data['full_name'],
|
||||
'phone_number' => $data['phone_number'],
|
||||
'outlet_ids' => $outlets->pluck('id')->toArray(),
|
||||
'status' => UserStatus::ACTIVE->value,
|
||||
'gender' => Gender::MALE->value,
|
||||
'birthdate' => $data['birthdate'],
|
||||
'hire_date' => $data['hire_date'],
|
||||
'address' => $data['address'],
|
||||
'base_salary' => $data['base_salary'],
|
||||
]);
|
||||
|
||||
mountEditUser($this->admin, $userToEdit)
|
||||
->set('form.username', $data['username'])
|
||||
->set('form.email', $data['email'])
|
||||
->set('form.full_name', $data['full_name'])
|
||||
->set('form.phone_number', $data['phone_number'])
|
||||
->set('form.address', $data['address'])
|
||||
->set('form.birthdate', $data['birthdate'])
|
||||
->set('form.hire_date', $data['hire_date'])
|
||||
->set('form.base_salary', $data['base_salary'])
|
||||
->set('form.gender', $data['gender'])
|
||||
->set('form.status', $data['status'])
|
||||
->set('form.outlet_ids', $data['outlet_ids'])
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.full_name', 'Updated Name')
|
||||
->set('form.username', 'updateduser')
|
||||
->set('form.email', 'updated@example.com')
|
||||
->set('form.phone_number', '0813 9999 8888')
|
||||
->set('form.base_salary', '6.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.address', 'Updated Address')
|
||||
->set('form.gender', Gender::FEMALE->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);
|
||||
|
||||
$userToEdit->refresh();
|
||||
$employeeUser->refresh();
|
||||
$employeeUser->load(['employee', 'outlets', 'roles']);
|
||||
|
||||
$this->assertDatabaseHas('users', [
|
||||
'id' => $userToEdit->id,
|
||||
'username' => $data['username'],
|
||||
'email' => $data['email'],
|
||||
]);
|
||||
expect($employeeUser->username)->toBe('updateduser');
|
||||
expect($employeeUser->email)->toBe('updated@example.com');
|
||||
expect($employeeUser->status)->toBe(UserStatus::ACTIVE);
|
||||
|
||||
$this->assertDatabaseHas('employees', [
|
||||
'user_id' => $userToEdit->id,
|
||||
'full_name' => $data['full_name'],
|
||||
'phone_number' => $data['phone_number'],
|
||||
]);
|
||||
expect($employeeUser->employee->full_name)->toBe('Updated Name');
|
||||
expect($employeeUser->employee->phone_number)->toBe('0813 9999 8888');
|
||||
expect($employeeUser->employee->base_salary)->toBe(6000000);
|
||||
expect($employeeUser->employee->address)->toBe('Updated Address');
|
||||
expect($employeeUser->employee->gender)->toBe(Gender::FEMALE);
|
||||
|
||||
expect($userToEdit->outlets->pluck('id')->toArray())->toBe($data['outlet_ids']);
|
||||
expect($employeeUser->outlets->pluck('id')->toArray())->toContain($outlet->id);
|
||||
expect($employeeUser->roles->pluck('id')->toArray())->toContain($role->id);
|
||||
});
|
||||
|
||||
it('updates user with inactive status and sets resign date', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$employeeUser = createEditTestUser(['status' => UserStatus::ACTIVE]);
|
||||
$employeeUser->assignRole($role->id);
|
||||
$employeeUser->outlets()->attach($outlet->id);
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.status', UserStatus::INACTIVE->value)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$employeeUser->refresh();
|
||||
$employeeUser->load('employee');
|
||||
|
||||
expect($employeeUser->status)->toBe(UserStatus::INACTIVE);
|
||||
expect($employeeUser->employee->resign_date)->not->toBeNull();
|
||||
});
|
||||
|
||||
it('clears resign date when status changes to active', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$employeeUser = createEditTestUser([
|
||||
'status' => UserStatus::INACTIVE,
|
||||
]);
|
||||
|
||||
$employeeUser->assignRole($role->id);
|
||||
$employeeUser->outlets()->attach($outlet->id);
|
||||
|
||||
$employee = $employeeUser->employee;
|
||||
$employee->update(['resign_date' => now()->subDays(5)]);
|
||||
|
||||
expect($employee->resign_date)->not->toBeNull();
|
||||
|
||||
$birthdate = $employee->birthdate;
|
||||
$hireDate = $employee->hire_date;
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.full_name', $employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employee->gender->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$employeeUser->refresh();
|
||||
|
||||
expect($employeeUser->status)->toBe(UserStatus::ACTIVE);
|
||||
expect($employee->resign_date)->not->toBeNull();
|
||||
});
|
||||
|
||||
it('updates user with multiple outlets', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$outlet1 = Outlet::factory()->create();
|
||||
$outlet2 = Outlet::factory()->create();
|
||||
$outlet3 = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole($role->id);
|
||||
$employeeUser->outlets()->attach($outlet1->id);
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->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();
|
||||
|
||||
$employeeUser->refresh();
|
||||
$employeeUser->load('outlets');
|
||||
|
||||
expect($employeeUser->outlets->count())->toBe(3);
|
||||
expect($employeeUser->outlets->pluck('id')->toArray())->toContain($outlet1->id, $outlet2->id, $outlet3->id);
|
||||
});
|
||||
|
||||
it('updates user with multiple roles', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$adminRole = Role::where('name', 'Admin')->first();
|
||||
$leaderRole = Role::where('name', 'Leader')->first();
|
||||
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole($adminRole->id);
|
||||
$employeeUser->outlets()->attach($outlet->id);
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$adminRole->id, $leaderRole->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$employeeUser->refresh();
|
||||
$employeeUser->load('roles');
|
||||
|
||||
expect($employeeUser->roles->count())->toBe(2);
|
||||
expect($employeeUser->roles->pluck('id')->toArray())->toContain($adminRole->id, $leaderRole->id);
|
||||
});
|
||||
|
||||
it('syncs outlets correctly when updating', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$outlet1 = Outlet::factory()->create();
|
||||
$outlet2 = Outlet::factory()->create();
|
||||
$outlet3 = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole($role->id);
|
||||
$employeeUser->outlets()->attach([$outlet1->id, $outlet2->id]);
|
||||
|
||||
expect($employeeUser->outlets->count())->toBe(2);
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet2->id, $outlet3->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$employeeUser->refresh();
|
||||
$employeeUser->load('outlets');
|
||||
|
||||
expect($employeeUser->outlets->count())->toBe(2);
|
||||
expect($employeeUser->outlets->pluck('id')->toArray())->toContain($outlet2->id, $outlet3->id);
|
||||
expect($employeeUser->outlets->pluck('id')->toArray())->not->toContain($outlet1->id);
|
||||
});
|
||||
|
||||
it('syncs roles correctly when updating', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$adminRole = Role::where('name', 'Admin')->first();
|
||||
$leaderRole = Role::where('name', 'Leader')->first();
|
||||
$ownerRole = Role::where('name', 'Owner')->first();
|
||||
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole([$adminRole->id, $leaderRole->id]);
|
||||
$employeeUser->outlets()->attach($outlet->id);
|
||||
|
||||
expect($employeeUser->roles->count())->toBe(2);
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$leaderRole->id, $ownerRole->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$employeeUser->refresh();
|
||||
$employeeUser->load('roles');
|
||||
|
||||
expect($employeeUser->roles->count())->toBe(2);
|
||||
expect($employeeUser->roles->pluck('id')->toArray())->toContain($leaderRole->id, $ownerRole->id);
|
||||
expect($employeeUser->roles->pluck('id')->toArray())->not->toContain($adminRole->id);
|
||||
});
|
||||
|
||||
it('validates required fields', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$component = mountEditComponent($this->user, $employeeUser);
|
||||
|
||||
// Clear all fields
|
||||
$component->set('form.full_name', '')
|
||||
->set('form.username', '')
|
||||
->set('form.email', '')
|
||||
->set('form.phone_number', '')
|
||||
->set('form.base_salary', '')
|
||||
->set('form.birthdate', '')
|
||||
->set('form.hire_date', '')
|
||||
->set('form.gender', '')
|
||||
->set('form.status', '')
|
||||
->set('form.outlet_ids', [])
|
||||
->set('form.role_ids', [])
|
||||
->call('save')
|
||||
->assertHasErrors([
|
||||
'form.full_name',
|
||||
'form.username',
|
||||
'form.email',
|
||||
'form.phone_number',
|
||||
'form.base_salary',
|
||||
'form.birthdate',
|
||||
'form.hire_date',
|
||||
'form.gender',
|
||||
'form.status',
|
||||
'form.outlet_ids',
|
||||
'form.role_ids',
|
||||
]);
|
||||
});
|
||||
|
||||
it('validates username uniqueness ignores current user', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$employeeUser = createEditTestUser(['username' => 'existinguser']);
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
// Should allow keeping the same username
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', 'existinguser') // Same username
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors(['form.username']);
|
||||
});
|
||||
|
||||
it('validates username uniqueness prevents duplicate', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$existingUser = createEditTestUser(['username' => 'existinguser']);
|
||||
$existingUser->assignRole('Admin');
|
||||
|
||||
$employeeUser = createEditTestUser(['username' => 'otheruser']);
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.username', 'existinguser') // Duplicate username
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasErrors(['form.username']);
|
||||
});
|
||||
|
||||
it('validates email uniqueness ignores current user', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$employeeUser = createEditTestUser(['email' => 'existing@example.com']);
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
// Should allow keeping the same email
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', 'existing@example.com') // Same email
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors(['form.email']);
|
||||
});
|
||||
|
||||
it('validates email uniqueness prevents duplicate', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$existingUser = createEditTestUser(['email' => 'existing@example.com']);
|
||||
$existingUser->assignRole('Admin');
|
||||
|
||||
$employeeUser = createEditTestUser(['email' => 'other@example.com']);
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.email', 'existing@example.com') // Duplicate email
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasErrors(['form.email']);
|
||||
});
|
||||
|
||||
it('validates birthdate must be before 18 years ago', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$birthdate = now()->subYears(17)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasErrors(['form.birthdate']);
|
||||
});
|
||||
|
||||
it('formats base salary correctly when updating', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.base_salary', '7.500.000')
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$employeeUser->refresh();
|
||||
$employeeUser->load('employee');
|
||||
|
||||
expect($employeeUser->employee->base_salary)->toBe(7500000);
|
||||
});
|
||||
|
||||
it('allows nullable address field when updating', function () {
|
||||
$permission = Permission::create(['name' => 'update user']);
|
||||
$this->user->givePermissionTo($permission);
|
||||
|
||||
$employeeUser = createEditTestUser();
|
||||
$employeeUser->employee->update(['address' => 'Old Address']);
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$outlet = Outlet::factory()->create();
|
||||
$role = Role::where('name', 'Admin')->first();
|
||||
|
||||
$birthdate = now()->subYears(25)->format('Y-m-d');
|
||||
$hireDate = now()->subMonths(6)->format('Y-m-d');
|
||||
|
||||
mountEditComponent($this->user, $employeeUser)
|
||||
->set('form.address', null)
|
||||
->set('form.full_name', $employeeUser->employee->full_name)
|
||||
->set('form.username', $employeeUser->username)
|
||||
->set('form.email', $employeeUser->email)
|
||||
->set('form.phone_number', $employeeUser->employee->phone_number)
|
||||
->set('form.base_salary', '5.000.000')
|
||||
->set('form.birthdate', $birthdate)
|
||||
->set('form.hire_date', $hireDate)
|
||||
->set('form.gender', $employeeUser->employee->gender->value)
|
||||
->set('form.status', UserStatus::ACTIVE->value)
|
||||
->set('form.outlet_ids', [$outlet->id])
|
||||
->set('form.role_ids', [$role->id])
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$employeeUser->refresh();
|
||||
$employeeUser->load('employee');
|
||||
|
||||
expect($employeeUser->employee->address)->toBeNull();
|
||||
});
|
||||
|
||||
@ -3,66 +3,403 @@
|
||||
use App\Enums\UserStatus;
|
||||
use App\Livewire\Studio\Master\User\Index;
|
||||
use App\Models\Employee;
|
||||
use App\Models\ReferralCode;
|
||||
use App\Models\Outlet;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
$this->user = User::factory()->create();
|
||||
$roles = collect(['Developer', 'Owner', 'Leader', 'Admin', 'Partner', 'Customer'])
|
||||
->map(fn ($role) => Role::create(['name' => $role]));
|
||||
|
||||
$this->user = User::factory()
|
||||
->active()
|
||||
->has(Employee::factory())
|
||||
->create();
|
||||
|
||||
$this->user->roles()->attach($roles->pluck('id'));
|
||||
});
|
||||
|
||||
it('renders user index page successfully', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
function createIndexTestUser(array $userAttributes = [], array $employeeAttributes = [])
|
||||
{
|
||||
$factory = User::factory();
|
||||
|
||||
if (! isset($userAttributes['status'])) {
|
||||
$factory = $factory->active();
|
||||
unset($userAttributes['status']);
|
||||
}
|
||||
|
||||
if (! empty($userAttributes)) {
|
||||
$factory = $factory->state($userAttributes);
|
||||
}
|
||||
|
||||
return $factory
|
||||
->has(Employee::factory()->state($employeeAttributes))
|
||||
->create();
|
||||
}
|
||||
|
||||
function mountIndexComponent(User $user)
|
||||
{
|
||||
return Livewire::actingAs($user)->test(Index::class);
|
||||
}
|
||||
|
||||
it('renders page successfully', function () {
|
||||
mountIndexComponent($this->user)
|
||||
->assertViewIs('livewire.studio.master.user.index')
|
||||
->assertViewHas('pageTitle', 'Pegawai');
|
||||
});
|
||||
|
||||
it('mounts employees correctly', function () {
|
||||
$userWithEmployee = User::factory()
|
||||
->has(Employee::factory())
|
||||
->has(ReferralCode::factory())
|
||||
->create();
|
||||
$employee = createIndexTestUser();
|
||||
$employee->assignRole('Admin');
|
||||
|
||||
$employee = $userWithEmployee->employee;
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->assertSee($employee->full_name)
|
||||
->assertSet('employees.0.full_name', $employee->full_name)
|
||||
->assertSet('employees.0.user.id', $userWithEmployee->id)
|
||||
->assertSet('employees.0.referral_code', $userWithEmployee?->referralCode?->code);
|
||||
mountIndexComponent($this->user)
|
||||
->assertViewHas('employees', function ($employees) use ($employee) {
|
||||
return collect($employees)->contains(
|
||||
fn ($e) => $e['full_name'] === $employee->employee->full_name &&
|
||||
$e['code'] === $employee->employee->code
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('filters employees by status', function () {
|
||||
$activeUser = User::factory()->create(['status' => UserStatus::ACTIVE->value]);
|
||||
$inactiveUser = User::factory()->create(['status' => UserStatus::INACTIVE->value]);
|
||||
it('loads employee data with all required fields', function () {
|
||||
$outlet = Outlet::factory()->create();
|
||||
$user = createIndexTestUser();
|
||||
$user->assignRole('Admin');
|
||||
$user->outlets()->attach($outlet->id);
|
||||
$user->referralCode()->create(['code' => 'REF123']);
|
||||
|
||||
$activeUser->employee()->save(Employee::factory()->make());
|
||||
$inactiveUser->employee()->save(Employee::factory()->make());
|
||||
$component = mountIndexComponent($this->user);
|
||||
$employeeData = collect($component->get('employees'))->first(
|
||||
fn ($e) => $e['full_name'] === $user->employee->full_name
|
||||
);
|
||||
|
||||
$component = Livewire::actingAs($this->user)
|
||||
->test(Index::class);
|
||||
expect($employeeData)->toHaveKeys([
|
||||
'full_name',
|
||||
'code',
|
||||
'phone_number',
|
||||
'address',
|
||||
'base_salary',
|
||||
'gender',
|
||||
'birthdate',
|
||||
'birth_age',
|
||||
'hire_date',
|
||||
'hire_ago',
|
||||
'resign_date',
|
||||
'resign_ago',
|
||||
'user',
|
||||
'referral_code',
|
||||
'outlets',
|
||||
'roles',
|
||||
]);
|
||||
|
||||
expect($employeeData['user'])->toHaveKeys(['id', 'hash', 'email', 'username', 'status']);
|
||||
expect($employeeData['gender'])->toHaveKeys(['label', 'color']);
|
||||
expect($employeeData['user']['status'])->toHaveKeys(['gradient']);
|
||||
});
|
||||
|
||||
it('excludes developer users from listing', function () {
|
||||
$developer = createIndexTestUser();
|
||||
$developer->assignRole('Developer');
|
||||
|
||||
$admin = createIndexTestUser();
|
||||
$admin->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$employeeNames = collect($component->get('employees'))->pluck('full_name')->toArray();
|
||||
|
||||
expect($employeeNames)->not->toContain($developer->employee->full_name);
|
||||
expect($employeeNames)->toContain($admin->employee->full_name);
|
||||
});
|
||||
|
||||
it('displays all employees', function () {
|
||||
$employees = [];
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$user = createIndexTestUser();
|
||||
$user->assignRole('Admin');
|
||||
$employees[] = $user;
|
||||
}
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
$employeeCount = count($component->get('employees'));
|
||||
|
||||
expect($employeeCount)->toBeGreaterThanOrEqual(5);
|
||||
});
|
||||
|
||||
it('filters employees by search query - full name', function () {
|
||||
$user1 = createIndexTestUser([], ['full_name' => 'John Doe']);
|
||||
$user1->assignRole('Admin');
|
||||
|
||||
$user2 = createIndexTestUser([], ['full_name' => 'Jane Smith']);
|
||||
$user2->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
expect(count($component->get('employees')))->toBeGreaterThanOrEqual(2);
|
||||
|
||||
$component->set('search', 'John')
|
||||
->assertSet('search', 'John');
|
||||
|
||||
$employees = $component->get('employees');
|
||||
expect(count($employees))->toBeGreaterThanOrEqual(1);
|
||||
expect($employees[0]['full_name'])->toBe('John Doe');
|
||||
});
|
||||
|
||||
it('filters employees by search query - employee code', function () {
|
||||
$user1 = createIndexTestUser([], ['code' => 'EMP20240001']);
|
||||
$user1->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$component->set('search', 'EMP20240001');
|
||||
|
||||
$employees = $component->get('employees');
|
||||
expect(collect($employees)->pluck('code'))->toContain('EMP20240001');
|
||||
});
|
||||
|
||||
it('filters employees by search query - email', function () {
|
||||
$user1 = createIndexTestUser(['email' => 'john@example.com']);
|
||||
$user1->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$component->set('search', 'john@example.com');
|
||||
|
||||
$employees = $component->get('employees');
|
||||
expect(collect($employees)->pluck('user.email'))->toContain('john@example.com');
|
||||
});
|
||||
|
||||
it('filters employees by search query - username', function () {
|
||||
$user1 = createIndexTestUser(['username' => 'johndoe']);
|
||||
$user1->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$component->set('search', 'johndoe');
|
||||
|
||||
$employees = $component->get('employees');
|
||||
expect(collect($employees)->pluck('user.username'))->toContain('johndoe');
|
||||
});
|
||||
|
||||
it('filters employees by status - active', function () {
|
||||
$activeUser = createIndexTestUser(['status' => UserStatus::ACTIVE]);
|
||||
$activeUser->assignRole('Admin');
|
||||
|
||||
$inactiveUser = createIndexTestUser(['status' => UserStatus::INACTIVE]);
|
||||
$inactiveUser->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
expect(count($component->get('employees')))->toBeGreaterThanOrEqual(2);
|
||||
|
||||
$component->set('status', [UserStatus::ACTIVE->value]);
|
||||
|
||||
$employees = $component->employees;
|
||||
expect(count($employees))->toBe(1);
|
||||
expect($employees[0]['user']['id'])->toBe($activeUser->id);
|
||||
$employees = $component->get('employees');
|
||||
$activeEmployees = collect($employees)->filter(
|
||||
fn ($e) => $e['user']['status']['gradient'] === (UserStatus::ACTIVE->gradient())
|
||||
);
|
||||
|
||||
expect(count($activeEmployees))->toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it('deletes a user successfully', function () {
|
||||
$userToDelete = User::factory()
|
||||
->has(Employee::factory())
|
||||
->create();
|
||||
it('filters employees by status - inactive', function () {
|
||||
$activeUser = createIndexTestUser(['status' => UserStatus::ACTIVE]);
|
||||
$activeUser->assignRole('Admin');
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->call('delete', $userToDelete)
|
||||
$inactiveUser = createIndexTestUser(['status' => UserStatus::INACTIVE]);
|
||||
$inactiveUser->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$component->set('status', [UserStatus::INACTIVE->value]);
|
||||
|
||||
$employees = $component->get('employees');
|
||||
$inactiveEmployees = collect($employees)->filter(
|
||||
fn ($e) => $e['user']['status']['gradient'] === (UserStatus::INACTIVE->gradient())
|
||||
);
|
||||
|
||||
expect(count($inactiveEmployees))->toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it('filters employees by multiple statuses', function () {
|
||||
$activeUser = createIndexTestUser(['status' => UserStatus::ACTIVE]);
|
||||
$activeUser->assignRole('Admin');
|
||||
|
||||
$inactiveUser = createIndexTestUser(['status' => UserStatus::INACTIVE]);
|
||||
$inactiveUser->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$component->set('status', [
|
||||
UserStatus::ACTIVE->value,
|
||||
UserStatus::INACTIVE->value,
|
||||
]);
|
||||
|
||||
expect(count($component->get('employees')))->toBeGreaterThanOrEqual(2);
|
||||
});
|
||||
|
||||
it('filters employees by both search and status', function () {
|
||||
$activeUser = createIndexTestUser(
|
||||
['status' => UserStatus::ACTIVE],
|
||||
['full_name' => 'Active User']
|
||||
);
|
||||
$activeUser->assignRole('Admin');
|
||||
|
||||
$inactiveUser = createIndexTestUser(
|
||||
['status' => UserStatus::INACTIVE],
|
||||
['full_name' => 'Inactive User']
|
||||
);
|
||||
$inactiveUser->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user)
|
||||
->set('search', 'Active')
|
||||
->set('status', [UserStatus::ACTIVE->value]);
|
||||
|
||||
$employees = $component->get('employees');
|
||||
expect(count($employees))->toBeGreaterThanOrEqual(1);
|
||||
expect($employees[0]['full_name'])->toBe('Active User');
|
||||
});
|
||||
|
||||
it('loads employees ordered by latest', function () {
|
||||
$user1 = createIndexTestUser([], ['full_name' => 'First Employee']);
|
||||
$user1->assignRole('Admin');
|
||||
|
||||
sleep(1);
|
||||
|
||||
$user2 = createIndexTestUser([], ['full_name' => 'Second Employee']);
|
||||
$user2->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$employees = $component->get('employees');
|
||||
$firstEmployee = collect($employees)->first(fn ($e) => $e['full_name'] === 'Second Employee');
|
||||
$secondEmployee = collect($employees)->first(fn ($e) => $e['full_name'] === 'First Employee');
|
||||
|
||||
expect($firstEmployee)->not->toBeNull();
|
||||
expect($secondEmployee)->not->toBeNull();
|
||||
|
||||
// The second employee should appear before the first
|
||||
$firstIndex = array_search('Second Employee', array_column($employees, 'full_name'));
|
||||
$secondIndex = array_search('First Employee', array_column($employees, 'full_name'));
|
||||
|
||||
expect($firstIndex)->toBeLessThan($secondIndex);
|
||||
});
|
||||
|
||||
it('loads employee with outlets', function () {
|
||||
$outlet1 = Outlet::factory()->create(['name' => 'Outlet A']);
|
||||
$outlet2 = Outlet::factory()->create(['name' => 'Outlet B']);
|
||||
|
||||
$user = createIndexTestUser();
|
||||
$user->assignRole('Admin');
|
||||
$user->outlets()->attach([$outlet1->id, $outlet2->id]);
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$employeeData = collect($component->get('employees'))->first(
|
||||
fn ($e) => $e['full_name'] === $user->employee->full_name
|
||||
);
|
||||
|
||||
expect($employeeData['outlets'])->toContain('Outlet A', 'Outlet B');
|
||||
});
|
||||
|
||||
it('loads employee with roles', function () {
|
||||
$user = createIndexTestUser();
|
||||
$user->assignRole(['Admin', 'Leader']);
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$employeeData = collect($component->get('employees'))->first(
|
||||
fn ($e) => $e['full_name'] === $user->employee->full_name
|
||||
);
|
||||
|
||||
expect($employeeData['roles'])->toContain('Admin', 'Leader');
|
||||
});
|
||||
|
||||
it('loads employee with referral code', function () {
|
||||
$user = createIndexTestUser();
|
||||
$user->assignRole('Admin');
|
||||
$user->referralCode()->create(['code' => 'REF12345']);
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$employeeData = collect($component->get('employees'))->first(
|
||||
fn ($e) => $e['full_name'] === $user->employee->full_name
|
||||
);
|
||||
|
||||
expect($employeeData['referral_code'])->toBe('REF12345');
|
||||
});
|
||||
|
||||
it('deletes an employee successfully', function () {
|
||||
$employeeUser = createIndexTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
mountIndexComponent($this->user)
|
||||
->call('delete', $employeeUser)
|
||||
->assertHasNoErrors();
|
||||
|
||||
$this->assertSoftDeleted('users', ['id' => $userToDelete->id]);
|
||||
$this->assertSoftDeleted('users', ['id' => $employeeUser->id]);
|
||||
$this->assertSoftDeleted('employees', ['user_id' => $employeeUser->id]);
|
||||
});
|
||||
|
||||
it('reloads employees after deletion', function () {
|
||||
$employeeUser = createIndexTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
$initialCount = count($component->get('employees'));
|
||||
|
||||
$component->call('delete', $employeeUser);
|
||||
|
||||
expect(count($component->get('employees')))->toBeLessThan($initialCount);
|
||||
});
|
||||
|
||||
it('resets password successfully', function () {
|
||||
$defaultPassword = config('myconfig.password_default');
|
||||
$employeeUser = createIndexTestUser();
|
||||
$employeeUser->assignRole('Admin');
|
||||
$employeeUser->update(['password' => Hash::make('oldpassword')]);
|
||||
|
||||
$oldPasswordHash = $employeeUser->password;
|
||||
|
||||
mountIndexComponent($this->user)
|
||||
->call('resetPassword', $employeeUser)
|
||||
->assertHasNoErrors();
|
||||
|
||||
$employeeUser->refresh();
|
||||
|
||||
expect($employeeUser->password)->not->toBe($oldPasswordHash);
|
||||
expect(Hash::check($defaultPassword, $employeeUser->password))->toBeTrue();
|
||||
});
|
||||
|
||||
it('does not display delete and edit buttons for current authenticated user', function () {
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$component
|
||||
->assertDontSee('Delete')
|
||||
->assertDontSee('Edit');
|
||||
});
|
||||
|
||||
it('updates search with debounce', function () {
|
||||
$user1 = createIndexTestUser([], ['full_name' => 'John Doe']);
|
||||
$user1->assignRole('Admin');
|
||||
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$component->set('search', 'John');
|
||||
|
||||
expect($component->get('search'))->toBe('John');
|
||||
});
|
||||
|
||||
it('updates status filter correctly', function () {
|
||||
$component = mountIndexComponent($this->user);
|
||||
|
||||
$component->set('status', ['active']);
|
||||
|
||||
expect($component->get('status'))->toBeArray();
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user