Files
HRM-System/tests/Feature/EmployeeImportTest.php

129 lines
4.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Branch;
use App\Models\Department;
use App\Models\Designation;
use App\Models\Employee;
use App\Models\Shift;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
class EmployeeImportTest extends TestCase
{
use RefreshDatabase;
protected User $company;
protected function setUp(): void
{
parent::setUp();
Permission::firstOrCreate(['name' => 'manage-employees']);
Permission::firstOrCreate(['name' => 'import-employee']);
Role::firstOrCreate(['name' => 'employee']);
$this->company = User::factory()->create([
'type' => 'company',
]);
$this->company->givePermissionTo(['manage-employees', 'import-employee']);
}
public function test_can_download_sample_template(): void
{
$response = $this->actingAs($this->company)->get(route('hr.employees.download.template'));
$response->assertStatus(200);
$this->assertStringContainsString('sample-employee.csv', $response->headers->get('Content-Disposition') ?? '');
}
public function test_can_import_employee_with_only_mandatory_fields(): void
{
$branch = Branch::create(['name' => 'HQ', 'created_by' => $this->company->id]);
$department = Department::create(['name' => 'Tech', 'branch_id' => $branch->id, 'created_by' => $this->company->id]);
$designation = Designation::create(['name' => 'Dev', 'department_id' => $department->id, 'created_by' => $this->company->id]);
$shift = Shift::create(['name' => 'Morning', 'start_time' => '08:00:00', 'end_time' => '17:00:00', 'created_by' => $this->company->id]);
$payload = [
'data' => [
[
'name' => 'Alice Optional Test',
'email' => 'alice.optional@example.com',
// No biometric_emp_id, no bank_name, no account_number, no postal_code!
'branch' => 'HQ',
'department' => 'Tech',
'designation' => 'Dev',
'shift' => 'Morning',
]
]
];
$response = $this->actingAs($this->company)->post(route('hr.employees.import'), $payload);
$response->assertSessionHas('success');
$user = User::where('email', 'alice.optional@example.com')->first();
$this->assertNotNull($user);
$this->assertEquals('Alice Optional Test', $user->name);
$employee = Employee::where('user_id', $user->id)->first();
$this->assertNotNull($employee);
$this->assertNull($employee->biometric_emp_id);
$this->assertEquals('', $employee->bank_name);
$this->assertEquals('', $employee->account_number);
$this->assertEquals('', $employee->postal_code);
$this->assertEquals(0.00, (float) $employee->base_salary);
$this->assertEquals('active', $employee->employee_status);
$this->assertEquals('full-time', $employee->employment_type);
}
public function test_handles_excel_numeric_date_and_string_formats(): void
{
$payload = [
'data' => [
[
'name' => 'Bob Date Test',
'email' => 'bob.date@example.com',
'date_of_joining' => '45217', // Excel serial for 2023-10-18
'date_of_birth' => '10/18/1990', // Locale date
'gender' => 'MALE', // Uppercase enum check
'base_salary' => '25000',
]
]
];
$response = $this->actingAs($this->company)->post(route('hr.employees.import'), $payload);
$response->assertSessionHas('success');
$user = User::where('email', 'bob.date@example.com')->first();
$this->assertNotNull($user);
$employee = Employee::where('user_id', $user->id)->first();
$this->assertNotNull($employee);
$this->assertEquals('2023-10-18', $employee->date_of_joining);
$this->assertEquals('1990-10-18', $employee->date_of_birth);
$this->assertEquals('male', $employee->gender);
$this->assertEquals(25000.00, (float) $employee->base_salary);
}
public function test_duplicate_email_is_skipped_cleanly(): void
{
User::factory()->create(['email' => 'existing@example.com']);
$payload = [
'data' => [
[
'name' => 'Duplicate Person',
'email' => 'existing@example.com',
]
]
];
$response = $this->actingAs($this->company)->post(route('hr.employees.import'), $payload);
$response->assertSessionHas('error'); // 0 added, 1 skipped
}
}