ldc-mesbr-app/tests/Unit/Application/UseCases/Campaign/Update/RemoveCouponToCampaignTest.php

176 lines
7 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\RemoveCouponToCampaign;
use Application\UseCases\Campaign\Update\Inputs\RemoveCouponToCampaignInput;
use Application\UseCases\Campaign\Update\Outputs\CampaignUpdated;
use Application\UseCases\Campaign\Update\Outputs\CouponNotFound;
use Application\UseCases\Campaign\Update\Outputs\CouponNotInCampaign;
use Application\UseCases\Campaign\Update\Outputs\NotEnoughCouponInCampaign;
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 Tests\Fixtures\Campaign\CampaignFactory;
use Tests\Fixtures\Coupon\CouponFactory;
covers(
RemoveCouponToCampaign::class,
RemoveCouponToCampaignInput::class,
CampaignUpdated::class,
CampaignNotFound::class,
CouponNotFound::class,
CouponNotInCampaign::class,
NotEnoughCouponInCampaign::class,
);
describe('remove 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));
$campaignCoupon3 = new CampaignCoupon($coupon3->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,
$campaignCoupon3,
]),
new BrandCode('AAA01'),
ActorId::generate()
);
it('removes a coupon from a campaign', function () use (
$existingCampaign,
$coupon2,
$campaignCoupon1,
$campaignCoupon2,
$campaignCoupon3
): void {
// GIVEN
$campaign = $existingCampaign(CampaignCode::generate(), true);
$repository = \Mockery::mock(CampaignRepository::class);
$repository->shouldReceive('findByCode')->once()->andReturn($campaign);
$repository->shouldReceive('findCampaignCoupon')->once()->andReturn($campaignCoupon2);
$repository->shouldReceive('save');
$couponRepository = \Mockery::mock(CouponRepository::class);
$couponRepository->shouldReceive('findByCode')->once()->andReturn($coupon2);
$input = new RemoveCouponToCampaignInput(code: $campaign->code, couponCode: $coupon2->code);
$useCase = new RemoveCouponToCampaign($repository, $couponRepository);
// WHEN
$result = $useCase->execute($input);
// THEN
expect($result)->toBeInstanceOf(CampaignUpdated::class)
->and($result->coupons->toArray())->toHaveCount(2)
->and($result->coupons->toArray()[0])->toBe($campaignCoupon1)
->and($result->coupons->toArray()[1])->toBe($campaignCoupon3);
});
it('returns a specific output when the coupon is not in the campaign', function () use ($existingCampaign): void {
// GIVEN
$campaign = $existingCampaign(CampaignCode::generate(), true);
$coupon = CouponFactory::make();
$repository = \Mockery::mock(CampaignRepository::class);
$repository->shouldReceive('findByCode')->once()->andReturn($campaign);
$repository->shouldReceive('findCampaignCoupon')->once()->andReturn(null);
$repository->shouldReceive('save');
$couponRepository = \Mockery::mock(CouponRepository::class);
$couponRepository->shouldReceive('findByCode')->once()->andReturn($coupon);
$input = new RemoveCouponToCampaignInput(code: $campaign->code, couponCode: $coupon->code);
$useCase = new RemoveCouponToCampaign($repository, $couponRepository);
// WHEN
$result = $useCase->execute($input);
// THEN
expect($result)->toBeInstanceOf(CouponNotInCampaign::class);
});
it('returns a specific output when there is only one coupon in the campaign', function () use ($coupon1): void {
// GIVEN
$campaign = CampaignFactory::hydrated(couponCodes: [$coupon1->code]);
$repository = \Mockery::mock(CampaignRepository::class);
$repository->shouldReceive('findByCode')->once()->andReturn($campaign);
$repository->shouldNotReceive('save');
$couponRepository = \Mockery::mock(CouponRepository::class);
$couponRepository->shouldReceive('findByCode')->once()->andReturn($coupon1);
$input = new RemoveCouponToCampaignInput(code: $campaign->code, couponCode: $coupon1->code);
$useCase = new RemoveCouponToCampaign($repository, $couponRepository);
// WHEN
$result = $useCase->execute(
$input,
);
// THEN
expect($result)->toBeInstanceOf(NotEnoughCouponInCampaign::class);
});
it('returns a specific output when the campaign is not found', function () use ($coupon1): void {
// GIVEN
$code = CampaignCode::generate();
$repository = \Mockery::mock(CampaignRepository::class);
$repository->shouldReceive('findByCode')->once()->with($code)->andReturn(null);
$couponRepository = \Mockery::mock(CouponRepository::class);
$input = new RemoveCouponToCampaignInput(code: $code, couponCode: $coupon1->code);
$useCase = new RemoveCouponToCampaign($repository, $couponRepository);
// WHEN
$result = $useCase->execute($input);
// THEN
expect($result)->toBeInstanceOf(CampaignNotFound::class);
});
it('returns a specific output when the coupon is not found', function (): void {
// GIVEN
$campaign = CampaignFactory::hydrated();
$repository = \Mockery::mock(CampaignRepository::class);
$repository->shouldReceive('findByCode')->once()->andReturn($campaign);
$repository->shouldNotReceive('save');
$couponRepository = \Mockery::mock(CouponRepository::class);
$couponRepository->shouldReceive('findByCode')->once()->andReturn(null);
$input = new RemoveCouponToCampaignInput(code: $campaign->code, couponCode: CouponCode::generate());
$useCase = new RemoveCouponToCampaign($repository, $couponRepository);
// WHEN
$result = $useCase->execute($input);
// THEN
expect($result)->toBeInstanceOf(CouponNotFound::class);
});
});