Files
ratemas/tests/Feature/RateMasWorkflowTest.php
2026-05-26 12:02:16 +08:00

307 lines
10 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
use Tests\TestCase;
class RateMasWorkflowTest extends TestCase
{
use RefreshDatabase;
public function test_user_can_login_and_open_account_search(): void
{
User::create([
'name' => 'User Cukai',
'username' => 'cukai',
'email' => 'cukai@example.local',
'password' => '123',
]);
$this->post('/login', [
'username' => 'cukai',
'password' => '123',
])->assertRedirect('/tables');
$this->get('/tables')
->assertOk()
->assertSee('Carian Akaun')
->assertSee('A010100001');
}
public function test_authenticated_user_can_submit_account_and_year_to_print_record(): void
{
$this->actingAs(User::create([
'name' => 'User Cukai',
'username' => 'cukai',
'email' => 'cukai@example.local',
'password' => '123',
]));
$this->createRateMasTable('2013_ratemas');
$this->get('/records/search?noakaun=A001&year=2013')
->assertRedirect('/tables/2013_ratemas/records?noakaun=A001');
$this->get('/tables/2013_ratemas/records?noakaun=A001')
->assertOk()
->assertSee('RateMas 2013')
->assertSee('A001')
->assertSee('Ali Ahmad')
->assertSee('Next 2014')
->assertSee('/records/search', false)
->assertSee('Cetak');
}
public function test_print_record_has_previous_and_next_year_navigation(): void
{
$this->actingAs(User::create([
'name' => 'User Cukai',
'username' => 'cukai',
'email' => 'cukai@example.local',
'password' => '123',
]));
$this->createRateMasTable('2014_ratemas');
$this->get('/tables/2014_ratemas/records?noakaun=A001')
->assertOk()
->assertSee('Prev 2013')
->assertSee('Next 2015')
->assertSee('value="2014"', false);
}
public function test_regular_user_cannot_open_admin_upload_page(): void
{
$this->actingAs(User::create([
'name' => 'User Cukai',
'username' => 'cukai',
'email' => 'cukai@example.local',
'password' => '123',
]));
$this->get('/admin/ratemas/upload')->assertForbidden();
}
public function test_regular_user_cannot_open_admin_user_management(): void
{
$this->actingAs(User::create([
'name' => 'User Cukai',
'username' => 'cukai',
'email' => 'cukai@example.local',
'password' => '123',
]));
$this->get('/admin/users')->assertForbidden();
}
public function test_admin_can_upload_csv_and_create_year_table(): void
{
$this->actingAs(User::create([
'name' => 'Admin',
'username' => 'admin',
'role' => 'admin',
'email' => 'admin@example.local',
'password' => 'admin123',
]));
$csv = implode("\n", [
'no_akaun,nama_pemilik,jumlah_baki',
'A009,Siti Aminah,123.45',
]);
$this->post('/admin/ratemas/upload', [
'year' => 2020,
'file' => UploadedFile::fake()->createWithContent('ratemas-2020.csv', $csv),
])->assertRedirect('/admin/ratemas/upload');
$this->assertTrue(Schema::hasTable('2020_ratemas'));
$this->assertSame('Siti Aminah', DB::table('2020_ratemas')->where('no_akaun', 'A009')->value('nama_pemilik'));
$this->get('/tables/2020_ratemas/records?noakaun=A009')
->assertOk()
->assertSee('RateMas 2020')
->assertSee('Siti Aminah');
}
public function test_authenticated_user_can_update_email_and_password(): void
{
$user = User::create([
'name' => 'User Cukai',
'username' => 'cukai',
'email' => 'cukai@example.local',
'password' => '12345678',
]);
$this->actingAs($user);
$this->put('/profile/email', [
'email' => 'baru@example.local',
])->assertRedirect();
$this->assertSame('baru@example.local', $user->fresh()->email);
$this->put('/profile/password', [
'current_password' => '12345678',
'password' => 'password-baru',
'password_confirmation' => 'password-baru',
])->assertRedirect();
$this->assertTrue(Hash::check('password-baru', $user->fresh()->password));
}
public function test_guest_can_request_and_complete_password_reset(): void
{
$user = User::create([
'name' => 'User Cukai',
'username' => 'cukai',
'email' => 'cukai@example.local',
'password' => '12345678',
]);
$this->post('/forgot-password', [
'email' => $user->email,
])->assertRedirect();
$this->assertDatabaseHas('password_reset_tokens', [
'email' => $user->email,
]);
$token = Str::random(64);
DB::table('password_reset_tokens')->updateOrInsert([
'email' => $user->email,
], [
'token' => Hash::make($token),
'created_at' => now(),
]);
$this->post('/reset-password', [
'token' => $token,
'email' => $user->email,
'password' => 'reset-baru',
'password_confirmation' => 'reset-baru',
])->assertRedirect('/login');
$this->assertTrue(Hash::check('reset-baru', $user->fresh()->password));
$this->assertDatabaseMissing('password_reset_tokens', [
'email' => $user->email,
]);
}
public function test_admin_can_create_regular_user_by_default(): void
{
$this->actingAs(User::create([
'name' => 'Admin',
'username' => 'admin',
'role' => 'admin',
'email' => 'admin@example.local',
'password' => 'admin123',
]));
$this->post('/admin/users', [
'name' => 'User Baru',
'username' => 'userbaru',
'email' => 'userbaru@example.local',
'password' => 'password123',
'password_confirmation' => 'password123',
])->assertRedirect('/admin/users');
$user = User::where('username', 'userbaru')->firstOrFail();
$this->assertSame('user', $user->role);
$this->assertTrue(Hash::check('password123', $user->password));
}
public function test_admin_can_create_new_admin_user(): void
{
$this->actingAs(User::create([
'name' => 'Admin',
'username' => 'admin',
'role' => 'admin',
'email' => 'admin@example.local',
'password' => 'admin123',
]));
$this->post('/admin/users', [
'name' => 'Admin Baru',
'username' => 'adminbaru',
'email' => 'adminbaru@example.local',
'password' => 'password123',
'password_confirmation' => 'password123',
'role' => 'admin',
])->assertRedirect('/admin/users');
$this->assertTrue(User::where('username', 'adminbaru')->firstOrFail()->isAdmin());
}
private function createRateMasTable(string $table): void
{
Schema::create($table, function ($table) {
$table->string('no_akaun')->primary();
$table->string('no_akaun_lama')->nullable();
$table->string('nama_pemilik')->nullable();
$table->string('alamatpos_1')->nullable();
$table->string('alamatpos_2')->nullable();
$table->string('alamatpos_3')->nullable();
$table->string('ic_no')->nullable();
$table->string('old_ic_no')->nullable();
$table->string('bangsa')->nullable();
$table->string('warganegara')->nullable();
$table->string('nolot')->nullable();
$table->string('nogeran')->nullable();
$table->string('kegunaan')->nullable();
$table->string('mukim')->nullable();
$table->string('no_bangunan')->nullable();
$table->string('lokasiharta_1')->nullable();
$table->string('lokasiharta_2')->nullable();
$table->string('kawasan')->nullable();
$table->string('jenisbangunan')->nullable();
$table->decimal('new_taksiran', 12, 2)->default(0);
$table->decimal('kadar', 6, 2)->default(0);
$table->decimal('cukai_setengahtahun', 12, 2)->default(0);
$table->string('tarikh_kuatkuasa')->nullable();
$table->decimal('old_taksiran', 12, 2)->default(0);
$table->decimal('old_kadar', 6, 2)->default(0);
$table->decimal('tunggakan_cukai', 12, 2)->default(0);
$table->decimal('cukai_semasa_1', 12, 2)->default(0);
$table->decimal('cukai_semasa_2', 12, 2)->default(0);
$table->decimal('pelarasan_cukai', 12, 2)->default(0);
$table->decimal('bayaran_cukai_diterima', 12, 2)->default(0);
$table->decimal('baki_cukai', 12, 2)->default(0);
$table->decimal('baki_najis', 12, 2)->default(0);
$table->decimal('baki_notis', 12, 2)->default(0);
$table->decimal('baki_waran', 12, 2)->default(0);
$table->decimal('jumlah_baki', 12, 2)->default(0);
});
\DB::table($table)->insert([
'no_akaun' => 'A001',
'no_akaun_lama' => 'OLD001',
'nama_pemilik' => 'Ali Ahmad',
'alamatpos_1' => 'Alamat 1',
'alamatpos_2' => 'Alamat 2',
'alamatpos_3' => 'Alamat 3',
'ic_no' => '900101010101',
'old_ic_no' => 'A1234567',
'bangsa' => 'Melayu',
'warganegara' => 'Malaysia',
'nolot' => 'Lot 1',
'nogeran' => 'DHM 1',
'kegunaan' => 'Kediaman',
'mukim' => 'Mukim A',
'no_bangunan' => 'B1',
'lokasiharta_1' => 'Lokasi 1',
'lokasiharta_2' => 'Lokasi 2',
'kawasan' => 'Kawasan A',
'jenisbangunan' => 'Rumah',
'tarikh_kuatkuasa' => '01/01/2013',
]);
}
}