8476c5d643
- Add AdminUserController: CRUD users, assign role, reset password,
self-delete guard (403 on own account)
- Add admin route group under role:administrator middleware
(GET/POST/PUT/DELETE /api/admin/users, PUT /api/admin/users/{id}/password)
- Add resources/views/admin/users.blade.php: DaisyUI table + 4 modals
(create, edit, reset password, delete confirm), stats grid, toast
- Add Admin nav link (administrator-only) to map and data navbars
- 9 new tests covering page access, API CRUD, self-delete guard, password reset
- Mark Plan 3 complete in missing_features.md; update README page list
- Save plan3 to docs/ for reference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
128 lines
3.8 KiB
PHP
128 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class AdminUserTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
foreach (['administrator', 'pengurus_ibadah', 'petugas_pendataan', 'pemangku_kebijakan'] as $role) {
|
|
\Spatie\Permission\Models\Role::create(['name' => $role, 'guard_name' => 'web']);
|
|
}
|
|
}
|
|
|
|
private function createUser(string $role): User
|
|
{
|
|
$user = User::factory()->create();
|
|
$user->assignRole($role);
|
|
return $user;
|
|
}
|
|
|
|
public function test_admin_users_page_is_accessible(): void
|
|
{
|
|
$admin = $this->createUser('administrator');
|
|
$this->actingAs($admin);
|
|
|
|
$this->get('/admin/users')->assertOk();
|
|
}
|
|
|
|
public function test_non_admin_cannot_access_users_page(): void
|
|
{
|
|
$pengurus = $this->createUser('pengurus_ibadah');
|
|
$this->actingAs($pengurus);
|
|
|
|
$this->get('/admin/users')->assertStatus(403);
|
|
}
|
|
|
|
public function test_admin_can_list_users(): void
|
|
{
|
|
$admin = $this->createUser('administrator');
|
|
$this->actingAs($admin);
|
|
|
|
$this->getJson('/api/admin/users')
|
|
->assertOk()
|
|
->assertJsonFragment(['email' => $admin->email]);
|
|
}
|
|
|
|
public function test_non_admin_cannot_list_users(): void
|
|
{
|
|
$pengurus = $this->createUser('pengurus_ibadah');
|
|
$this->actingAs($pengurus);
|
|
|
|
$this->getJson('/api/admin/users')->assertStatus(403);
|
|
}
|
|
|
|
public function test_admin_can_create_user(): void
|
|
{
|
|
$admin = $this->createUser('administrator');
|
|
$this->actingAs($admin);
|
|
|
|
$this->postJson('/api/admin/users', [
|
|
'name' => 'User Baru',
|
|
'email' => 'userbaru@webgis.local',
|
|
'password' => 'password123',
|
|
'role' => 'petugas_pendataan',
|
|
])->assertOk()->assertJsonFragment(['email' => 'userbaru@webgis.local']);
|
|
|
|
$this->assertDatabaseHas('users', ['email' => 'userbaru@webgis.local']);
|
|
}
|
|
|
|
public function test_admin_can_update_user(): void
|
|
{
|
|
$admin = $this->createUser('administrator');
|
|
$target = $this->createUser('pengurus_ibadah');
|
|
$this->actingAs($admin);
|
|
|
|
$this->putJson("/api/admin/users/{$target->id}", [
|
|
'name' => 'Nama Diubah',
|
|
'email' => $target->email,
|
|
'role' => 'petugas_pendataan',
|
|
])->assertOk()->assertJsonFragment(['name' => 'Nama Diubah']);
|
|
|
|
$this->assertTrue($target->fresh()->hasRole('petugas_pendataan'));
|
|
}
|
|
|
|
public function test_admin_can_delete_other_user(): void
|
|
{
|
|
$admin = $this->createUser('administrator');
|
|
$target = $this->createUser('pengurus_ibadah');
|
|
$this->actingAs($admin);
|
|
|
|
$this->deleteJson("/api/admin/users/{$target->id}")->assertOk();
|
|
$this->assertNull(User::find($target->id));
|
|
}
|
|
|
|
public function test_admin_cannot_delete_self(): void
|
|
{
|
|
$admin = $this->createUser('administrator');
|
|
$this->actingAs($admin);
|
|
|
|
$this->deleteJson("/api/admin/users/{$admin->id}")->assertStatus(403);
|
|
$this->assertNotNull(User::find($admin->id));
|
|
}
|
|
|
|
public function test_admin_can_reset_password(): void
|
|
{
|
|
$admin = $this->createUser('administrator');
|
|
$target = $this->createUser('pengurus_ibadah');
|
|
$this->actingAs($admin);
|
|
|
|
$this->putJson("/api/admin/users/{$target->id}/password", [
|
|
'password' => 'newpassword123',
|
|
'password_confirmation' => 'newpassword123',
|
|
])->assertOk();
|
|
|
|
$this->assertTrue(
|
|
\Illuminate\Support\Facades\Hash::check('newpassword123', $target->fresh()->password)
|
|
);
|
|
}
|
|
}
|