156 lines
5.5 KiB
PHP
156 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Application;
|
|
use App\Models\ApplicationDocument;
|
|
use App\Models\BankVerification;
|
|
use App\Models\ExportLog;
|
|
use App\Models\Position;
|
|
use App\Models\PusatMengundi;
|
|
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 FinanceModuleTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_admin_kewangan_can_view_approved_staff_bank_list(): void
|
|
{
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$finance = User::query()->where('email', 'kewangan@prn.local')->firstOrFail();
|
|
$application = $this->assignedApplication('Finance View', '910101105551');
|
|
|
|
$this->actingAs($finance)
|
|
->get(route('kewangan.bank.index'))
|
|
->assertOk()
|
|
->assertSee($application->name)
|
|
->assertSee('Penyata ada');
|
|
}
|
|
|
|
public function test_admin_kewangan_can_verify_bank_account(): void
|
|
{
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$finance = User::query()->where('email', 'kewangan@prn.local')->firstOrFail();
|
|
$application = $this->assignedApplication('Finance Verify', '910101105552');
|
|
$verification = $application->bankVerification()->firstOrFail();
|
|
|
|
$this->actingAs($finance)
|
|
->patch(route('kewangan.bank.update', $verification), [
|
|
'status' => 'verified',
|
|
'finance_note' => 'Akaun disahkan.',
|
|
])
|
|
->assertRedirect(route('kewangan.bank.show', $verification));
|
|
|
|
$verification->refresh();
|
|
|
|
$this->assertSame('verified', $verification->status);
|
|
$this->assertSame('Akaun disahkan.', $verification->finance_note);
|
|
$this->assertSame($finance->id, $verification->verified_by_user_id);
|
|
$this->assertNotNull($verification->verified_at);
|
|
}
|
|
|
|
public function test_finance_filters_missing_bank_statement_and_account_number(): void
|
|
{
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$finance = User::query()->where('email', 'kewangan@prn.local')->firstOrFail();
|
|
$complete = $this->assignedApplication('Finance Complete', '910101105553');
|
|
$missing = $this->assignedApplication('Finance Missing', '910101105554', false, false);
|
|
|
|
$this->actingAs($finance)
|
|
->get(route('kewangan.bank.index', [
|
|
'missing_bank_statement' => 1,
|
|
'missing_account_number' => 1,
|
|
]))
|
|
->assertOk()
|
|
->assertSee($missing->name)
|
|
->assertDontSee($complete->name);
|
|
}
|
|
|
|
public function test_admin_kewangan_cannot_change_assignment(): void
|
|
{
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$finance = User::query()->where('email', 'kewangan@prn.local')->firstOrFail();
|
|
$assignment = StaffAssignment::query()->firstOrFail();
|
|
|
|
$this->actingAs($finance)
|
|
->get(route('admin.management.assignments.edit', $assignment))
|
|
->assertForbidden();
|
|
}
|
|
|
|
public function test_finance_export_creates_export_log(): void
|
|
{
|
|
Storage::fake('local');
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$finance = User::query()->where('email', 'kewangan@prn.local')->firstOrFail();
|
|
$this->assignedApplication('Finance Export', '910101105555');
|
|
|
|
$this->actingAs($finance)
|
|
->get(route('kewangan.bank.export'))
|
|
->assertOk();
|
|
|
|
$exportLog = ExportLog::query()->where('report_type', 'finance_verification_list')->firstOrFail();
|
|
|
|
$this->assertSame($finance->id, $exportLog->generated_by_user_id);
|
|
$this->assertNotNull($exportLog->generated_at);
|
|
$this->assertSame('local', $exportLog->disk);
|
|
Storage::disk('local')->assertExists($exportLog->path);
|
|
}
|
|
|
|
private function assignedApplication(string $name, string $icNumber, bool $withBankStatement = true, bool $withAccountNumber = true): Application
|
|
{
|
|
$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,
|
|
'approved_position_id' => $position->id,
|
|
'status' => 'assigned',
|
|
'name' => $name,
|
|
'ic_number' => $icNumber,
|
|
'bank_name' => 'Maybank',
|
|
'bank_account_number' => $withAccountNumber ? '1234567890' : null,
|
|
]);
|
|
|
|
BankVerification::query()->create([
|
|
'application_id' => $application->id,
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
StaffAssignment::query()->create([
|
|
'election_id' => $pusat->election_id,
|
|
'application_id' => $application->id,
|
|
'position_id' => $position->id,
|
|
'pusat_mengundi_id' => $pusat->id,
|
|
'status' => 'active',
|
|
'assigned_at' => now(),
|
|
'source' => 'test',
|
|
]);
|
|
|
|
if ($withBankStatement) {
|
|
ApplicationDocument::query()->create([
|
|
'application_id' => $application->id,
|
|
'document_type' => 'bank_statement',
|
|
'disk' => 'local',
|
|
'path' => 'applications/'.$application->public_uuid.'/bank.pdf',
|
|
'original_name' => 'bank.pdf',
|
|
'mime_type' => 'application/pdf',
|
|
'size' => 12,
|
|
]);
|
|
}
|
|
|
|
return $application;
|
|
}
|
|
}
|