first
This commit is contained in:
246
tests/Feature/PpmApplicationReviewTest.php
Normal file
246
tests/Feature/PpmApplicationReviewTest.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationDocument;
|
||||
use App\Models\DaerahMengundi;
|
||||
use App\Models\Election;
|
||||
use App\Models\Position;
|
||||
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 PpmApplicationReviewTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_ppm_can_view_only_own_pusat_applications_in_list(): void
|
||||
{
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ppm = User::query()->where('email', 'ppm@prn.local')->firstOrFail();
|
||||
$ownPusat = PusatMengundi::query()->where('code', 'PM001')->firstOrFail();
|
||||
$otherPusat = $this->otherPusat();
|
||||
$position = Position::query()->where('code', 'PAPM')->firstOrFail();
|
||||
|
||||
$ownApplication = Application::factory()->create([
|
||||
'election_id' => $ownPusat->election_id,
|
||||
'pusat_mengundi_id' => $ownPusat->id,
|
||||
'requested_position_id' => $position->id,
|
||||
'name' => 'Pemohon Pusat Sendiri',
|
||||
]);
|
||||
|
||||
Application::factory()->create([
|
||||
'election_id' => $otherPusat->election_id,
|
||||
'pusat_mengundi_id' => $otherPusat->id,
|
||||
'requested_position_id' => $position->id,
|
||||
'name' => 'Pemohon Pusat Lain',
|
||||
]);
|
||||
|
||||
$this->actingAs($ppm)
|
||||
->get(route('ppm.applications.index'))
|
||||
->assertOk()
|
||||
->assertSee($ownApplication->name)
|
||||
->assertDontSee('Pemohon Pusat Lain');
|
||||
}
|
||||
|
||||
public function test_ppm_cannot_view_application_outside_own_pusat(): void
|
||||
{
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ppm = User::query()->where('email', 'ppm@prn.local')->firstOrFail();
|
||||
$position = Position::query()->where('code', 'PAPM')->firstOrFail();
|
||||
$otherPusat = $this->otherPusat();
|
||||
|
||||
$application = Application::factory()->create([
|
||||
'election_id' => $otherPusat->election_id,
|
||||
'pusat_mengundi_id' => $otherPusat->id,
|
||||
'requested_position_id' => $position->id,
|
||||
]);
|
||||
|
||||
$this->actingAs($ppm)
|
||||
->get(route('ppm.applications.show', $application->public_uuid))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function test_ppm_cannot_approve_application_without_required_documents(): void
|
||||
{
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ppm = User::query()->where('email', 'ppm@prn.local')->firstOrFail();
|
||||
$pusat = PusatMengundi::query()->where('code', 'PM001')->firstOrFail();
|
||||
$position = Position::query()->where('code', 'PAPM')->firstOrFail();
|
||||
|
||||
$application = Application::factory()->create([
|
||||
'election_id' => $pusat->election_id,
|
||||
'pusat_mengundi_id' => $pusat->id,
|
||||
'requested_position_id' => $position->id,
|
||||
]);
|
||||
|
||||
$this->actingAs($ppm)
|
||||
->post(route('ppm.applications.approve', $application->public_uuid), [
|
||||
'approved_position_code' => 'PAPM',
|
||||
])
|
||||
->assertSessionHasErrors('documents');
|
||||
|
||||
$this->assertDatabaseMissing('staff_assignments', [
|
||||
'application_id' => $application->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_ppm_can_approve_ktm_and_assign_saluran(): void
|
||||
{
|
||||
Storage::fake('local');
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ppm = User::query()->where('email', 'ppm@prn.local')->firstOrFail();
|
||||
$pusat = PusatMengundi::query()->where('code', 'PM001')->firstOrFail();
|
||||
$position = Position::query()->where('code', 'KTM')->firstOrFail();
|
||||
$saluran = SaluranMengundi::query()
|
||||
->where('pusat_mengundi_id', $pusat->id)
|
||||
->where('number', '3')
|
||||
->firstOrFail();
|
||||
$application = $this->applicationWithDocuments($pusat, $position, 'Pemohon KTM');
|
||||
|
||||
$this->actingAs($ppm)
|
||||
->post(route('ppm.applications.approve', $application->public_uuid), [
|
||||
'approved_position_code' => 'KTM',
|
||||
'saluran_mengundi_id' => $saluran->id,
|
||||
'note' => 'Diluluskan untuk Saluran 3.',
|
||||
])
|
||||
->assertRedirect(route('ppm.applications.show', $application->public_uuid));
|
||||
|
||||
$application->refresh();
|
||||
|
||||
$this->assertSame('assigned', $application->status);
|
||||
$this->assertSame($position->id, $application->approved_position_id);
|
||||
$this->assertTrue(StaffAssignment::query()
|
||||
->where('application_id', $application->id)
|
||||
->where('position_id', $position->id)
|
||||
->where('saluran_mengundi_id', $saluran->id)
|
||||
->where('status', 'active')
|
||||
->exists());
|
||||
$this->assertTrue($application->statusHistories()->where('to_status', 'assigned')->exists());
|
||||
}
|
||||
|
||||
public function test_ppm_can_change_role_and_assign_kp_to_approved_ktm(): void
|
||||
{
|
||||
Storage::fake('local');
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ppm = User::query()->where('email', 'ppm@prn.local')->firstOrFail();
|
||||
$pusat = PusatMengundi::query()->where('code', 'PM001')->firstOrFail();
|
||||
$requestedPosition = Position::query()->where('code', 'PAPM')->firstOrFail();
|
||||
$approvedPosition = Position::query()->where('code', 'KP')->firstOrFail();
|
||||
$ktmAssignment = $this->ktmAssignment($pusat);
|
||||
$application = $this->applicationWithDocuments($pusat, $requestedPosition, 'Pemohon Ditukar KP');
|
||||
|
||||
$this->actingAs($ppm)
|
||||
->post(route('ppm.applications.approve', $application->public_uuid), [
|
||||
'approved_position_code' => 'KP',
|
||||
'ktm_assignment_id' => $ktmAssignment->id,
|
||||
'note' => 'Tukar dari PAPM ke KP.',
|
||||
])
|
||||
->assertRedirect(route('ppm.applications.show', $application->public_uuid));
|
||||
|
||||
$application->refresh();
|
||||
|
||||
$this->assertSame('assigned', $application->status);
|
||||
$this->assertSame($approvedPosition->id, $application->approved_position_id);
|
||||
$this->assertSame($ktmAssignment->id, $application->selected_ktm_assignment_id);
|
||||
$this->assertTrue(StaffAssignment::query()
|
||||
->where('application_id', $application->id)
|
||||
->where('position_id', $approvedPosition->id)
|
||||
->where('reports_to_assignment_id', $ktmAssignment->id)
|
||||
->where('status', 'active')
|
||||
->exists());
|
||||
}
|
||||
|
||||
public function test_ppm_can_reject_own_pusat_application(): void
|
||||
{
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ppm = User::query()->where('email', 'ppm@prn.local')->firstOrFail();
|
||||
$pusat = PusatMengundi::query()->where('code', 'PM001')->firstOrFail();
|
||||
$position = Position::query()->where('code', 'PAPM')->firstOrFail();
|
||||
$application = Application::factory()->create([
|
||||
'election_id' => $pusat->election_id,
|
||||
'pusat_mengundi_id' => $pusat->id,
|
||||
'requested_position_id' => $position->id,
|
||||
]);
|
||||
|
||||
$this->actingAs($ppm)
|
||||
->post(route('ppm.applications.reject', $application->public_uuid), [
|
||||
'reason' => 'Tidak memenuhi syarat.',
|
||||
])
|
||||
->assertRedirect(route('ppm.applications.show', $application->public_uuid));
|
||||
|
||||
$application->refresh();
|
||||
|
||||
$this->assertSame('rejected', $application->status);
|
||||
$this->assertSame('Tidak memenuhi syarat.', $application->rejection_reason);
|
||||
$this->assertTrue($application->statusHistories()->where('to_status', 'rejected')->exists());
|
||||
}
|
||||
|
||||
private function otherPusat(): PusatMengundi
|
||||
{
|
||||
$election = Election::query()->where('code', 'PRN2026')->firstOrFail();
|
||||
$daerah = DaerahMengundi::factory()->forElection($election)->create([
|
||||
'code' => 'D999',
|
||||
'name' => 'Daerah Lain',
|
||||
]);
|
||||
|
||||
return PusatMengundi::factory()->create([
|
||||
'election_id' => $election->id,
|
||||
'daerah_mengundi_id' => $daerah->id,
|
||||
'code' => 'PM999',
|
||||
'name' => 'Pusat Lain',
|
||||
]);
|
||||
}
|
||||
|
||||
private function applicationWithDocuments(PusatMengundi $pusatMengundi, Position $position, string $name): Application
|
||||
{
|
||||
$application = Application::factory()->create([
|
||||
'election_id' => $pusatMengundi->election_id,
|
||||
'pusat_mengundi_id' => $pusatMengundi->id,
|
||||
'requested_position_id' => $position->id,
|
||||
'name' => $name,
|
||||
]);
|
||||
|
||||
foreach (['ic_document', 'bank_statement'] as $type) {
|
||||
$path = 'applications/'.$application->public_uuid.'/'.$type.'.pdf';
|
||||
Storage::disk('local')->put($path, 'test');
|
||||
|
||||
ApplicationDocument::query()->create([
|
||||
'application_id' => $application->id,
|
||||
'document_type' => $type,
|
||||
'disk' => 'local',
|
||||
'path' => $path,
|
||||
'original_name' => $type.'.pdf',
|
||||
'mime_type' => 'application/pdf',
|
||||
'size' => 4,
|
||||
]);
|
||||
}
|
||||
|
||||
return $application;
|
||||
}
|
||||
|
||||
private function ktmAssignment(PusatMengundi $pusatMengundi): StaffAssignment
|
||||
{
|
||||
$ktmPosition = Position::query()->where('code', 'KTM')->firstOrFail();
|
||||
|
||||
return StaffAssignment::query()
|
||||
->where('election_id', $pusatMengundi->election_id)
|
||||
->where('pusat_mengundi_id', $pusatMengundi->id)
|
||||
->where('position_id', $ktmPosition->id)
|
||||
->where('status', 'active')
|
||||
->whereNotNull('saluran_mengundi_id')
|
||||
->firstOrFail();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user