176 lines
7.6 KiB
PHP
176 lines
7.6 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\Inputs\PublishCampaignInput;
|
|
use Application\UseCases\Campaign\Update\Outputs\CampaignStatusUpdated;
|
|
use Application\UseCases\Campaign\Update\Outputs\NotEnoughCouponAvailable;
|
|
use Application\UseCases\Campaign\Update\PublishCampaign;
|
|
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 Domain\Services\Campaign\CampaignAvailabilityChecker;
|
|
use Tests\Fixtures\Coupon\CouponFactory;
|
|
|
|
covers(PublishCampaign::class, PublishCampaignInput::class, CampaignStatusUpdated::class, CampaignNotFound::class);
|
|
|
|
describe('update campaign publication use case', function (): void {
|
|
$campaignCoupon1 = new CampaignCoupon(CouponCode::generate(), new PrintRules(maxPerCustomer: 1));
|
|
$campaignCoupon2 = new CampaignCoupon(CouponCode::generate(), 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()
|
|
);
|
|
|
|
it('unpublish a published campaign', function () use ($existingCampaign): void {
|
|
// GIVEN
|
|
$code = CampaignCode::generate();
|
|
$campaign = $existingCampaign($code, true);
|
|
$publication = false;
|
|
$input = new PublishCampaignInput(code: $campaign->code, publication: $publication);
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->with($code)->andReturn($campaign);
|
|
$repository->shouldReceive('save')->once()->with(\Mockery::on(
|
|
fn (Campaign $saved): bool => $saved->publication === $publication
|
|
&& $saved->code === $campaign->code
|
|
&& $saved->name === $campaign->name,
|
|
));
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
|
|
$useCase = new PublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository));
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CampaignStatusUpdated::class)
|
|
->and($result->publication)->toBeFalse();
|
|
});
|
|
|
|
it('publish an unpublished campaign', function () use ($existingCampaign): void {
|
|
// GIVEN
|
|
$code = CampaignCode::generate();
|
|
$campaign = $existingCampaign($code, false);
|
|
$publication = true;
|
|
$input = new PublishCampaignInput(code: $campaign->code, publication: $publication);
|
|
$expectedCoupons = [
|
|
CouponFactory::make(),
|
|
CouponFactory::make(),
|
|
CouponFactory::expired(),
|
|
];
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->with($code)->andReturn($campaign);
|
|
$repository->shouldReceive('save')->once()->with(\Mockery::on(
|
|
fn (Campaign $saved): bool => $saved->publication === $publication
|
|
&& $saved->code === $campaign->code
|
|
&& $saved->name === $campaign->name,
|
|
));
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCodes')->once()->with($campaign->coupons->getCouponCodes())->andReturn($expectedCoupons);
|
|
|
|
$useCase = new PublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository));
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CampaignStatusUpdated::class)
|
|
->and($result->publication)->toBeTrue();
|
|
});
|
|
|
|
it('returns a CampaignNotFound output when the campaign is not found', function (): void {
|
|
// GIVEN
|
|
$code = CampaignCode::generate();
|
|
$publication = true;
|
|
$input = new PublishCampaignInput(code: $code, publication: $publication);
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->with($code)->andReturn(null);
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
|
|
$useCase = new PublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository));
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(CampaignNotFound::class);
|
|
});
|
|
|
|
it('returns a specific output when there is no available coupons in the campaign', function () use ($existingCampaign): void {
|
|
// GIVEN
|
|
$code = CampaignCode::generate();
|
|
$campaign = $existingCampaign($code, false);
|
|
$publication = true;
|
|
$input = new PublishCampaignInput(code: $campaign->code, publication: $publication);
|
|
$expectedCoupons = [
|
|
CouponFactory::expired(),
|
|
CouponFactory::upcoming(),
|
|
];
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->with($code)->andReturn($campaign);
|
|
$repository->shouldNotReceive('save');
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCodes')->once()->with($campaign->coupons->getCouponCodes())->andReturn($expectedCoupons);
|
|
|
|
$useCase = new PublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository));
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(NotEnoughCouponAvailable::class);
|
|
});
|
|
|
|
it('returns a NotEnoughCouponAvailable output when there is no available coupons in the campaign', function () use ($existingCampaign): void {
|
|
// GIVEN
|
|
$code = CampaignCode::generate();
|
|
$campaign = $existingCampaign($code, false);
|
|
$publication = true;
|
|
$input = new PublishCampaignInput(code: $campaign->code, publication: $publication);
|
|
$expectedCoupons = [];
|
|
|
|
$repository = \Mockery::mock(CampaignRepository::class);
|
|
$repository->shouldReceive('findByCode')->once()->with($code)->andReturn($campaign);
|
|
$repository->shouldNotReceive('save');
|
|
|
|
$couponRepository = \Mockery::mock(CouponRepository::class);
|
|
$couponRepository->shouldReceive('findByCodes')->once()->with($campaign->coupons->getCouponCodes())->andReturn($expectedCoupons);
|
|
|
|
$useCase = new PublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository));
|
|
|
|
// WHEN
|
|
$result = $useCase->execute($input);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(NotEnoughCouponAvailable::class);
|
|
});
|
|
});
|