first
This commit is contained in:
204
tests/Feature/KtmFlowTest.php
Normal file
204
tests/Feature/KtmFlowTest.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Mail\KtmCreatedApplicantMail;
|
||||
use App\Models\Application;
|
||||
use App\Models\Position;
|
||||
use App\Models\StaffAssignment;
|
||||
use App\Models\User;
|
||||
use Database\Seeders\DatabaseSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
use Tests\TestCase;
|
||||
|
||||
class KtmFlowTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_ktm_can_view_assigned_saluran_and_kp_team(): void
|
||||
{
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ktm = User::query()->where('email', 'ktm@prn.local')->firstOrFail();
|
||||
$assignment = $this->ktmAssignmentFor($ktm);
|
||||
|
||||
$this->actingAs($ktm)
|
||||
->get(route('ktm.applications.index'))
|
||||
->assertOk()
|
||||
->assertSee('Saluran '.$assignment->saluranMengundi?->number)
|
||||
->assertSee('Team KP');
|
||||
}
|
||||
|
||||
public function test_ktm_can_register_kp_only_and_email_applicant(): void
|
||||
{
|
||||
Mail::fake();
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ktm = User::query()->where('email', 'ktm@prn.local')->firstOrFail();
|
||||
$assignment = $this->ktmAssignmentFor($ktm);
|
||||
$kpPosition = Position::query()->where('code', 'KP')->firstOrFail();
|
||||
|
||||
$this->actingAs($ktm)
|
||||
->post(route('ktm.applications.store'), [
|
||||
'ktm_assignment_id' => $assignment->id,
|
||||
'name' => 'KP Didaftar KTM',
|
||||
'ic_number' => '880101101111',
|
||||
'phone_number' => '0123456789',
|
||||
'email' => 'kp-created@example.test',
|
||||
'address' => 'Alamat KP',
|
||||
'requested_position_code' => 'KTM',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$application = Application::query()->where('ic_number', '880101101111')->firstOrFail();
|
||||
|
||||
$this->assertSame('created_by_ktm', $application->source);
|
||||
$this->assertSame('submitted', $application->status);
|
||||
$this->assertSame($kpPosition->id, $application->requested_position_id);
|
||||
$this->assertSame($assignment->id, $application->selected_ktm_assignment_id);
|
||||
|
||||
Mail::assertQueued(KtmCreatedApplicantMail::class, fn (KtmCreatedApplicantMail $mail): bool => $mail->application->is($application));
|
||||
}
|
||||
|
||||
public function test_ktm_cannot_register_kp_after_registration_period(): void
|
||||
{
|
||||
Mail::fake();
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ktm = User::query()->where('email', 'ktm@prn.local')->firstOrFail();
|
||||
$assignment = $this->ktmAssignmentFor($ktm);
|
||||
$assignment->election->settings()->update([
|
||||
'registration_start_date' => now()->subWeeks(4)->toDateString(),
|
||||
'registration_end_date' => now()->subDay()->toDateString(),
|
||||
'is_registration_open' => true,
|
||||
'is_registration_open_override' => null,
|
||||
]);
|
||||
|
||||
$this->actingAs($ktm)
|
||||
->post(route('ktm.applications.store'), [
|
||||
'ktm_assignment_id' => $assignment->id,
|
||||
'name' => 'KP Lewat',
|
||||
'ic_number' => '880101101112',
|
||||
'phone_number' => '0123456789',
|
||||
'email' => 'kp-late@example.test',
|
||||
])
|
||||
->assertSessionHasErrors('registration');
|
||||
|
||||
$this->assertDatabaseMissing('applications', [
|
||||
'ic_number' => '880101101112',
|
||||
]);
|
||||
Mail::assertNothingQueued();
|
||||
}
|
||||
|
||||
public function test_ktm_can_approve_kp_application_under_own_team(): void
|
||||
{
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ktm = User::query()->where('email', 'ktm@prn.local')->firstOrFail();
|
||||
$assignment = $this->ktmAssignmentFor($ktm);
|
||||
$application = $this->kpApplicationFor($assignment, 'KP Untuk Approve', '880101101113');
|
||||
|
||||
$this->actingAs($ktm)
|
||||
->post(route('ktm.applications.approve', $application->public_uuid))
|
||||
->assertRedirect(route('ktm.applications.show', $application->public_uuid));
|
||||
|
||||
$application->refresh();
|
||||
$kpPosition = Position::query()->where('code', 'KP')->firstOrFail();
|
||||
|
||||
$this->assertSame('assigned', $application->status);
|
||||
$this->assertSame($kpPosition->id, $application->approved_position_id);
|
||||
$this->assertTrue(StaffAssignment::query()
|
||||
->where('application_id', $application->id)
|
||||
->where('reports_to_assignment_id', $assignment->id)
|
||||
->where('position_id', $kpPosition->id)
|
||||
->where('status', 'active')
|
||||
->exists());
|
||||
}
|
||||
|
||||
public function test_ktm_cannot_approve_non_kp_or_other_team_application(): void
|
||||
{
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ktm = User::query()->where('email', 'ktm@prn.local')->firstOrFail();
|
||||
$ownAssignment = $this->ktmAssignmentFor($ktm);
|
||||
$otherKtm = User::query()->where('email', 'ppm@prn.local')->firstOrFail();
|
||||
$otherAssignment = $this->ktmAssignmentFor($otherKtm);
|
||||
$papmPosition = Position::query()->where('code', 'PAPM')->firstOrFail();
|
||||
|
||||
$otherTeamApplication = $this->kpApplicationFor($otherAssignment, 'KP Team Lain', '880101101114');
|
||||
$nonKpApplication = Application::query()->create([
|
||||
'election_id' => $ownAssignment->election_id,
|
||||
'pusat_mengundi_id' => $ownAssignment->pusat_mengundi_id,
|
||||
'selected_ktm_assignment_id' => $ownAssignment->id,
|
||||
'public_uuid' => (string) Str::uuid(),
|
||||
'source' => 'public',
|
||||
'status' => 'submitted',
|
||||
'name' => 'Bukan KP',
|
||||
'ic_number' => '880101101115',
|
||||
'phone_number' => '0123456789',
|
||||
'email' => 'not-kp@example.test',
|
||||
'requested_position_id' => $papmPosition->id,
|
||||
]);
|
||||
|
||||
$this->actingAs($ktm)
|
||||
->post(route('ktm.applications.approve', $otherTeamApplication->public_uuid))
|
||||
->assertSessionHasErrors('application');
|
||||
|
||||
$this->actingAs($ktm)
|
||||
->post(route('ktm.applications.approve', $nonKpApplication->public_uuid))
|
||||
->assertSessionHasErrors('requested_position_id');
|
||||
}
|
||||
|
||||
public function test_ktm_can_delete_own_created_applicant_to_allow_public_registration(): void
|
||||
{
|
||||
Mail::fake();
|
||||
$this->seed(DatabaseSeeder::class);
|
||||
|
||||
$ktm = User::query()->where('email', 'ktm@prn.local')->firstOrFail();
|
||||
$assignment = $this->ktmAssignmentFor($ktm);
|
||||
$application = $this->kpApplicationFor($assignment, 'KP Padam', '880101101116', 'created_by_ktm');
|
||||
|
||||
$this->actingAs($ktm)
|
||||
->delete(route('ktm.applications.destroy', $application->public_uuid))
|
||||
->assertRedirect(route('ktm.applications.index'));
|
||||
|
||||
$this->assertSoftDeleted('applications', [
|
||||
'id' => $application->id,
|
||||
'status' => 'deleted_by_ktm',
|
||||
]);
|
||||
}
|
||||
|
||||
private function ktmAssignmentFor(User $user): StaffAssignment
|
||||
{
|
||||
$ktmPosition = Position::query()->where('code', 'KTM')->firstOrFail();
|
||||
|
||||
return StaffAssignment::query()
|
||||
->with(['election.settings', 'pusatMengundi', 'saluranMengundi'])
|
||||
->where('user_id', $user->id)
|
||||
->where('position_id', $ktmPosition->id)
|
||||
->where('status', 'active')
|
||||
->whereNotNull('saluran_mengundi_id')
|
||||
->firstOrFail();
|
||||
}
|
||||
|
||||
private function kpApplicationFor(StaffAssignment $assignment, string $name, string $icNumber, string $source = 'public'): Application
|
||||
{
|
||||
$kpPosition = Position::query()->where('code', 'KP')->firstOrFail();
|
||||
|
||||
return Application::query()->create([
|
||||
'election_id' => $assignment->election_id,
|
||||
'pusat_mengundi_id' => $assignment->pusat_mengundi_id,
|
||||
'selected_ktm_assignment_id' => $assignment->id,
|
||||
'public_uuid' => (string) Str::uuid(),
|
||||
'source' => $source,
|
||||
'status' => 'submitted',
|
||||
'name' => $name,
|
||||
'ic_number' => $icNumber,
|
||||
'phone_number' => '0123456789',
|
||||
'email' => Str::slug($name).'@example.test',
|
||||
'requested_position_id' => $kpPosition->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user