183 lines
7.4 KiB
PHP
183 lines
7.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit\Application\UseCases\Campaign\Update;
|
|
|
|
use Application\UseCases\Campaign\Outputs\CampaignNotFound;
|
|
use Application\UseCases\Campaign\Update\AddCouponToCampaign;
|
|
use Application\UseCases\Campaign\Update\Inputs\AddCouponToCampaignInput;
|
|
use Application\UseCases\Campaign\Update\Outputs\CampaignUpdated;
|
|
use Application\UseCases\Campaign\Update\Outputs\CouponAlreadyInCampaign;
|
|
use Application\UseCases\Campaign\Update\Outputs\CouponNotActive;
|
|
use Application\UseCases\Campaign\Update\Outputs\CouponNotFound;
|
|
use Domain\Models\Entities\Campaign;
|
|
use Domain\Models\ValueObjects\Actor\ActorId;
|
|
use Domain\Models\ValueObjects\Brand\BrandCode;
|
|
use Domain\Models\ValueObjects\Campaign\CampaignCode;
|
|
use Domain\Models\ValueObjects\Campaign\CampaignCoupon;
|
|
use Domain\Models\ValueObjects\Campaign\CampaignCouponArray;
|
|
use Domain\Models\ValueObjects\Campaign\CampaignId;
|
|
use Domain\Models\ValueObjects\Campaign\CampaignName;
|
|
use Domain\Models\ValueObjects\Coupon\CouponCode;
|
|
use Domain\Models\ValueObjects\PrintRules;
|
|
use Domain\Ports\Repositories\CampaignRepository;
|
|
use Domain\Ports\Repositories\CouponRepository;
|
|
use Shared\Helpers\DatesHelper;
|
|
use Tests\Fixtures\Campaign\CampaignFactory;
|
|
use Tests\Fixtures\Coupon\CouponFactory;
|
|
|
|
covers(
|
|
AddCouponToCampaign::class,
|
|
AddCouponToCampaignInput::class,
|
|
CampaignUpdated::class,
|
|
CampaignNotFound::class,
|
|
CouponNotFound::class,
|
|
CouponAlreadyInCampaign::class,
|
|
CouponNotActive::class,
|
|
);
|
|
|
|
describe('add coupons to campaign use case', function (): void {
|
|
$coupon1 = CouponFactory::make();
|
|
$coupon2 = CouponFactory::make();
|
|
$coupon3 = CouponFactory::make();
|
|
$campaignCoupon1 = new CampaignCoupon($coupon1->code, new PrintRules(maxPerCustomer: 1));
|
|
$campaignCoupon2 = new CampaignCoupon($coupon2->code, new PrintRules(maxPerCustomer: 1));
|
|
$existingCampaign = static fn (CampaignCode $code, bool $basePublicationStatus): Campaign => Campaign::hydrate(
|
|
CampaignId::generate(),
|
|
$code,
|
|
new CampaignName('Name'),
|
|
$basePublicationStatus,
|
|
false,
|
|
new CampaignCouponArray([
|
|
$campaignCoupon1,
|
|
$campaignCoupon2
|
|
]),
|
|
new BrandCode('AAA01'),
|
|
ActorId::generate()
|
|
);
|
|
$printRules = new PrintRules(maxPerCustomer: 1);
|
|
|
|
it('adds a published coupon to a campaign', function () use ($existingCampaign, $coupon3, $printRules): void {
|
|
// GIVEN
|
|
$code = CampaignCode::generate();
|
|
$campaign = $existingCampaign($code, true);
|
|
$input = new AddCouponToCampaignInput(
|
|
code: $campaign->code,
|
|
couponCode: $coupon3->code,
|
|
printRules: $printRules
|
|
);
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->with($campaign->code)->andReturn($campaign);
|
|
$repository->shouldReceive('findCampaignCoupon')->once()->andReturn(null);
|
|
$repository->shouldReceive('save')->once()->with(\Mockery::on(
|
|
static fn (Campaign $saved): bool => count($saved->coupons->toArray()) === 3
|
|
&& $saved->coupons->findCoupon($coupon3->code) instanceof CampaignCoupon,
|
|
));
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCode')->once()->with($coupon3->code)->andReturn($coupon3);
|
|
|
|
$useCase = new AddCouponToCampaign($repository, $couponRepository);
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CampaignUpdated::class)
|
|
->and($result->coupons->toArray())->toHaveCount(3);
|
|
});
|
|
|
|
it('returns a specific error when the coupon is already in the campaign', function () use ($campaignCoupon1, $coupon1): void {
|
|
// GIVEN
|
|
$campaign = CampaignFactory::hydrated(couponCodes: [$coupon1->code]);
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->andReturn($campaign);
|
|
$repository->shouldReceive('findCampaignCoupon')->once()->andReturn($campaignCoupon1);
|
|
$repository->shouldNotReceive('save');
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCode')->once()->andReturn($coupon1);
|
|
|
|
$input = new AddCouponToCampaignInput(code: $campaign->code, couponCode: $coupon1->code, printRules: null);
|
|
|
|
$useCase = new AddCouponToCampaign($repository, $couponRepository);
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CouponAlreadyInCampaign::class);
|
|
});
|
|
|
|
it('returns a specific error when the coupon is not printable', function (): void {
|
|
// WHEN
|
|
$baseCoupon = CouponFactory::make();
|
|
$campaign = CampaignFactory::hydrated(couponCodes: [$baseCoupon->code]);
|
|
$couponToAdd = CouponFactory::make(
|
|
diffusionStart: DatesHelper::now()->subYear()->subMonth()->toDateTime(),
|
|
diffusionEnd: DatesHelper::now()->subYear()->toDateTime()
|
|
);
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->andReturn($campaign);
|
|
$repository->shouldNotReceive('save');
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCode')->once()->andReturn($couponToAdd);
|
|
|
|
$input = new AddCouponToCampaignInput(code: $campaign->code, couponCode: $couponToAdd->code, printRules: null);
|
|
|
|
$useCase = new AddCouponToCampaign($repository, $couponRepository);
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CouponNotActive::class);
|
|
});
|
|
|
|
it('returns a specific error when the campaign is not found', function () use ($coupon1, $printRules): void {
|
|
// GIVEN
|
|
$code = CampaignCode::generate();
|
|
$input = new AddCouponToCampaignInput(code: $code, couponCode: $coupon1->code, printRules: $printRules);
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->with($code)->andReturn(null);
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
|
|
$useCase = new AddCouponToCampaign($repository, $couponRepository);
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CampaignNotFound::class);
|
|
});
|
|
|
|
it('returns a specific error when the coupon is not found', function (): void {
|
|
// GIVEN
|
|
$campaign = CampaignFactory::hydrated();
|
|
$couponCode = CouponCode::generate();
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->andReturn($campaign);
|
|
$repository->shouldNotReceive('save');
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCode')->once()->with($couponCode)->andReturn(null);
|
|
|
|
$input = new AddCouponToCampaignInput(code: $campaign->code, couponCode: $couponCode, printRules: null);
|
|
|
|
$useCase = new AddCouponToCampaign($repository, $couponRepository);
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CouponNotFound::class);
|
|
});
|
|
});
|