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); }); });