205 lines
8.6 KiB
PHP
205 lines
8.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit\Application\UseCases\Coupon\Find;
|
|
|
|
use Application\UseCases\Coupon\Find\FindCoupon;
|
|
use Application\UseCases\Coupon\Find\Input;
|
|
use Application\UseCases\Coupon\Find\Output\CouponFound;
|
|
use Application\UseCases\Coupon\Find\Output\CouponNotFound;
|
|
use Application\UseCases\Coupon\Outputs\BrandNotFound;
|
|
use DateTime;
|
|
use Domain\Models\Entities\Brand;
|
|
use Domain\Models\Entities\Campaign;
|
|
use Domain\Models\Entities\Coupon;
|
|
use Domain\Models\ValueObjects\Actor\ActorId;
|
|
use Domain\Models\ValueObjects\Brand\BrandCode;
|
|
use Domain\Models\ValueObjects\Brand\BrandName;
|
|
use Domain\Models\ValueObjects\Campaign\CampaignCoupon;
|
|
use Domain\Models\ValueObjects\Campaign\CampaignCouponArray;
|
|
use Domain\Models\ValueObjects\Campaign\CampaignName;
|
|
use Domain\Models\ValueObjects\Coupon\CouponCode;
|
|
use Domain\Models\ValueObjects\Coupon\CouponDiffusion;
|
|
use Domain\Models\ValueObjects\Coupon\CouponLegalInformation;
|
|
use Domain\Models\ValueObjects\Coupon\CouponLegalInformationArray;
|
|
use Domain\Models\ValueObjects\Coupon\CouponMovement;
|
|
use Domain\Models\ValueObjects\Coupon\CouponMovementArray;
|
|
use Domain\Models\ValueObjects\Coupon\CouponName;
|
|
use Domain\Models\ValueObjects\Coupon\CouponPicture;
|
|
use Domain\Models\ValueObjects\Coupon\CouponProductArray;
|
|
use Domain\Models\ValueObjects\Coupon\CouponValidityInformation;
|
|
use Domain\Models\ValueObjects\Coupon\CouponValidityInformationArray;
|
|
use Domain\Models\ValueObjects\IncoCode;
|
|
use Domain\Models\ValueObjects\MoneyAmount;
|
|
use Domain\Models\ValueObjects\Period;
|
|
use Domain\Models\ValueObjects\PicturePath;
|
|
use Domain\Models\ValueObjects\ProcessingCode;
|
|
use Domain\Models\ValueObjects\ProcessingCodeArray;
|
|
use Domain\Ports\Repositories\BrandRepository;
|
|
use Domain\Ports\Repositories\CampaignRepository;
|
|
use Domain\Ports\Repositories\CouponRepository;
|
|
use Shared\Enums\Country;
|
|
use Shared\Enums\Currency;
|
|
use Shared\ValueObjects\Email;
|
|
use Shared\ValueObjects\Money;
|
|
use Shared\ValueObjects\Rcs;
|
|
|
|
covers(FindCoupon::class, Input::class, CouponFound::class, CouponNotFound::class);
|
|
|
|
describe('find coupon use case', function (): void {
|
|
$brand = Brand::create(
|
|
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'),
|
|
);
|
|
$coupon = Coupon::create(
|
|
code: new CouponCode('COU01'),
|
|
name: new CouponName('Coupon name'),
|
|
amount: new MoneyAmount(new Money(Currency::EUR, 100)),
|
|
picture: new CouponPicture(
|
|
new PicturePath('files/product.jpg'),
|
|
new PicturePath('files/thumbnail.jpg'),
|
|
new PicturePath('files/mobile_thumbnail.jpg'),
|
|
),
|
|
diffusion: new CouponDiffusion(
|
|
new Period(
|
|
new DateTime('2026-01-01'),
|
|
new DateTime('2026-02-01'),
|
|
),
|
|
),
|
|
validityInformations: new CouponValidityInformationArray([
|
|
new CouponValidityInformation(
|
|
'Lorem ipsum dolor sit amet consectetur adipiscing elit.',
|
|
Country::FRANCE
|
|
),
|
|
]),
|
|
legalInformations: new CouponLegalInformationArray([
|
|
new CouponLegalInformation(
|
|
'Lorem ipsum dolor sit amet consectetur adipiscing elit.',
|
|
Country::FRANCE
|
|
),
|
|
]),
|
|
processingCode: new ProcessingCodeArray([
|
|
new ProcessingCode('5425003944130', Country::FRANCE),
|
|
]),
|
|
brandCode: $brand->code,
|
|
createdBy: ActorId::generate(),
|
|
products: new CouponProductArray([
|
|
new IncoCode(35784),
|
|
new IncoCode(15522),
|
|
]),
|
|
movements: new CouponMovementArray([
|
|
new CouponMovement(1000)
|
|
]),
|
|
);
|
|
$campaign = Campaign::create(
|
|
name: new CampaignName('Campaign name'),
|
|
printAllAtOnce: true,
|
|
coupons: new CampaignCouponArray([
|
|
new CampaignCoupon($coupon->code),
|
|
]),
|
|
brandCode: $brand->code,
|
|
actorId: ActorId::generate(),
|
|
);
|
|
|
|
it('finds a coupon by its code', function () use ($coupon, $campaign): void {
|
|
// GIVEN
|
|
$brandRepository = \Mockery::mock(BrandRepository::class);
|
|
$brandRepository->shouldReceive('existsByCode')->once()->with($coupon->brandCode)->andReturnTrue();
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCode')->once()->with($coupon->code)->andReturn($coupon);
|
|
|
|
$campaignRepository = \Mockery::mock(CampaignRepository::class);
|
|
$campaignRepository->shouldReceive('findByCouponCode')->once()->with($coupon->code)->andReturn([$campaign]);
|
|
|
|
$useCase = new FindCoupon($couponRepository, $brandRepository, $campaignRepository);
|
|
|
|
// WHEN
|
|
$result = $useCase->execute(new Input(code: $coupon->code));
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CouponFound::class)
|
|
->and($result->code)->toBe($coupon->code)
|
|
->and($result->name)->toBe($coupon->name)
|
|
->and($result->amount)->toBe($coupon->amount)
|
|
->and($result->picture)->toBe($coupon->picture)
|
|
->and($result->diffusion)->toBe($coupon->diffusion)
|
|
->and($result->availabilityCalendar)->toBe($coupon->availabilityCalendar)
|
|
->and($result->validityInformations)->toBe($coupon->validityInformations)
|
|
->and($result->legalInformations)->toBe($coupon->legalInformations)
|
|
->and($result->processingCode)->toBe($coupon->processingCode)
|
|
->and($result->brandCode)->toBe($coupon->brandCode)
|
|
->and($result->createdBy)->toBe($coupon->createdBy)
|
|
->and($result->products)->toBe($coupon->products)
|
|
->and($result->movements)->toBe($coupon->movements)
|
|
->and($result->quantity)->toBe($coupon->quantity())
|
|
->and($result->campaigns)->toBe([$campaign])
|
|
->and($result->createdAt)->toBeInstanceOf(\DateTimeInterface::class)
|
|
->and($result->updatedAt)->toBeNull();
|
|
});
|
|
|
|
it('returns CouponNotFound when the code is not found', function (): void {
|
|
// GIVEN
|
|
$code = new CouponCode('COU02');
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCode')->once()->with($code)->andReturn(null);
|
|
|
|
$brandRepository = \Mockery::mock(BrandRepository::class);
|
|
$brandRepository->shouldNotReceive('existsByCode');
|
|
|
|
$campaignRepository = \Mockery::mock(CampaignRepository::class);
|
|
$campaignRepository->shouldNotReceive('findByCouponCode');
|
|
|
|
$useCase = new FindCoupon($couponRepository, $brandRepository, $campaignRepository);
|
|
|
|
// WHEN
|
|
$result = $useCase->execute(new Input(code: $code));
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CouponNotFound::class);
|
|
});
|
|
|
|
it('throws when the brand of the coupon is not found', function () use ($coupon): void {
|
|
// GIVEN
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCode')->once()->with($coupon->code)->andReturn($coupon);
|
|
|
|
$brandRepository = \Mockery::mock(BrandRepository::class);
|
|
$brandRepository->shouldReceive('existsByCode')->once()->with($coupon->brandCode)->andReturnFalse();
|
|
|
|
$campaignRepository = \Mockery::mock(CampaignRepository::class);
|
|
$campaignRepository->shouldNotReceive('findByCouponCode');
|
|
|
|
$useCase = new FindCoupon($couponRepository, $brandRepository, $campaignRepository);
|
|
|
|
// WHEN / THEN
|
|
expect($useCase->execute(new Input(code: $coupon->code)))
|
|
->toBeInstanceOf(BrandNotFound::class);
|
|
});
|
|
|
|
it('finds a coupon not attached to any campaign', function () use ($coupon): void {
|
|
// GIVEN
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCode')->once()->with($coupon->code)->andReturn($coupon);
|
|
|
|
$brandRepository = \Mockery::mock(BrandRepository::class);
|
|
$brandRepository->shouldReceive('existsByCode')->once()->with($coupon->brandCode)->andReturnTrue();
|
|
|
|
$campaignRepository = \Mockery::mock(CampaignRepository::class);
|
|
$campaignRepository->shouldReceive('findByCouponCode')->once()->with($coupon->code)->andReturn([]);
|
|
|
|
$useCase = new FindCoupon($couponRepository, $brandRepository, $campaignRepository);
|
|
|
|
// WHEN
|
|
$result = $useCase->execute(new Input(code: $coupon->code));
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CouponFound::class)
|
|
->and($result->campaigns)->toBe([]);
|
|
});
|
|
});
|