ldc-boutique-cnc-sable/tests/Unit/App/Services/CodeGenerationServiceTest.php
Jérémy Munsch e0c4b34ed8
feat(employees): implement deterministic 6-character code generation using SerialCaster
- Add kwaadpepper/serial-int-caster and SerialCasterServiceProvider
- Update CodeGenerationService to encode Matricule deterministically with length 6
- Update Code value object to support lengths between 6 and 10 with 53 non-ambiguous characters
- Add database migration to sanitize legacy ambiguous codes
- Recreate and update unit and integration tests for CodeGenerationService and Code value object
2026-10-27 09:58:46 +01:00

67 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\App\Services;
use App\Services\CodeGenerationService;
use Domain\Models\ValueObjects\Code;
use Domain\Models\ValueObjects\Matricule;
use Kwaadpepper\Serial\Converters\NativeBaseConverter;
use Kwaadpepper\Serial\SerialCasterBuilder;
use Kwaadpepper\Serial\Shufflers\FisherYatesShuffler;
covers(CodeGenerationService::class);
describe('CodeGenerationService', function (): void {
it('generates a valid code of exactly 6 characters from matricule', function (): void {
// GIVEN
$builder = (new SerialCasterBuilder(new NativeBaseConverter()))
->withShuffler(new FisherYatesShuffler())
->withSeed(12345);
$service = new CodeGenerationService($builder);
$matricule = new Matricule('0100759');
// WHEN
$code = $service->generateFrom($matricule);
// THEN
expect($code)->toBeInstanceOf(Code::class)
->and(strlen($code->value))->toBe(Code::LENGTH)
->and(preg_match('/^[' . Code::ALLOWED_CHARACTERS . ']+$/', $code->value))->toBe(1);
});
it('generates deterministic codes for the same matricule', function (): void {
// GIVEN
$builder = (new SerialCasterBuilder(new NativeBaseConverter()))
->withShuffler(new FisherYatesShuffler())
->withSeed(12345);
$service = new CodeGenerationService($builder);
$matricule = new Matricule('0100759');
// WHEN
$code1 = $service->generateFrom($matricule);
$code2 = $service->generateFrom($matricule);
// THEN
expect($code1->value)->toBe($code2->value);
});
it('generates different codes for different matricules', function (): void {
// GIVEN
$builder = (new SerialCasterBuilder(new NativeBaseConverter()))
->withShuffler(new FisherYatesShuffler())
->withSeed(12345);
$service = new CodeGenerationService($builder);
// WHEN
$code1 = $service->generateFrom(new Matricule('0100759'));
$code2 = $service->generateFrom(new Matricule('0100760'));
// THEN
expect($code1->value)->not->toBe($code2->value);
});
});