2026-08-20 17:35:38 +02:00
< ? php
declare ( strict_types = 1 );
namespace Tests\Unit\Domain\Services ;
use Domain\Exceptions\BrandNotFoundException ;
use Domain\Models\Entities\Brand ;
use Domain\Models\ValueObjects\Brand\ArcadiaBrand ;
use Domain\Models\ValueObjects\Brand\ArcadiaId ;
use Domain\Models\ValueObjects\Brand\BrandCode ;
use Domain\Models\ValueObjects\Brand\BrandId ;
use Domain\Models\ValueObjects\Brand\BrandName ;
use Domain\Services\BrandCodeGenerator ;
use Domain\Services\BrandResolver ;
use Infra\Adapters\Directories\InMemoryArcadiaBrandDirectory ;
use Infra\Adapters\Repositories\InMemoryBrandRepository ;
use Psr\Log\NullLogger ;
use Ramsey\Uuid\Uuid ;
covers ( BrandResolver :: class );
describe ( 'BrandResolver Unit Tests' , function () : void {
$arcadiaDirectory = new InMemoryArcadiaBrandDirectory ();
$brandRepository = new InMemoryBrandRepository ();
$codeGenerator = new BrandCodeGenerator ();
$logger = new NullLogger ();
beforeEach ( function () use ( $arcadiaDirectory , $brandRepository ) : void {
$arcadiaDirectory -> clear ();
$brandRepository -> clear ();
});
it ( 'returns existing brand if already present in repository' , function () use ( $arcadiaDirectory , $brandRepository , $codeGenerator , $logger ) : void {
// GIVEN
$existing = Brand :: hydrate (
id : new BrandId ( Uuid :: uuid7 ()),
name : new BrandName ( 'Le Gaulois' ),
code : new BrandCode ( 'LGL01' ),
arcadiaId : new ArcadiaId ( 1 ),
);
$brandRepository -> add ( $existing );
2026-08-20 18:16:31 +02:00
$resolver = new BrandResolver ( $arcadiaDirectory , $brandRepository , $codeGenerator , $logger );
2026-08-20 17:35:38 +02:00
// WHEN
2026-08-20 18:16:31 +02:00
$resolved = $resolver -> resolve ( new ArcadiaId ( 1 ));
2026-08-20 17:35:38 +02:00
// THEN
expect ( $resolved ) -> toBe ( $existing );
});
2026-08-20 18:16:31 +02:00
it ( 'generates, persists and logs a new brand if not in repository but in Arcadia directory' , function () use ( $arcadiaDirectory , $brandRepository , $codeGenerator , $logger ) : void {
2026-08-20 17:35:38 +02:00
// GIVEN
2026-08-20 18:16:31 +02:00
$arcadiaDirectory -> add ( new ArcadiaBrand ( new ArcadiaId ( 2 ), new BrandName ( 'Maître CoQ' )));
$resolver = new BrandResolver ( $arcadiaDirectory , $brandRepository , $codeGenerator , $logger );
2026-08-20 17:35:38 +02:00
// WHEN
2026-08-20 18:16:31 +02:00
$resolved = $resolver -> resolve ( new ArcadiaId ( 2 ));
2026-08-20 17:35:38 +02:00
// THEN
expect ( $resolved -> arcadiaId -> value ) -> toBe ( 2 )
-> and ( $resolved -> name -> value ) -> toBe ( 'Maître CoQ' )
-> and ( str_starts_with ( $resolved -> code -> value , 'MCQ' )) -> toBeTrue ();
expect ( $brandRepository -> findByArcadiaId ( new ArcadiaId ( 2 ))) -> not -> toBeNull ();
});
2026-08-20 18:16:31 +02:00
it ( 'throws BrandNotFoundException when resolving an unknown ArcadiaId' , function () use ( $arcadiaDirectory , $brandRepository , $codeGenerator , $logger ) : void {
2026-08-20 17:35:38 +02:00
// GIVEN
$resolver = new BrandResolver ( $arcadiaDirectory , $brandRepository , $codeGenerator , $logger );
// WHEN & THEN
2026-08-20 18:16:31 +02:00
expect ( fn () => $resolver -> resolve ( new ArcadiaId ( 999 )))
2026-08-20 17:35:38 +02:00
-> toThrow ( BrandNotFoundException :: class , 'Arcadia brand with ID 999 not found.' );
});
});