shouldReceive('findByCode')->once()->with($code)->andReturn(null); $repository->shouldNotReceive('save'); $couponRepository = \Mockery::mock(CouponRepository::class); $couponRepository->shouldNotReceive('findByCodes'); $useCase = new AutoUnpublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository)); // WHEN $result = $useCase->execute(new AutoUnpublishCampaignInput($code)); // THEN expect($result)->toBeInstanceOf(CampaignNotFound::class); }); it('skips an already unpublished campaign without querying coupons', function (): void { // GIVEN $campaign = CampaignFactory::hydrated(published: false); $repository = \Mockery::mock(CampaignRepository::class); $repository->shouldReceive('findByCode')->once()->with($campaign->code)->andReturn($campaign); $repository->shouldNotReceive('save'); $couponRepository = \Mockery::mock(CouponRepository::class); $couponRepository->shouldNotReceive('findByCodes'); $useCase = new AutoUnpublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository)); // WHEN $result = $useCase->execute(new AutoUnpublishCampaignInput($campaign->code)); // THEN expect($result)->toBeInstanceOf(CampaignUnpublicationSkipped::class); }); it('skips a published campaign that still has an active coupon', function (): void { // GIVEN $couponCode = CouponCode::generate(); $campaign = CampaignFactory::hydrated(published: true, couponCodes: [$couponCode]); $repository = \Mockery::mock(CampaignRepository::class); $repository->shouldReceive('findByCode')->once()->with($campaign->code)->andReturn($campaign); $repository->shouldNotReceive('save'); $couponRepository = \Mockery::mock(CouponRepository::class); $couponRepository->shouldReceive('findByCodes')->once()->andReturn([CouponFactory::make()]); $useCase = new AutoUnpublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository)); // WHEN $result = $useCase->execute(new AutoUnpublishCampaignInput($campaign->code)); // THEN expect($result)->toBeInstanceOf(CampaignUnpublicationSkipped::class); }); it('skips a published campaign with one active and one expired coupon', function (): void { // GIVEN $campaign = CampaignFactory::hydrated(published: true, couponCodes: [CouponCode::generate(), CouponCode::generate()]); $repository = \Mockery::mock(CampaignRepository::class); $repository->shouldReceive('findByCode')->once()->with($campaign->code)->andReturn($campaign); $repository->shouldNotReceive('save'); $couponRepository = \Mockery::mock(CouponRepository::class); $couponRepository->shouldReceive('findByCodes')->once()->andReturn([ CouponFactory::expired(), CouponFactory::make(), ]); $useCase = new AutoUnpublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository)); // WHEN $result = $useCase->execute(new AutoUnpublishCampaignInput($campaign->code)); // THEN expect($result)->toBeInstanceOf(CampaignUnpublicationSkipped::class); }); it('unpublishes a published campaign when every coupon is not available', function (): void { // GIVEN $couponCode1 = CouponCode::generate(); $couponCode2 = CouponCode::generate(); $campaign = CampaignFactory::hydrated(published: true, couponCodes: [$couponCode1->value, $couponCode2->value]); $repository = \Mockery::mock(CampaignRepository::class); $repository->shouldReceive('findByCode')->once()->with($campaign->code)->andReturn($campaign); $repository->shouldReceive('save')->once()->with(\Mockery::on( static fn (Campaign $saved): bool => $saved->publication === false && $saved->code === $campaign->code && $saved->updatedAt() instanceof \DateTimeInterface, )); $couponRepository = \Mockery::mock(CouponRepository::class); $couponRepository->shouldReceive('findByCodes')->once()->andReturn([ CouponFactory::expired(), CouponFactory::upcoming(), ]); $useCase = new AutoUnpublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository)); // WHEN $result = $useCase->execute(new AutoUnpublishCampaignInput($campaign->code)); // THEN expect($result)->toBeInstanceOf(CampaignStatusUpdated::class) ->and($result->publication)->toBeFalse() ->and($result->code)->toBe($campaign->code) ->and($result->name)->toBe($campaign->name) ->and($result->brandCode)->toBe($campaign->brandCode) ->and($result->coupons)->toBe($campaign->coupons); }); it('unpublishes a published campaign when no coupon is found', function (): void { // GIVEN $couponCode = CouponCode::generate(); $campaign = CampaignFactory::hydrated(published: true, couponCodes: [$couponCode]); $repository = \Mockery::mock(CampaignRepository::class); $repository->shouldReceive('findByCode')->once()->with($campaign->code)->andReturn($campaign); $repository->shouldReceive('save')->once()->with(\Mockery::on( static fn (Campaign $saved): bool => $saved->publication === false, )); $couponRepository = \Mockery::mock(CouponRepository::class); $couponRepository->shouldReceive('findByCodes')->once()->andReturn([]); $useCase = new AutoUnpublishCampaign($repository, new CampaignAvailabilityChecker($couponRepository)); // WHEN $result = $useCase->execute(new AutoUnpublishCampaignInput($campaign->code)); // THEN expect($result)->toBeInstanceOf(CampaignStatusUpdated::class) ->and($result->publication)->toBeFalse(); }); });