169 lines
6.0 KiB
PHP
169 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\BahagianPilihanraya;
|
|
use App\Models\DaerahMengundi;
|
|
use App\Models\Election;
|
|
use App\Models\Position;
|
|
use App\Models\PositionQuota;
|
|
use App\Models\PusatMengundi;
|
|
use App\Models\SaluranMengundi;
|
|
use App\Models\StaffAssignment;
|
|
use App\Models\User;
|
|
use Database\Seeders\DatabaseSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Tests\TestCase;
|
|
|
|
class AdminSetupTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_admin_can_create_election_hierarchy_records_and_generate_pusat_qr(): void
|
|
{
|
|
Storage::fake('local');
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$admin = User::query()->where('email', 'admin@prn.local')->firstOrFail();
|
|
$election = Election::query()->where('code', 'PRN2026')->firstOrFail();
|
|
|
|
$this->actingAs($admin)
|
|
->post(route('admin.setup.bahagian.store'), [
|
|
'election_id' => $election->id,
|
|
'code' => 'B999',
|
|
'name' => 'Bahagian Ujian',
|
|
])
|
|
->assertRedirect(route('admin.setup.bahagian.index'));
|
|
|
|
$bahagian = BahagianPilihanraya::query()->where('code', 'B999')->firstOrFail();
|
|
|
|
$this->actingAs($admin)
|
|
->post(route('admin.setup.daerah.store'), [
|
|
'election_id' => $election->id,
|
|
'bahagian_pilihanraya_id' => $bahagian->id,
|
|
'code' => 'D999',
|
|
'name' => 'Daerah Ujian',
|
|
])
|
|
->assertRedirect(route('admin.setup.daerah.index'));
|
|
|
|
$daerah = DaerahMengundi::query()->where('code', 'D999')->firstOrFail();
|
|
|
|
$this->actingAs($admin)
|
|
->post(route('admin.setup.pusat.store'), [
|
|
'election_id' => $election->id,
|
|
'daerah_mengundi_id' => $daerah->id,
|
|
'code' => 'PM999',
|
|
'name' => 'SK Ujian',
|
|
'address' => 'Jalan Ujian',
|
|
'saluran_count' => 2,
|
|
'ktm_count' => 1,
|
|
'polis_iring_count' => 1,
|
|
'kp_count' => 4,
|
|
'ppm_count' => 1,
|
|
'kpdp_count' => 1,
|
|
'papm_count' => 3,
|
|
'jkm_count' => 1,
|
|
'kkm_count' => 1,
|
|
'calon_tambahan_count' => 1,
|
|
])
|
|
->assertRedirect(route('admin.setup.pusat.index'));
|
|
|
|
$pusat = PusatMengundi::query()->where('code', 'PM999')->firstOrFail();
|
|
|
|
$this->assertNotNull($pusat->public_uuid);
|
|
$this->assertStringContainsString('/pohon/'.$pusat->public_uuid, (string) $pusat->registration_url);
|
|
$this->assertNotNull($pusat->qr_code_path);
|
|
Storage::disk('local')->assertExists($pusat->qr_code_path);
|
|
|
|
$this->actingAs($admin)
|
|
->post(route('admin.setup.saluran.store'), [
|
|
'election_id' => $election->id,
|
|
'pusat_mengundi_id' => $pusat->id,
|
|
'number' => '3',
|
|
'voter_count' => 500,
|
|
])
|
|
->assertRedirect(route('admin.setup.saluran.index'));
|
|
|
|
$this->assertDatabaseHas('saluran_mengundis', [
|
|
'pusat_mengundi_id' => $pusat->id,
|
|
'number' => '1',
|
|
]);
|
|
}
|
|
|
|
public function test_admin_can_create_position_quota_and_assign_ppm(): void
|
|
{
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$admin = User::query()->where('email', 'admin@prn.local')->firstOrFail();
|
|
$election = Election::query()->where('code', 'PRN2026')->firstOrFail();
|
|
$pusat = PusatMengundi::query()->where('code', 'PM001')->firstOrFail();
|
|
$saluran = SaluranMengundi::query()->where('pusat_mengundi_id', $pusat->id)->firstOrFail();
|
|
$position = Position::query()->where('code', 'KP')->firstOrFail();
|
|
$newPpm = User::factory()->create();
|
|
|
|
$this->actingAs($admin)
|
|
->post(route('admin.setup.quotas.store'), [
|
|
'election_id' => $election->id,
|
|
'pusat_mengundi_id' => $pusat->id,
|
|
'saluran_mengundi_id' => $saluran->id,
|
|
'position_id' => $position->id,
|
|
'quota' => 6,
|
|
])
|
|
->assertRedirect(route('admin.setup.quotas.index'));
|
|
|
|
$quota = PositionQuota::query()
|
|
->where('election_id', $election->id)
|
|
->where('pusat_mengundi_id', $pusat->id)
|
|
->where('saluran_mengundi_id', $saluran->id)
|
|
->where('position_id', $position->id)
|
|
->firstOrFail();
|
|
|
|
$this->assertSame(6, $quota->quota);
|
|
|
|
$this->actingAs($admin)
|
|
->post(route('admin.setup.pusat.assign-ppm', $pusat), [
|
|
'user_id' => $newPpm->id,
|
|
])
|
|
->assertRedirect(route('admin.setup.pusat.show', $pusat));
|
|
|
|
$newPpm->refresh();
|
|
$this->assertTrue($newPpm->hasRole('PPM'));
|
|
|
|
$ppmPosition = Position::query()->where('code', 'PPM')->firstOrFail();
|
|
|
|
$this->assertTrue(StaffAssignment::query()
|
|
->where('election_id', $election->id)
|
|
->where('pusat_mengundi_id', $pusat->id)
|
|
->where('position_id', $ppmPosition->id)
|
|
->where('user_id', $newPpm->id)
|
|
->where('status', 'active')
|
|
->exists());
|
|
}
|
|
|
|
public function test_non_admin_cannot_access_admin_setup_routes(): void
|
|
{
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$ktm = User::query()->where('email', 'ktm@prn.local')->firstOrFail();
|
|
|
|
$this->actingAs($ktm)
|
|
->get(route('admin.setup.index'))
|
|
->assertForbidden();
|
|
}
|
|
|
|
public function test_public_qr_placeholder_uses_public_uuid_without_authentication(): void
|
|
{
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$pusat = PusatMengundi::query()->where('code', 'PM001')->firstOrFail();
|
|
|
|
$this->get(route('public.applications.create', [
|
|
'pusatMengundi' => $pusat->public_uuid,
|
|
]))
|
|
->assertOk()
|
|
->assertSee($pusat->name)
|
|
->assertSee($pusat->code);
|
|
}
|
|
}
|