seed(DatabaseSeeder::class); $application = $this->application('submitted'); $this->get(route('public.applications.status', $application->public_uuid)) ->assertOk() ->assertSee('Menunggu Semakan') ->assertDontSee($application->name) // full name must not appear ->assertDontSee($application->ic_number); // IC must not appear } public function test_assigned_application_shows_placed_status(): void { $this->seed(DatabaseSeeder::class); $application = $this->application('assigned'); $this->get(route('public.applications.status', $application->public_uuid)) ->assertOk() ->assertSee('Diluluskan'); } public function test_rejected_application_shows_rejection_reason(): void { $this->seed(DatabaseSeeder::class); $application = $this->application('rejected', [ 'rejection_reason' => 'Dokumen IC tidak jelas.', ]); $this->get(route('public.applications.status', $application->public_uuid)) ->assertOk() ->assertSee('Ditolak') ->assertSee('Dokumen IC tidak jelas.'); } public function test_unknown_uuid_returns_200_with_generic_message(): void { $this->seed(DatabaseSeeder::class); $this->get(route('public.applications.status', (string) Str::uuid())) ->assertOk() ->assertSee('Status tidak dapat dipaparkan'); } public function test_deleted_by_ktm_application_returns_generic_message(): void { $this->seed(DatabaseSeeder::class); $application = $this->application('deleted_by_ktm'); $application->delete(); // soft-delete $this->get(route('public.applications.status', $application->public_uuid)) ->assertOk() ->assertSee('Status tidak dapat dipaparkan') ->assertDontSee($application->name); } public function test_soft_deleted_application_returns_generic_message(): void { $this->seed(DatabaseSeeder::class); $application = $this->application('cancelled'); $application->delete(); $this->get(route('public.applications.status', $application->public_uuid)) ->assertOk() ->assertSee('Status tidak dapat dipaparkan'); } public function test_name_is_masked_in_status_view(): void { $this->seed(DatabaseSeeder::class); $application = $this->application('submitted', ['name' => 'Ahmad bin Ali']); $response = $this->get(route('public.applications.status', $application->public_uuid)) ->assertOk(); $response->assertSee('Ahm'); // first 3 chars shown $response->assertDontSee('Ahmad bin Ali'); // full name not shown } public function test_status_page_does_not_require_authentication(): void { $this->seed(DatabaseSeeder::class); $application = $this->application('submitted'); // Access without actingAs — must succeed $this->get(route('public.applications.status', $application->public_uuid)) ->assertOk(); } public function test_status_page_shows_link_to_check_status_on_success_page(): void { $this->seed(DatabaseSeeder::class); $application = $this->application('submitted'); $expectedUrl = route('public.applications.status', $application->public_uuid); $this->get(route('public.applications.success', $application->public_uuid)) ->assertOk() ->assertSee($expectedUrl); } private function application(string $status, array $extra = []): Application { $pusat = PusatMengundi::query()->where('code', 'PM001')->firstOrFail(); $position = Position::query()->where('code', 'PAPM')->firstOrFail(); return Application::query()->create(array_merge([ 'election_id' => $pusat->election_id, 'pusat_mengundi_id' => $pusat->id, 'requested_position_id' => $position->id, 'public_uuid' => (string) Str::uuid(), 'source' => 'public', 'status' => $status, 'name' => 'Pemohon Ujian', 'ic_number' => '900101109999', 'phone_number' => '0123456789', 'email' => 'ujian@example.test', 'address' => 'Jalan Ujian', ], $extra)); } }