feat: generate draft assignments from a staffing matrix

This commit is contained in:
fromme committed 2026-10-15 18:11:51 +02:00
1 parent 3116d23199
commit 2fc9806c69
41 files changed
+2618

No files matched your search

@@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
namespace App\Tests\Service\Assignment;
use App\Entity\Fee;
use App\Entity\JobProfile;
use App\Enum\StaffingFee;
use App\Enum\StaffingRole;
use App\Repository\FeeRepository;
use App\Repository\JobProfileRepository;
use App\Service\Assignment\StaffingConfigurationException;
use App\Service\Assignment\StaffingResolver;
use PHPUnit\Framework\TestCase;
class StaffingResolverTest extends TestCase
{
public function testAConfiguredRoleResolvesToItsJobProfile(): void
{
$jobProfile = new JobProfile();
$resolver = $this->resolver(jobProfiles: [5 => $jobProfile]);
$this->assertSame($jobProfile, $resolver->jobProfile(StaffingRole::GUIDE));
}
public function testAnUnconfiguredRoleIsRefused(): void
{
$this->expectException(StaffingConfigurationException::class);
$this->expectExceptionMessage('auto_assignment_job_profiles.ski_beginner');
$this->resolver()->jobProfile(StaffingRole::SKI_BEGINNER);
}
public function testADeletedJobProfileIsRefused(): void
{
$this->expectException(StaffingConfigurationException::class);
$this->resolver(jobProfiles: [5 => (new JobProfile())->setDeleted()])->jobProfile(StaffingRole::GUIDE);
}
public function testAMissingFeeIsRefused(): void
{
$this->expectException(StaffingConfigurationException::class);
$this->expectExceptionMessage('auto_assignment_fees.course');
$this->resolver(fees: [3 => new Fee()])->fee(StaffingFee::COURSE);
}
public function testAssertConfiguredChecksEveryRoleAndFee(): void
{
$jobProfiles = [];
foreach ([5, 3, 14, 20] as $id) {
$jobProfiles[$id] = new JobProfile();
}
// guide_ski_advanced (21) is missing
$this->expectException(StaffingConfigurationException::class);
$this->expectExceptionMessage('guide_ski_advanced');
$this->resolver(jobProfiles: $jobProfiles, fees: [3 => new Fee(), 4 => new Fee()])->assertConfigured();
}
/**
* @param array<int, JobProfile> $jobProfiles
* @param array<int, Fee> $fees
*/
private function resolver(array $jobProfiles = [], array $fees = []): StaffingResolver
{
$jobProfileRepository = $this->createStub(JobProfileRepository::class);
$jobProfileRepository->method('find')->willReturnCallback(static fn ($id) => $jobProfiles[$id] ?? null);
$feeRepository = $this->createStub(FeeRepository::class);
$feeRepository->method('find')->willReturnCallback(static fn ($id) => $fees[$id] ?? null);
return new StaffingResolver(
$jobProfileRepository,
$feeRepository,
['guide' => 5, 'ski_beginner' => 3, 'ski_advanced' => 14, 'guide_ski_beginner' => 20, 'guide_ski_advanced' => 21],
['guiding' => 3, 'course' => 4],
);
}
}