ldc-mesbr-app/tests/Unit/Domain/Services/BrandServiceTest.php
2026-09-15 09:24:18 +02:00

366 lines
11 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Domain\Services;
use Domain\Services\BrandService;
use Domain\Enums\Brand\SortDirection;
use Domain\Enums\Brand\SortField;
use Domain\Models\Entities\Brand;
use Domain\Exceptions\BrandCodeAlreadyExistsException;
use Domain\Exceptions\BrandNotFoundException;
use Domain\Ports\Repositories\BrandRepository;
use Domain\Models\ValueObjects\Brand\BrandCode;
use Domain\Models\ValueObjects\Brand\BrandId;
use Domain\Models\ValueObjects\Brand\BrandName;
use Mockery;
use Shared\Helpers\Paginated;
use Shared\Helpers\Pagination;
use Shared\Models\ValueObjects\Email;
use Shared\Models\ValueObjects\PicturePath;
use Shared\Models\ValueObjects\RCS;
covers(BrandService::class);
describe('brand service', function (): void {
it('creates a brand', function (): void {
// GIVEN
$code = new BrandCode('AAA01');
$name = new BrandName('Name');
$logo = new PicturePath('files/picture.jpg');
$rcs = new RCS('RCS PARIS 111 222 333');
$contact = new Email('contact@example.com');
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('existsByCode')
->once()
->with($code)
->andReturn(false);
$mock->shouldReceive('save')
->once();
$service = new BrandService($mock);
// WHEN
$brand = $service->create($code, $name, $logo, $rcs, $contact);
// THEN
expect($brand)->toBeInstanceOf(Brand::class)
->and($brand->code())->toBe($code)
->and($brand->name())->toBe($name);
});
it('throws when the brand code already exists', function (): void {
// GIVEN
$code = new BrandCode('AAA01');
$name = new BrandName('Name');
$logo = new PicturePath('files/picture.jpg');
$rcs = new RCS('RCS PARIS 111 222 333');
$contact = new Email('contact@example.com');
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('existsByCode')
->once()
->with($code)
->andReturn(true);
$mock->shouldNotReceive('save');
$service = new BrandService($mock);
// WHEN
$action = fn (): Brand => $service->create(
$code,
$name,
$logo,
$rcs,
$contact,
);
// THEN
expect($action)->toThrow(BrandCodeAlreadyExistsException::class);
});
it('gets a brand by id', function (): void {
// GIVEN
$id = BrandId::generate();
$brand = new Brand(
$id,
new BrandCode('AAA01'),
new BrandName('Name'),
new PicturePath('files/picture.jpg'),
new RCS('RCS PARIS 111 222 333'),
new Email('contact@example.com'),
);
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findById')
->once()
->with($id)
->andReturn($brand);
$service = new BrandService($mock);
// WHEN
$result = $service->getById($id);
// THEN
expect($result)->toBe($brand);
});
it('throws when the brand id is not found', function (): void {
// GIVEN
$id = BrandId::generate();
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findById')
->once()
->with($id)
->andReturn(null);
$service = new BrandService($mock);
// WHEN
$action = fn (): Brand => $service->getById($id);
// THEN
expect($action)->toThrow(BrandNotFoundException::class);
});
it('gets a brand by code', function (): void {
// GIVEN
$code = new BrandCode('AAA01');
$brand = new Brand(
BrandId::generate(),
$code,
new BrandName('Name'),
new PicturePath('files/picture.jpg'),
new RCS('RCS PARIS 111 222 333'),
new Email('contact@example.com'),
);
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findByCode')
->once()
->with($code)
->andReturn($brand);
$service = new BrandService($mock);
// WHEN
$result = $service->getByCode($code);
// THEN
expect($result)->toBe($brand);
});
it('throws when the brand code is not found', function (): void {
// GIVEN
$code = new BrandCode('AAA01');
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findByCode')
->once()
->with($code)
->andReturn(null);
$service = new BrandService($mock);
// WHEN
$action = fn (): Brand => $service->getByCode($code);
// THEN
expect($action)->toThrow(BrandNotFoundException::class);
});
it('updates the logo of a brand', function (): void {
// GIVEN
$id = BrandId::generate();
$brand = new Brand(
$id,
new BrandCode('AAA01'),
new BrandName('Name'),
new PicturePath('files/picture-old.jpg'),
new RCS('RCS PARIS 111 222 333'),
new Email('contact@example.com'),
);
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findById')
->once()
->with($id)
->andReturn($brand);
$mock->shouldReceive('save')
->once();
$service = new BrandService($mock);
// WHEN
$newLogo = new PicturePath('files/picture-new.jpg');
$updated = $service->updateLogo($id, $newLogo);
// THEN
expect($updated)->not->toBe($brand)
->and($updated->logo())->toBe($newLogo);
});
it('throws when updating the logo of a brand that does not exist', function (): void {
// GIVEN
$id = BrandId::generate();
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findById')
->once()
->with($id)
->andReturn(null);
$mock->shouldNotReceive('save');
$service = new BrandService($mock);
// WHEN
$newLogo = new PicturePath('files/picture-new.jpg');
$action = fn (): Brand => $service->updateLogo($id, $newLogo);
// THEN
expect($action)->toThrow(BrandNotFoundException::class);
});
it('updates the RCS text of a brand', function (): void {
// GIVEN
$id = BrandId::generate();
$brand = new Brand(
$id,
new BrandCode('AAA01'),
new BrandName('Name'),
new PicturePath('files/picture-old.jpg'),
new RCS('RCS PARIS 111 222 333'),
new Email('contact@example.com'),
);
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findById')
->once()
->with($id)
->andReturn($brand);
$mock->shouldReceive('save')
->once();
$service = new BrandService($mock);
// WHEN
$newRcs = new RCS('RCS NANTES 444 555 666');
$updated = $service->updateRcs($id, $newRcs);
// THEN
expect($updated)->not->toBe($brand)
->and($updated->rcs())->toBe($newRcs);
});
it('throws when updating the RCS text of a brand that does not exist', function (): void {
// GIVEN
$id = BrandId::generate();
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findById')
->once()
->with($id)
->andReturn(null);
$mock->shouldNotReceive('save');
$service = new BrandService($mock);
// WHEN
$newRcs = new RCS('RCS NANTES 444 555 666');
$action = fn (): Brand => $service->updateRcs($id, $newRcs);
// THEN
expect($action)->toThrow(BrandNotFoundException::class);
});
it('updates the contact of a brand', function (): void {
// GIVEN
$id = BrandId::generate();
$brand = new Brand(
$id,
new BrandCode('AAA01'),
new BrandName('Name'),
new PicturePath('files/picture-old.jpg'),
new RCS('RCS PARIS 111 222 333'),
new Email('contact-old@example.com'),
);
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findById')
->once()
->with($id)
->andReturn($brand);
$mock->shouldReceive('save')
->once();
$service = new BrandService($mock);
// WHEN
$newContact = new Email('contact-new@example.com');
$updated = $service->updateContact($id, $newContact);
// THEN
expect($updated)->not->toBe($brand)
->and($updated->contact())->toBe($newContact);
});
it('throws when updating the contact of a brand that does not exist', function (): void {
// GIVEN
$id = BrandId::generate();
$mock = Mockery::mock(BrandRepository::class);
$mock->shouldReceive('findById')
->once()
->with($id)
->andReturn(null);
$mock->shouldNotReceive('save');
$service = new BrandService($mock);
// WHEN
$newContact = new Email('contact-new@example.com');
$action = fn (): Brand => $service->updateContact($id, $newContact);
// THEN
expect($action)->toThrow(BrandNotFoundException::class);
});
it('lists brands with pagination and sorting', function (): void {
$brand1 = new Brand(
BrandId::generate(),
new BrandCode('AAA01'),
new BrandName('Name 01'),
new PicturePath('files/picture-1.jpg'),
new RCS('RCS PARIS 111 222 333'),
new Email('contact-1@example.com'),
);
$brand2 = new Brand(
BrandId::generate(),
new BrandCode('BBB02'),
new BrandName('Name 02'),
new PicturePath('files/picture-2.jpg'),
new RCS('RCS NANTES 444 555 666'),
new Email('contact-2@example.com'),
);
$pagination = Pagination::ofPage(1, 25);
$sortField = SortField::NAME;
$sortDirection = SortDirection::ASC;
$paginated = new Paginated($pagination, [$brand1, $brand2], 2);
$mock = Mockery::mock(BrandRepository::class);
$mock
->shouldReceive('findAll')
->once()
->with($pagination, $sortField, $sortDirection)
->andReturn($paginated);
$service = new BrandService($mock);
expect($service->getAll($pagination))->toBe($paginated);
});
});