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
This commit is contained in:
parent
d365c6c8f8
commit
2b5983fb2a
@ -14,6 +14,7 @@
|
|||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Livewire\Form;
|
use Livewire\Form;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
class UserForm extends Form
|
class UserForm extends Form
|
||||||
{
|
{
|
||||||
@ -35,7 +36,7 @@ class UserForm extends Form
|
|||||||
|
|
||||||
public ?string $address = null;
|
public ?string $address = null;
|
||||||
|
|
||||||
public string $gender = '';
|
public int $gender;
|
||||||
|
|
||||||
public int $status = UserStatus::ACTIVE->value;
|
public int $status = UserStatus::ACTIVE->value;
|
||||||
|
|
||||||
@ -183,7 +184,9 @@ private function createReferralCode(User $user, array $data): void
|
|||||||
private function assignOutletsAndRoles(User $user): void
|
private function assignOutletsAndRoles(User $user): void
|
||||||
{
|
{
|
||||||
$user->outlets()->attach($this->outlet_ids);
|
$user->outlets()->attach($this->outlet_ids);
|
||||||
$user->assignRole(array_map('intval', $this->role_ids));
|
|
||||||
|
$roles = Role::whereIn('id', $this->role_ids)->get();
|
||||||
|
$user->assignRole($roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(): void
|
public function update(): void
|
||||||
@ -225,6 +228,8 @@ private function updateEmployee(array $data): void
|
|||||||
private function syncOutletsAndRoles(): void
|
private function syncOutletsAndRoles(): void
|
||||||
{
|
{
|
||||||
$this->user->outlets()->sync($this->outlet_ids);
|
$this->user->outlets()->sync($this->outlet_ids);
|
||||||
$this->user->syncRoles(array_map('intval', $this->role_ids));
|
|
||||||
|
$roles = Role::whereIn('id', $this->role_ids)->get();
|
||||||
|
$this->user->syncRoles($roles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
use App\Models\Employee;
|
use App\Models\Employee;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Traits\Notification\WithSubscribeNotification;
|
use App\Traits\Notification\WithSubscribeNotification;
|
||||||
|
use App\Traits\WithAuthorization;
|
||||||
use App\Traits\WithConfirmation;
|
use App\Traits\WithConfirmation;
|
||||||
use App\Traits\WithToast;
|
use App\Traits\WithToast;
|
||||||
use Flux\Flux;
|
use Flux\Flux;
|
||||||
@ -17,7 +18,7 @@
|
|||||||
#[Title('Pegawai')]
|
#[Title('Pegawai')]
|
||||||
class Index extends Component
|
class Index extends Component
|
||||||
{
|
{
|
||||||
use WithConfirmation, WithSubscribeNotification, WithToast;
|
use WithAuthorization, WithConfirmation, WithSubscribeNotification, WithToast;
|
||||||
|
|
||||||
/** @var Collection<int, \App\Models\Employee> */
|
/** @var Collection<int, \App\Models\Employee> */
|
||||||
public Collection $employees;
|
public Collection $employees;
|
||||||
@ -60,6 +61,8 @@ public function updatedStatus(): void
|
|||||||
|
|
||||||
public function delete(User $user): void
|
public function delete(User $user): void
|
||||||
{
|
{
|
||||||
|
$this->canOrAbort('delete user');
|
||||||
|
|
||||||
$user->delete();
|
$user->delete();
|
||||||
|
|
||||||
$this->loadEmployees();
|
$this->loadEmployees();
|
||||||
@ -71,6 +74,8 @@ public function delete(User $user): void
|
|||||||
|
|
||||||
public function resetPassword(User $user): void
|
public function resetPassword(User $user): void
|
||||||
{
|
{
|
||||||
|
$this->canOrAbort('reset password user');
|
||||||
|
|
||||||
$user->update(['password' => Hash::make(config('myconfig.password_default'))]);
|
$user->update(['password' => Hash::make(config('myconfig.password_default'))]);
|
||||||
|
|
||||||
$this->toast('Kata sandi pegawai berhasil direset.');
|
$this->toast('Kata sandi pegawai berhasil direset.');
|
||||||
|
|||||||
@ -114,29 +114,37 @@ class="w-4 h-4 text-gray-500 dark:text-white flex-shrink-0 mt-0.5" />
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@if ($employee->user?->outlets?->isNotEmpty())
|
||||||
<div>
|
<div>
|
||||||
<flux:heading class="uppercase font-semibold text-gray-500 dark:text-gray-400 ">Outlet
|
<flux:heading class="uppercase font-semibold text-gray-500 dark:text-gray-400 ">
|
||||||
|
Outlet
|
||||||
</flux:heading>
|
</flux:heading>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2">
|
||||||
@foreach ($employee->user?->outlets as $outlet)
|
@foreach ($employee->user?->outlets as $outlet)
|
||||||
<span class="text-xs text-gray-400 border border-gray-400 rounded px-2 py-1">
|
<span
|
||||||
|
class="text-xs text-gray-400 border border-gray-400 rounded px-2 py-1">
|
||||||
{{ $outlet->name }}
|
{{ $outlet->name }}
|
||||||
</span>
|
</span>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($employee->user?->roles?->isNotEmpty())
|
||||||
<div>
|
<div>
|
||||||
<flux:heading class="uppercase font-semibold text-gray-500 dark:text-gray-400 ">Peran
|
<flux:heading class="uppercase font-semibold text-gray-500 dark:text-gray-400 ">
|
||||||
|
Peran
|
||||||
</flux:heading>
|
</flux:heading>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2">
|
||||||
@foreach ($employee->user?->roles as $role)
|
@foreach ($employee->user?->roles as $role)
|
||||||
<span class="text-xs text-gray-400 border border-gray-400 rounded px-2 py-1">
|
<span
|
||||||
|
class="text-xs text-gray-400 border border-gray-400 rounded px-2 py-1">
|
||||||
{{ $role->name }}
|
{{ $role->name }}
|
||||||
</span>
|
</span>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<flux:heading class="uppercase font-semibold text-gray-500 dark:text-gray-400 ">
|
<flux:heading class="uppercase font-semibold text-gray-500 dark:text-gray-400 ">
|
||||||
@ -221,7 +229,7 @@ class="text-gray-500">({{ timeAgo($employee->resign_date) }})</span>
|
|||||||
'Anda yakin ingin mereset kata sandi pegawai ini menjadi ' . config('myconfig.password_default') . '?',
|
'Anda yakin ingin mereset kata sandi pegawai ini menjadi ' . config('myconfig.password_default') . '?',
|
||||||
'buttonVariant' => 'primary',
|
'buttonVariant' => 'primary',
|
||||||
'buttonColor' => 'reset',
|
'buttonColor' => 'reset',
|
||||||
'buttonText' => 'Ya, Hapus',
|
'buttonText' => 'Ya, Reset',
|
||||||
'target' => 'resetPassword',
|
'target' => 'resetPassword',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ function attemptResetPassword(
|
|||||||
->call('resetPassword');
|
->call('resetPassword');
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockPasswordResetStatus(string $status): void
|
function mockPasswordReset(string $status): void
|
||||||
{
|
{
|
||||||
Password::shouldReceive('reset')
|
Password::shouldReceive('reset')
|
||||||
->once()
|
->once()
|
||||||
@ -85,7 +85,7 @@ function mockPasswordResetStatus(string $status): void
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
it('resets password successfully', function () {
|
it('resets password successfully', function () {
|
||||||
mockPasswordResetStatus(Password::PasswordReset);
|
mockPasswordReset(Password::PasswordReset);
|
||||||
|
|
||||||
attemptResetPassword()
|
attemptResetPassword()
|
||||||
->assertHasNoErrors()
|
->assertHasNoErrors()
|
||||||
@ -95,7 +95,7 @@ function mockPasswordResetStatus(string $status): void
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles failure when resetting password', function () {
|
it('handles failure when resetting password', function () {
|
||||||
mockPasswordResetStatus('passwords.token');
|
mockPasswordReset('passwords.token');
|
||||||
|
|
||||||
attemptResetPassword()
|
attemptResetPassword()
|
||||||
->assertHasNoErrors();
|
->assertHasNoErrors();
|
||||||
|
|||||||
@ -33,7 +33,7 @@ function mountEditComponent(User $user, Voucher $voucher)
|
|||||||
return Livewire::actingAs($user)->test(Edit::class, ['voucher' => $voucher]);
|
return Livewire::actingAs($user)->test(Edit::class, ['voucher' => $voucher]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createOutlets(int $count = 3)
|
function createTestOutlets(int $count = 3)
|
||||||
{
|
{
|
||||||
return Outlet::factory()
|
return Outlet::factory()
|
||||||
->count($count)
|
->count($count)
|
||||||
|
|||||||
@ -408,7 +408,7 @@ function mountCreateComponent(User $user): Testable
|
|||||||
$this->user->givePermissionTo($permission);
|
$this->user->givePermissionTo($permission);
|
||||||
|
|
||||||
mountCreateComponent($this->user)
|
mountCreateComponent($this->user)
|
||||||
->set('form.gender', 'invalid')
|
->set('form.gender', 999) // Invalid enum value
|
||||||
->call('save')
|
->call('save')
|
||||||
->assertHasErrors(['form.gender']);
|
->assertHasErrors(['form.gender']);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -22,6 +22,11 @@
|
|||||||
->create();
|
->create();
|
||||||
|
|
||||||
$this->user->assignRole('Admin'); // Give admin role to test user
|
$this->user->assignRole('Admin'); // Give admin role to test user
|
||||||
|
|
||||||
|
// Give necessary permissions for testing (since Admin role in seeder doesn't have these permissions)
|
||||||
|
\Spatie\Permission\Models\Permission::create(['name' => 'delete user']);
|
||||||
|
\Spatie\Permission\Models\Permission::create(['name' => 'reset password user']);
|
||||||
|
$this->user->givePermissionTo(['delete user', 'reset password user']);
|
||||||
});
|
});
|
||||||
|
|
||||||
function createUser(array $attributes = []): User
|
function createUser(array $attributes = []): User
|
||||||
@ -104,7 +109,7 @@ function mountIndexComponent(User $user): Testable
|
|||||||
|
|
||||||
$component = mountIndexComponent($this->user);
|
$component = mountIndexComponent($this->user);
|
||||||
|
|
||||||
expect(count($component->get('employees')))->toBeGreaterThan(2); // 2 new users + logged in user
|
expect(count($component->get('employees')))->toBeGreaterThanOrEqual(2); // At least 2 new users
|
||||||
|
|
||||||
// Test filtering by username
|
// Test filtering by username
|
||||||
$filteredComponent = mountIndexComponent($this->user)->set('search', 'john_doe');
|
$filteredComponent = mountIndexComponent($this->user)->set('search', 'john_doe');
|
||||||
@ -119,7 +124,7 @@ function mountIndexComponent(User $user): Testable
|
|||||||
|
|
||||||
$component = mountIndexComponent($this->user);
|
$component = mountIndexComponent($this->user);
|
||||||
|
|
||||||
expect(count($component->get('employees')))->toBeGreaterThan(2); // 2 new users + logged in user
|
expect(count($component->get('employees')))->toBeGreaterThanOrEqual(2); // At least 2 new users
|
||||||
|
|
||||||
$filteredComponent = mountIndexComponent($this->user)->set('status', [UserStatus::ACTIVE->value]);
|
$filteredComponent = mountIndexComponent($this->user)->set('status', [UserStatus::ACTIVE->value]);
|
||||||
|
|
||||||
@ -133,7 +138,7 @@ function mountIndexComponent(User $user): Testable
|
|||||||
|
|
||||||
$component = mountIndexComponent($this->user);
|
$component = mountIndexComponent($this->user);
|
||||||
|
|
||||||
expect(count($component->get('employees')))->toBeGreaterThan(2); // 2 new users + logged in user
|
expect(count($component->get('employees')))->toBeGreaterThanOrEqual(2); // At least 2 new users
|
||||||
|
|
||||||
$filteredComponent = mountIndexComponent($this->user)->set('status', [
|
$filteredComponent = mountIndexComponent($this->user)->set('status', [
|
||||||
UserStatus::ACTIVE->value,
|
UserStatus::ACTIVE->value,
|
||||||
@ -204,7 +209,7 @@ function mountIndexComponent(User $user): Testable
|
|||||||
|
|
||||||
$component = mountIndexComponent($this->user)->set('status', []);
|
$component = mountIndexComponent($this->user)->set('status', []);
|
||||||
|
|
||||||
expect(count($component->get('employees')))->toBeGreaterThan(2); // 2 new users + logged in user
|
expect(count($component->get('employees')))->toBeGreaterThanOrEqual(2); // At least 2 new users
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loads employees efficiently with eager loading', function () {
|
it('loads employees efficiently with eager loading', function () {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user