fix(user): kolom email dan username di table dijadikan 1 kolom yaitu Kredensial
-menyesuaikan validasi base_salary dan menghapus toDateString() -menambahkan dispatch refreshDatatabse saat create -membuat EmployeeFactory -menyesuaikan UserFactory dan test
This commit is contained in:
parent
45b67c3ce4
commit
f8935a1c73
@ -39,12 +39,24 @@ public function columns(): array
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
->html(),
|
->html(),
|
||||||
|
|
||||||
|
Column::make('Kredensial')
|
||||||
|
->label(function ($row) {
|
||||||
|
return <<<HTML
|
||||||
|
<div>
|
||||||
|
<div>{$row->email}</div>
|
||||||
|
<span class="text-xs text-gray-400">{$row->username}</span>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
})
|
||||||
|
->searchable(function ($query, $searchTerm) {
|
||||||
|
$query->where('email', 'like', "%{$searchTerm}%")
|
||||||
|
->orWhere('username', 'like', "%{$searchTerm}%");
|
||||||
|
})
|
||||||
|
->html(),
|
||||||
|
|
||||||
Column::make('Nomor Telepon', 'employee.phone_number')->searchable(),
|
Column::make('Nomor Telepon', 'employee.phone_number')->searchable(),
|
||||||
|
|
||||||
Column::make('Email', 'email')->searchable(),
|
|
||||||
|
|
||||||
Column::make('Nama Pengguna', 'username')->searchable(),
|
|
||||||
|
|
||||||
Column::make('Jenis Kelamin', 'employee.gender')
|
Column::make('Jenis Kelamin', 'employee.gender')
|
||||||
->format(fn ($value) => Blade::render(
|
->format(fn ($value) => Blade::render(
|
||||||
'<flux:badge color="'.Gender::from($value)->color().'">'
|
'<flux:badge color="'.Gender::from($value)->color().'">'
|
||||||
@ -56,7 +68,7 @@ public function columns(): array
|
|||||||
Column::make('Gaji Pokok', 'employee.base_salary')
|
Column::make('Gaji Pokok', 'employee.base_salary')
|
||||||
->searchable()
|
->searchable()
|
||||||
->sortable()
|
->sortable()
|
||||||
->format(fn ($value) => currency($value)),
|
->format(fn ($value) => currency($value, 'Rp')),
|
||||||
|
|
||||||
Column::make('Alamat', 'employee.address')->searchable(),
|
Column::make('Alamat', 'employee.address')->searchable(),
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
use App\Models\Employee;
|
use App\Models\Employee;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Rules\PhoneNumber;
|
use App\Rules\PhoneNumber;
|
||||||
|
use App\Rules\UnsignedInteger;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@ -44,7 +45,7 @@ public function rules(): array
|
|||||||
'username' => ['required', 'alpha_dash', 'min:5', 'max:20', Rule::unique('users', 'username')->ignore($this->user)],
|
'username' => ['required', 'alpha_dash', 'min:5', 'max:20', Rule::unique('users', 'username')->ignore($this->user)],
|
||||||
'email' => ['required', 'email', 'max:100', Rule::unique('users', 'email')->ignore($this->user)],
|
'email' => ['required', 'email', 'max:100', Rule::unique('users', 'email')->ignore($this->user)],
|
||||||
'phone_number' => ['required', 'string', new PhoneNumber],
|
'phone_number' => ['required', 'string', new PhoneNumber],
|
||||||
'base_salary' => ['required', 'regex:/^[0-9.]+$/', 'max:999999999'],
|
'base_salary' => ['required', 'regex:/^[0-9.]+$/', new UnsignedInteger],
|
||||||
'birthdate' => ['required', 'date', 'before:'.Carbon::now()->subYears(18)->format('Y-m-d')],
|
'birthdate' => ['required', 'date', 'before:'.Carbon::now()->subYears(18)->format('Y-m-d')],
|
||||||
'hire_date' => ['required', 'date'],
|
'hire_date' => ['required', 'date'],
|
||||||
'address' => ['required', 'string'],
|
'address' => ['required', 'string'],
|
||||||
@ -77,8 +78,8 @@ public function setUser(User $user)
|
|||||||
$this->email = $user->email;
|
$this->email = $user->email;
|
||||||
$this->phone_number = $employee->phone_number;
|
$this->phone_number = $employee->phone_number;
|
||||||
$this->base_salary = $employee->base_salary;
|
$this->base_salary = $employee->base_salary;
|
||||||
$this->birthdate = $employee->birthdate->toDateString();
|
$this->birthdate = $employee->birthdate;
|
||||||
$this->hire_date = $employee->hire_date->toDateString();
|
$this->hire_date = $employee->hire_date;
|
||||||
$this->address = $employee->address;
|
$this->address = $employee->address;
|
||||||
$this->gender = $employee->gender->value;
|
$this->gender = $employee->gender->value;
|
||||||
$this->status = $user->status->value;
|
$this->status = $user->status->value;
|
||||||
|
|||||||
@ -19,6 +19,8 @@ public function save()
|
|||||||
{
|
{
|
||||||
$this->form->store();
|
$this->form->store();
|
||||||
|
|
||||||
|
$this->dispatch('refreshDatatable');
|
||||||
|
|
||||||
Flux::toast(
|
Flux::toast(
|
||||||
heading: 'Berhasil',
|
heading: 'Berhasil',
|
||||||
text: 'Pegawai berhasil ditambahkan.',
|
text: 'Pegawai berhasil ditambahkan.',
|
||||||
|
|||||||
31
database/factories/EmployeeFactory.php
Normal file
31
database/factories/EmployeeFactory.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Enums\EmploymentStatus;
|
||||||
|
use App\Enums\Gender;
|
||||||
|
use App\Models\Employee;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
class EmployeeFactory extends Factory
|
||||||
|
{
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'full_name' => $this->faker->name(),
|
||||||
|
'code' => Employee::generateEmployeeCode(),
|
||||||
|
'phone_number' => fake()->randomElement([
|
||||||
|
fake()->numerify('0812 #### ###'),
|
||||||
|
fake()->numerify('0812 #### ####'),
|
||||||
|
fake()->numerify('0812 #### #####'),
|
||||||
|
]),
|
||||||
|
'base_salary' => $this->faker->randomNumber(6),
|
||||||
|
'gender' => $this->faker->randomElement(Gender::cases()),
|
||||||
|
'address' => $this->faker->address(),
|
||||||
|
'birthdate' => $this->faker->dateTimeBetween('-60 years', '-18 years')->format('Y-m-d'),
|
||||||
|
'hire_date' => $this->faker->date(),
|
||||||
|
'resign_date' => $this->faker->optional()->date(),
|
||||||
|
'status' => $this->faker->randomElement(EmploymentStatus::cases()),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,43 +2,19 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Enums\UserStatus;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
|
||||||
*/
|
|
||||||
class UserFactory extends Factory
|
class UserFactory extends Factory
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The current password being used by the factory.
|
|
||||||
*/
|
|
||||||
protected static ?string $password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the model's default state.
|
|
||||||
*
|
|
||||||
* @return array<string, mixed>
|
|
||||||
*/
|
|
||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => fake()->name(),
|
'email' => $this->faker->unique()->safeEmail(),
|
||||||
'email' => fake()->unique()->safeEmail(),
|
'username' => fake()->unique()->regexify('[A-Za-z0-9]{8}'),
|
||||||
'email_verified_at' => now(),
|
'password' => Hash::make(config('myconfig.password_default')),
|
||||||
'password' => static::$password ??= Hash::make('password'),
|
'status' => $this->faker->randomElement(UserStatus::cases()),
|
||||||
'remember_token' => Str::random(10),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicate that the model's email address should be unverified.
|
|
||||||
*/
|
|
||||||
public function unverified(): static
|
|
||||||
{
|
|
||||||
return $this->state(fn (array $attributes) => [
|
|
||||||
'email_verified_at' => null,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
45
tests/Feature/Livewire/Studio/Master/User/CreateTest.php
Normal file
45
tests/Feature/Livewire/Studio/Master/User/CreateTest.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Livewire\Studio\Master\User\Create;
|
||||||
|
use App\Livewire\Studio\Master\User\Index;
|
||||||
|
use App\Models\Employee;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Livewire\Livewire;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('renders successfully', function () {
|
||||||
|
Livewire::test(Create::class)
|
||||||
|
->assertViewIs('livewire.studio.master.user.form')
|
||||||
|
->assertViewHas('pageTitle', 'Tambah Pegawai');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can create an user', function () {
|
||||||
|
$user = User::factory()->raw();
|
||||||
|
|
||||||
|
$employee = Employee::factory()->raw();
|
||||||
|
|
||||||
|
$data = array_merge($user, $employee);
|
||||||
|
|
||||||
|
Livewire::test(Create::class)
|
||||||
|
->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']->value)
|
||||||
|
->set('form.status', $data['status']->value)
|
||||||
|
->call('save')
|
||||||
|
->assertHasNoErrors()
|
||||||
|
->assertDispatched('refreshDatatable')
|
||||||
|
->assertRedirect(Index::class);
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('users', [
|
||||||
|
'email' => $data['email'],
|
||||||
|
'username' => $data['username'],
|
||||||
|
]);
|
||||||
|
});
|
||||||
53
tests/Feature/Livewire/Studio/Master/User/EditTest.php
Normal file
53
tests/Feature/Livewire/Studio/Master/User/EditTest.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Livewire\Studio\Master\User\Edit;
|
||||||
|
use App\Livewire\Studio\Master\User\Index;
|
||||||
|
use App\Models\Employee;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Livewire\Livewire;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('renders successfully', function () {
|
||||||
|
$user = User::factory()
|
||||||
|
->has(Employee::factory())
|
||||||
|
->create();
|
||||||
|
|
||||||
|
Livewire::test(Edit::class, ['user' => $user])
|
||||||
|
->assertViewIs('livewire.studio.master.user.form')
|
||||||
|
->assertViewHas('pageTitle', 'Ubah Pegawai');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can update an user', function () {
|
||||||
|
$existingUser = User::factory()
|
||||||
|
->has(Employee::factory())
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$user = User::factory()->raw();
|
||||||
|
$employee = Employee::factory()->raw();
|
||||||
|
|
||||||
|
$data = array_merge($user, $employee);
|
||||||
|
|
||||||
|
Livewire::test(Edit::class, ['user' => $existingUser])
|
||||||
|
->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']->value)
|
||||||
|
->set('form.status', $data['status']->value)
|
||||||
|
->call('save')
|
||||||
|
->assertHasNoErrors()
|
||||||
|
->assertDispatched('refreshDatatable')
|
||||||
|
->assertRedirect(Index::class);
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('users', [
|
||||||
|
'id' => $existingUser->id,
|
||||||
|
'email' => $data['email'],
|
||||||
|
'username' => $data['username'],
|
||||||
|
]);
|
||||||
|
});
|
||||||
38
tests/Feature/Livewire/Studio/Master/User/IndexTest.php
Normal file
38
tests/Feature/Livewire/Studio/Master/User/IndexTest.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Livewire\Studio\Master\User\Index;
|
||||||
|
use App\Models\Employee;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Livewire\Livewire;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('renders successfully', function () {
|
||||||
|
Livewire::test(Index::class)
|
||||||
|
->assertViewIs('livewire.studio.master.user.index')
|
||||||
|
->assertViewHas('pageTitle', 'Pegawai');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('displays all users', function () {
|
||||||
|
User::factory()
|
||||||
|
->count(10)
|
||||||
|
->has(Employee::factory())
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$user = User::first();
|
||||||
|
|
||||||
|
Livewire::test(Index::class)->assertSee($user->email);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can delete an user', function () {
|
||||||
|
$user = User::factory()
|
||||||
|
->has(Employee::factory())
|
||||||
|
->create();
|
||||||
|
|
||||||
|
Livewire::test(Index::class)
|
||||||
|
->call('delete', $user)
|
||||||
|
->assertDispatched('refreshDatatable');
|
||||||
|
|
||||||
|
expect(User::count())->toBe(0);
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user