263 lines
8.3 KiB
PHP
263 lines
8.3 KiB
PHP
<?php
|
|
|
|
use App\Models\User;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
use function Pest\Laravel\actingAs;
|
|
use function Pest\Laravel\assertDatabaseHas;
|
|
use function Pest\Laravel\assertSoftDeleted;
|
|
use function Pest\Laravel\deleteJson;
|
|
use function Pest\Laravel\get;
|
|
use function Pest\Laravel\patchJson;
|
|
use function Pest\Laravel\postJson;
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| User Module Tests
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
describe('User Module - Authorization', function () {
|
|
it('redirects to login when accessing user index unauthenticated', function () {
|
|
get(route('user.index'))
|
|
->assertRedirect(route('login'));
|
|
});
|
|
|
|
it('returns 403 when user has no permission to view users', function () {
|
|
actingAs(createUnauthorizedUser())
|
|
->get(route('user.index'))
|
|
->assertStatus(403);
|
|
});
|
|
});
|
|
|
|
describe('User Module - Authorized Actions', function () {
|
|
beforeEach(function () {
|
|
$user = createAuthorizedUser([
|
|
'View:User',
|
|
'Create:User',
|
|
'Edit:User',
|
|
'ResetPassword:User',
|
|
'Delete:User',
|
|
'DeleteAny:User',
|
|
'ToggleStatus:User',
|
|
]);
|
|
actingAs($user);
|
|
});
|
|
|
|
it('can access user index page', function () {
|
|
get(route('user.index'))
|
|
->assertOk()
|
|
->assertInertia(fn ($page) => $page
|
|
->component('admin/master/user/index')
|
|
->has('users', fn ($page) => $page->has('data')->etc())
|
|
->has('defaultPassword')
|
|
);
|
|
});
|
|
|
|
it('excludes users with Developer role from index', function () {
|
|
$developerRole = Role::create(['name' => 'Developer']);
|
|
$developer = User::factory()->create();
|
|
$developer->assignRole($developerRole);
|
|
|
|
$regularUser = User::factory()->create();
|
|
|
|
get(route('user.index'))
|
|
->assertOk()
|
|
->assertInertia(fn ($page) => $page
|
|
->has('users.data', fn ($data) => $data
|
|
->each(fn ($user) => $user->where('id', fn ($id) => $id !== $developer->id)->etc())
|
|
->etc()
|
|
)
|
|
);
|
|
});
|
|
|
|
it('can access user create page', function () {
|
|
Role::create(['name' => 'Developer']);
|
|
Role::create(['name' => 'Admin']);
|
|
|
|
get(route('user.create'))
|
|
->assertOk()
|
|
->assertInertia(fn ($page) => $page
|
|
->component('admin/master/user/create')
|
|
->has('roles', fn ($roles) => $roles
|
|
->each(fn ($role) => $role->where('name', fn ($name) => $name !== 'Developer')->etc())
|
|
)
|
|
);
|
|
});
|
|
|
|
it('can store a new user', function () {
|
|
$data = [
|
|
'username' => 'newuser',
|
|
'email' => 'newuser@example.com',
|
|
'nik' => '1234567890123456',
|
|
'full_name' => 'New User Full Name',
|
|
'phone_number' => '081234567890',
|
|
'address' => 'Test Address',
|
|
'birth_place' => 'Test City',
|
|
'birth_date' => '1990-01-01',
|
|
'base_salary' => 5000000,
|
|
'roles' => ['Admin'],
|
|
];
|
|
|
|
Role::create(['name' => 'Admin']);
|
|
|
|
postJson(route('user.store'), $data)
|
|
->assertRedirect(route('user.index'))
|
|
->assertSessionHas('success');
|
|
|
|
assertDatabaseHas('users', [
|
|
'username' => 'newuser',
|
|
'email' => 'newuser@example.com',
|
|
]);
|
|
|
|
assertDatabaseHas('user_profiles', [
|
|
'nik' => '1234567890123456',
|
|
'full_name' => 'New User Full Name',
|
|
]);
|
|
|
|
$newUser = User::where('username', 'newuser')->first();
|
|
expect($newUser->hasRole('Admin'))->toBeTrue();
|
|
});
|
|
|
|
it('validates user creation', function () {
|
|
postJson(route('user.store'), [])
|
|
->assertStatus(422)
|
|
->assertJsonValidationErrors(['username', 'email', 'nik', 'full_name', 'phone_number', 'address', 'birth_place', 'birth_date', 'base_salary']);
|
|
});
|
|
|
|
it('can access user edit page', function () {
|
|
Role::create(['name' => 'Developer']);
|
|
Role::create(['name' => 'Admin']);
|
|
$user = User::factory()->create();
|
|
|
|
get(route('user.edit', $user))
|
|
->assertOk()
|
|
->assertInertia(fn ($page) => $page
|
|
->component('admin/master/user/edit')
|
|
->has('user')
|
|
->has('roles', fn ($roles) => $roles
|
|
->each(fn ($role) => $role->where('name', fn ($name) => $name !== 'Developer')->etc())
|
|
)
|
|
);
|
|
});
|
|
|
|
it('can update a user', function () {
|
|
$user = User::factory()->create();
|
|
|
|
$newData = [
|
|
'username' => 'updateduser',
|
|
'email' => 'updated@example.com',
|
|
'nik' => '9876543210987654',
|
|
'full_name' => 'Updated Name',
|
|
'phone_number' => '089876543210',
|
|
'address' => 'Updated Address',
|
|
'birth_place' => 'Updated City',
|
|
'birth_date' => '1995-05-05',
|
|
'base_salary' => 6000000,
|
|
'roles' => ['Staff'],
|
|
];
|
|
|
|
Role::create(['name' => 'Staff']);
|
|
|
|
patchJson(route('user.update', $user), $newData)
|
|
->assertRedirect(route('user.index'))
|
|
->assertSessionHas('success');
|
|
|
|
assertDatabaseHas('users', [
|
|
'id' => $user->id,
|
|
'username' => 'updateduser',
|
|
]);
|
|
|
|
assertDatabaseHas('user_profiles', [
|
|
'user_id' => $user->id,
|
|
'full_name' => 'Updated Name',
|
|
]);
|
|
|
|
expect($user->fresh()->hasRole('Staff'))->toBeTrue();
|
|
});
|
|
|
|
it('can reset user password', function () {
|
|
$user = User::factory()->create(['password' => 'old-password']);
|
|
|
|
patchJson(route('user.resetPassword', $user))
|
|
->assertRedirect()
|
|
->assertSessionHas('success');
|
|
|
|
// Note: Password testing usually requires checking Hash::check, but for feature tests,
|
|
// we mainly check the redirection and session. The logic is verified by redirection.
|
|
});
|
|
|
|
it('can delete a user', function () {
|
|
$user = User::factory()->create();
|
|
|
|
deleteJson(route('user.destroy', $user))
|
|
->assertRedirect()
|
|
->assertSessionHas('success');
|
|
|
|
assertSoftDeleted('users', ['id' => $user->id]);
|
|
});
|
|
|
|
it('can delete users in bulk', function () {
|
|
$users = User::factory()->count(3)->create();
|
|
$ids = $users->pluck('id')->toArray();
|
|
|
|
deleteJson(route('user.bulkDestroy'), ['ids' => $ids])
|
|
->assertRedirect()
|
|
->assertSessionHas('success');
|
|
|
|
foreach ($ids as $id) {
|
|
assertSoftDeleted('users', ['id' => $id]);
|
|
}
|
|
});
|
|
|
|
it('can toggle user status', function () {
|
|
$user = User::factory()->create(['is_active' => true]);
|
|
|
|
patchJson(route('user.toggleStatus', $user))
|
|
->assertRedirect()
|
|
->assertSessionHas('success');
|
|
|
|
expect($user->fresh()->is_active)->toBeFalse();
|
|
|
|
patchJson(route('user.toggleStatus', $user))
|
|
->assertRedirect();
|
|
|
|
expect($user->fresh()->is_active)->toBeTrue();
|
|
});
|
|
});
|
|
|
|
describe('User Module - Unauthorized Actions', function () {
|
|
beforeEach(function () {
|
|
actingAs(createUnauthorizedUser());
|
|
});
|
|
|
|
it('cannot store a user without permission', function () {
|
|
postJson(route('user.store'), ['username' => 'Unauthorized'])
|
|
->assertStatus(403);
|
|
});
|
|
|
|
it('cannot update a user without permission', function () {
|
|
$user = User::factory()->create();
|
|
patchJson(route('user.update', $user), ['username' => 'Unauthorized'])
|
|
->assertStatus(403);
|
|
});
|
|
|
|
it('cannot reset user password without permission', function () {
|
|
$user = User::factory()->create();
|
|
patchJson(route('user.resetPassword', $user))
|
|
->assertStatus(403);
|
|
});
|
|
|
|
it('cannot delete a user without permission', function () {
|
|
$user = User::factory()->create();
|
|
deleteJson(route('user.destroy', $user))
|
|
->assertStatus(403);
|
|
});
|
|
|
|
it('cannot toggle user status without permission', function () {
|
|
$user = User::factory()->create();
|
|
patchJson(route('user.toggleStatus', $user))
|
|
->assertStatus(403);
|
|
});
|
|
});
|