Added Filter and Sorter classes to handle employee filtering and sorting criteria. Updated FindAllEmployees use case to utilize these new classes for improved employee data retrieval.
200 lines
8.1 KiB
PHP
200 lines
8.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Integration\Infra\Adapters\Directories;
|
|
|
|
use Domain\Models\Entities\Employee;
|
|
use Domain\Models\ValueObjects\Entities\ArcadiaEmployeeId;
|
|
use Domain\Models\ValueObjects\EstablishmentCode;
|
|
use Domain\Models\ValueObjects\ServiceId;
|
|
use Domain\Models\ValueObjects\SiteId;
|
|
use Domain\Models\ValueObjects\Employees\EmployeeFilter;
|
|
use Domain\Models\ValueObjects\Employees\EmployeeSortColumn;
|
|
use Domain\Models\ValueObjects\Employees\EmployeeSorter;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Infra\Adapters\Directories\EloquentEmployeeDirectory;
|
|
use Infra\Database\Models\Employee as EmployeeModel;
|
|
use Shared\Paginated;
|
|
use Shared\Pagination;
|
|
use Tests\TestCase;
|
|
|
|
uses(TestCase::class, RefreshDatabase::class);
|
|
covers(EloquentEmployeeDirectory::class);
|
|
|
|
beforeEach(function (): void {
|
|
EmployeeModel::query()->delete();
|
|
});
|
|
|
|
describe('EloquentEmployeeDirectory Integration Tests', function (): void {
|
|
it('finds an employee by public employee number and maps to domain entity', function (): void {
|
|
// GIVEN
|
|
$directory = new EloquentEmployeeDirectory();
|
|
|
|
EmployeeModel::factory()->create([
|
|
'public_employee_number' => '1234567',
|
|
'last_name' => 'DUPONT',
|
|
'first_name' => 'Jean',
|
|
'start_date' => '2024-01-01',
|
|
'end_date' => '2025-01-01',
|
|
'planned_end_date' => '2025-06-01',
|
|
'establishment' => '01',
|
|
'site' => 'LDCSER',
|
|
'service' => '097',
|
|
'created_at' => '2024-01-01 10:00:00',
|
|
'updated_at' => '2024-01-02 12:00:00',
|
|
]);
|
|
|
|
$employeeId = new ArcadiaEmployeeId('1234567');
|
|
|
|
// WHEN
|
|
$result = $directory->find($employeeId);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(Employee::class)
|
|
->and($result?->id()->value)->toBe('1234567')
|
|
->and($result?->lastName)->toBe('DUPONT')
|
|
->and($result?->firstName)->toBe('Jean')
|
|
->and($result?->startDate->format('Y-m-d'))->toBe('2024-01-01')
|
|
->and($result?->endDate?->format('Y-m-d'))->toBe('2025-01-01')
|
|
->and($result?->plannedEndDate?->format('Y-m-d'))->toBe('2025-06-01')
|
|
->and($result?->establishment->value)->toBe('01')
|
|
->and($result?->site->value)->toBe('LDCSER')
|
|
->and($result?->service->value)->toBe('097')
|
|
->and($result?->createdAt->format('Y-m-d H:i:s'))->toBe('2024-01-01 10:00:00')
|
|
->and($result?->updatedAt?->format('Y-m-d H:i:s'))->toBe('2024-01-02 12:00:00');
|
|
});
|
|
|
|
it('converts string dates to DateTimeInterface using toDateTime helper', function (): void {
|
|
// GIVEN
|
|
$directory = new EloquentEmployeeDirectory();
|
|
$reflection = new \ReflectionMethod(EloquentEmployeeDirectory::class, 'toDateTime');
|
|
|
|
// WHEN
|
|
/** @var \DateTimeInterface $result */
|
|
$result = $reflection->invoke($directory, '2024-01-15 14:30:00');
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(\DateTimeInterface::class)
|
|
->and($result->format('Y-m-d H:i:s'))->toBe('2024-01-15 14:30:00');
|
|
});
|
|
|
|
it('returns null when employee is not found', function (): void {
|
|
// GIVEN
|
|
$directory = new EloquentEmployeeDirectory();
|
|
$employeeId = new ArcadiaEmployeeId('9999999');
|
|
|
|
// WHEN
|
|
$result = $directory->find($employeeId);
|
|
|
|
// THEN
|
|
expect($result)->toBeNull();
|
|
});
|
|
|
|
it('throws UnexpectedValueException when created_at is null', function (): void {
|
|
// GIVEN
|
|
$directory = new EloquentEmployeeDirectory();
|
|
|
|
EmployeeModel::query()->insert([
|
|
'public_employee_number' => '7654321',
|
|
'last_name' => 'MARTIN',
|
|
'first_name' => 'Alice',
|
|
'start_date' => '2024-01-01',
|
|
'establishment' => '01',
|
|
'site' => 'LDCSER',
|
|
'service' => '097',
|
|
'created_at' => null,
|
|
'updated_at' => null,
|
|
]);
|
|
|
|
$employeeId = new ArcadiaEmployeeId('7654321');
|
|
|
|
// WHEN & THEN
|
|
expect(fn () => $directory->find($employeeId))
|
|
->toThrow(\UnexpectedValueException::class, 'Employee created_at cannot be null.');
|
|
});
|
|
|
|
it('filters employees when EmployeeFilter parameters are provided', function (): void {
|
|
// GIVEN
|
|
$directory = new EloquentEmployeeDirectory();
|
|
|
|
EmployeeModel::factory()->create([
|
|
'public_employee_number' => '1000001',
|
|
'establishment' => '01',
|
|
'site' => 'LDCSER',
|
|
'service' => '097',
|
|
'created_at' => '2024-01-01 08:00:00',
|
|
'updated_at' => '2024-01-01 09:00:00',
|
|
]);
|
|
|
|
EmployeeModel::factory()->create([
|
|
'public_employee_number' => '1000002',
|
|
'establishment' => 'LY',
|
|
'site' => 'LDCSER',
|
|
'service' => '101',
|
|
'created_at' => '2024-01-01 08:00:00',
|
|
'updated_at' => '2024-01-01 09:00:00',
|
|
]);
|
|
|
|
$filter = new EmployeeFilter(
|
|
establishment: new EstablishmentCode('01'),
|
|
sites: [new SiteId('LDCSER')],
|
|
service: new ServiceId('097'),
|
|
since: new \DateTimeImmutable('2024-01-01 00:00:00')
|
|
);
|
|
|
|
$pagination = Pagination::ofPage(1, 10);
|
|
$sorter = new EmployeeSorter(EmployeeSortColumn::arcadiaId, \SortDirection::Ascending);
|
|
|
|
// WHEN
|
|
$result = $directory->findAll($pagination, $sorter, $filter);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(Paginated::class)
|
|
->and($result->getTotal())->toBe(1)
|
|
->and(count($result->getItems()))->toBe(1)
|
|
->and($result->getItems()[0]->id()->value)->toBe('1000001');
|
|
});
|
|
|
|
it('returns paginated employees sorted by specified columns', function (EmployeeSortColumn $sortColumn, \SortDirection $direction): void {
|
|
// GIVEN
|
|
$directory = new EloquentEmployeeDirectory();
|
|
|
|
EmployeeModel::factory()->create([
|
|
'public_employee_number' => '1000001',
|
|
'start_date' => '2024-01-01',
|
|
'end_date' => '2024-06-01',
|
|
'planned_end_date' => '2024-12-01',
|
|
'created_at' => '2024-01-01 08:00:00',
|
|
'updated_at' => '2024-01-01 09:00:00',
|
|
]);
|
|
|
|
EmployeeModel::factory()->create([
|
|
'public_employee_number' => '1000002',
|
|
'start_date' => '2024-02-01',
|
|
'end_date' => '2024-07-01',
|
|
'planned_end_date' => '2024-12-15',
|
|
'created_at' => '2024-02-01 08:00:00',
|
|
'updated_at' => '2024-02-01 09:00:00',
|
|
]);
|
|
|
|
$pagination = Pagination::ofPage(1, 10);
|
|
$sorter = new EmployeeSorter($sortColumn, $direction);
|
|
|
|
// WHEN
|
|
$result = $directory->findAll($pagination, $sorter);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(Paginated::class)
|
|
->and($result->getTotal())->toBe(2)
|
|
->and(count($result->getItems()))->toBe(2);
|
|
})->with([
|
|
'arcadiaId asc' => [EmployeeSortColumn::arcadiaId, \SortDirection::Ascending],
|
|
'arcadiaId desc' => [EmployeeSortColumn::arcadiaId, \SortDirection::Descending],
|
|
'startDate asc' => [EmployeeSortColumn::startDate, \SortDirection::Ascending],
|
|
'endDate desc' => [EmployeeSortColumn::endDate, \SortDirection::Descending],
|
|
'plannedEndDate asc' => [EmployeeSortColumn::plannedEndDate, \SortDirection::Ascending],
|
|
'createdAt desc' => [EmployeeSortColumn::createdAt, \SortDirection::Descending],
|
|
'updatedAt asc' => [EmployeeSortColumn::updatedAt, \SortDirection::Ascending],
|
|
]);
|
|
});
|