[Catalog Promotions] Set processing state in listeners instead of in announcer

This commit is contained in:
Kevin Kaniaburka 2022-09-09 07:55:37 +02:00
parent c0cca1e0ff
commit 8867a6fbc2
No known key found for this signature in database
GPG key ID: 8DB4C54474F3FD72
20 changed files with 242 additions and 130 deletions

View file

@ -18,7 +18,6 @@
<!-- ###+ symfony/framework-bundle ### -->
<env name="APP_ENV" value="test"/>
<env name="SHELL_VERBOSITY" value="-1" />
<env name="MESSENGER_TRANSPORT_DSN" value="in-memory://" />
<!-- ###- symfony/framework-bundle ### -->
<server name="IS_DOCTRINE_ORM_SUPPORTED" value="true" />

View file

@ -51,7 +51,6 @@ final class CatalogPromotionContext implements Context
private ChannelRepositoryInterface $channelRepository,
private StateMachineFactoryInterface $stateMachineFactory,
private MessageBusInterface $eventBus,
private MessageBusInterface $commandBus,
private SharedStorageInterface $sharedStorage,
) {
}
@ -74,7 +73,6 @@ final class CatalogPromotionContext implements Context
$catalogPromotion->setEnabled(true);
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionUpdated($catalogPromotion->getCode()));
}
@ -86,7 +84,6 @@ final class CatalogPromotionContext implements Context
$catalogPromotion->setEnabled(false);
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionUpdated($catalogPromotion->getCode()));
}
@ -221,7 +218,6 @@ final class CatalogPromotionContext implements Context
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionCreated($catalogPromotion->getCode()));
}
@ -250,7 +246,6 @@ final class CatalogPromotionContext implements Context
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionCreated($catalogPromotion->getCode()));
}
@ -279,7 +274,6 @@ final class CatalogPromotionContext implements Context
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionCreated($catalogPromotion->getCode()));
}
@ -308,7 +302,6 @@ final class CatalogPromotionContext implements Context
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionCreated($catalogPromotion->getCode()));
}
@ -337,7 +330,6 @@ final class CatalogPromotionContext implements Context
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionCreated($catalogPromotion->getCode()));
}
@ -365,7 +357,6 @@ final class CatalogPromotionContext implements Context
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionCreated($catalogPromotion->getCode()));
}
@ -541,7 +532,6 @@ final class CatalogPromotionContext implements Context
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionCreated($catalogPromotion->getCode()));
}
@ -556,7 +546,6 @@ final class CatalogPromotionContext implements Context
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionUpdated($catalogPromotion->getCode()));
}
@ -707,7 +696,6 @@ final class CatalogPromotionContext implements Context
$catalogPromotion->setEndDate(new \DateTime($endDate));
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionUpdated($catalogPromotion->getCode()));
}
@ -719,7 +707,7 @@ final class CatalogPromotionContext implements Context
$catalogPromotion->setStartDate(new \DateTime($startDate));
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionUpdated($catalogPromotion->getCode()));
}
@ -731,7 +719,6 @@ final class CatalogPromotionContext implements Context
$catalogPromotion->setEndDate(new \DateTime($endDate));
$this->entityManager->flush();
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionUpdated($catalogPromotion->getCode()));
}

View file

@ -296,7 +296,6 @@
<argument type="service" id="sylius.repository.channel" />
<argument type="service" id="sm.factory" />
<argument type="service" id="sylius.event_bus" />
<argument type="service" id="sylius.command_bus" />
<argument type="service" id="sylius.behat.shared_storage" />
</service>
</services>

View file

@ -14,7 +14,6 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\CatalogPromotion\Announcer;
use Sylius\Bundle\CoreBundle\Calculator\DelayStampCalculatorInterface;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Calendar\Provider\DateTimeProviderInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionCreated;
@ -26,7 +25,6 @@ final class CatalogPromotionAnnouncer implements CatalogPromotionAnnouncerInterf
{
public function __construct(
private MessageBusInterface $eventBus,
private MessageBusInterface $commandBus,
private DelayStampCalculatorInterface $delayStampCalculator,
private DateTimeProviderInterface $dateTimeProvider,
) {
@ -34,11 +32,6 @@ final class CatalogPromotionAnnouncer implements CatalogPromotionAnnouncerInterf
public function dispatchCatalogPromotionCreatedEvent(CatalogPromotionInterface $catalogPromotion): void
{
$this->commandBus->dispatch(
new UpdateCatalogPromotionState($catalogPromotion->getCode()),
$this->calculateStartDateStamp($catalogPromotion)
);
$this->eventBus->dispatch(
new CatalogPromotionCreated($catalogPromotion->getCode()),
$this->calculateStartDateStamp($catalogPromotion),
@ -50,15 +43,9 @@ final class CatalogPromotionAnnouncer implements CatalogPromotionAnnouncerInterf
public function dispatchCatalogPromotionUpdatedEvent(CatalogPromotionInterface $catalogPromotion): void
{
if ($catalogPromotion->getStartDate() > $this->dateTimeProvider->now()) {
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionUpdated($catalogPromotion->getCode()));
$this->eventBus->dispatch(new CatalogPromotionUpdated($catalogPromotion->getCode()), []);
}
$this->commandBus->dispatch(
new UpdateCatalogPromotionState($catalogPromotion->getCode()),
$this->calculateStartDateStamp($catalogPromotion)
);
$this->eventBus->dispatch(
new CatalogPromotionUpdated($catalogPromotion->getCode()),
$this->calculateStartDateStamp($catalogPromotion),
@ -79,13 +66,10 @@ final class CatalogPromotionAnnouncer implements CatalogPromotionAnnouncerInterf
private function dispatchCatalogPromotionEndedEvent(CatalogPromotionInterface $catalogPromotion): void
{
if ($catalogPromotion->getEndDate() !== null) {
$delayStamp = $this->delayStampCalculator->calculate(
$this->dateTimeProvider->now(),
$catalogPromotion->getEndDate(),
$this->eventBus->dispatch(
new CatalogPromotionEnded($catalogPromotion->getCode()),
[$this->delayStampCalculator->calculate($this->dateTimeProvider->now(), $catalogPromotion->getEndDate())],
);
$this->commandBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()), [$delayStamp]);
$this->eventBus->dispatch(new CatalogPromotionEnded($catalogPromotion->getCode()), [$delayStamp]);
}
}
}

View file

@ -14,10 +14,11 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\CatalogPromotion\Listener;
use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionCreated;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Messenger\MessageBusInterface;
final class CatalogPromotionCreatedListener
{
@ -25,17 +26,19 @@ final class CatalogPromotionCreatedListener
private AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
private RepositoryInterface $catalogPromotionRepository,
private EntityManagerInterface $entityManager,
private MessageBusInterface $messageBus,
) {
}
public function __invoke(CatalogPromotionCreated $event): void
{
/** @var CatalogPromotionInterface|null $catalogPromotion */
$catalogPromotion = $this->catalogPromotionRepository->findOneBy(['code' => $event->code]);
if (null === $catalogPromotion) {
return;
}
$this->messageBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->allProductVariantsCatalogPromotionsProcessor->process();
$this->entityManager->flush();

View file

@ -14,9 +14,11 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\CatalogPromotion\Listener;
use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionEnded;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Messenger\MessageBusInterface;
final class CatalogPromotionEndedListener
{
@ -24,6 +26,7 @@ final class CatalogPromotionEndedListener
private AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
private RepositoryInterface $catalogPromotionRepository,
private EntityManagerInterface $entityManager,
private MessageBusInterface $messageBus,
) {
}
@ -35,6 +38,7 @@ final class CatalogPromotionEndedListener
return;
}
$this->messageBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->allProductVariantsCatalogPromotionsProcessor->process();
$this->entityManager->flush();

View file

@ -14,9 +14,11 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\CatalogPromotion\Listener;
use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionUpdated;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Messenger\MessageBusInterface;
final class CatalogPromotionUpdatedListener
{
@ -24,6 +26,7 @@ final class CatalogPromotionUpdatedListener
private AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
private RepositoryInterface $catalogPromotionRepository,
private EntityManagerInterface $entityManager,
private MessageBusInterface $messageBus,
) {
}
@ -35,6 +38,7 @@ final class CatalogPromotionUpdatedListener
return;
}
$this->messageBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
$this->allProductVariantsCatalogPromotionsProcessor->process();
$this->entityManager->flush();

View file

@ -37,7 +37,6 @@
class="Sylius\Bundle\CoreBundle\CatalogPromotion\Announcer\CatalogPromotionAnnouncer"
>
<argument type="service" id="sylius.event_bus" />
<argument type="service" id="sylius.command_bus" />
<argument type="service" id="Sylius\Bundle\CoreBundle\Calculator\DelayStampCalculatorInterface" />
<argument type="service" id="Sylius\Calendar\Provider\DateTimeProviderInterface" />
</service>

View file

@ -37,6 +37,7 @@
<argument type="service" id="Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface" />
<argument type="service" id="sylius.repository.catalog_promotion" />
<argument type="service" id="doctrine.orm.entity_manager" />
<argument type="service" id="sylius.command_bus" />
<tag name="messenger.message_handler" bus="sylius.event_bus" />
</service>
@ -44,6 +45,7 @@
<argument type="service" id="Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface" />
<argument type="service" id="sylius.repository.catalog_promotion" />
<argument type="service" id="doctrine.orm.entity_manager" />
<argument type="service" id="sylius.command_bus" />
<tag name="messenger.message_handler" bus="sylius.event_bus" />
</service>
@ -51,6 +53,7 @@
<argument type="service" id="Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface" />
<argument type="service" id="sylius.repository.catalog_promotion" />
<argument type="service" id="doctrine.orm.entity_manager" />
<argument type="service" id="sylius.command_bus" />
<tag name="messenger.message_handler" bus="sylius.event_bus" />
</service>

View file

@ -17,7 +17,6 @@ use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\CoreBundle\Calculator\DelayStampCalculatorInterface;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Announcer\CatalogPromotionAnnouncerInterface;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Calendar\Provider\DateTimeProviderInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionCreated;
@ -31,11 +30,10 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
{
function let(
MessageBusInterface $eventBus,
MessageBusInterface $commandBus,
DelayStampCalculatorInterface $delayStampCalculator,
DateTimeProviderInterface $dateTimeProvider,
): void {
$this->beConstructedWith($eventBus, $commandBus, $delayStampCalculator, $dateTimeProvider);
$this->beConstructedWith($eventBus, $delayStampCalculator, $dateTimeProvider);
}
function it_implements_catalog_promotion_announcer_interface(): void
@ -45,7 +43,6 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
function it_dispatches_catalog_promotion_created_and_catalog_promotion_ended_events(
MessageBusInterface $eventBus,
MessageBusInterface $commandBus,
DelayStampCalculatorInterface $delayStampCalculator,
DateTimeProviderInterface $dateTimeProvider,
CatalogPromotionInterface $catalogPromotion,
@ -65,13 +62,10 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
$delayStampCalculator->calculate(Argument::any(), $startDateTime)->willReturn($startDelayStamp);
$delayStampCalculator->calculate(Argument::any(), $endDateTime)->willReturn($endDelayStamp);
$messageUpdateState = new UpdateCatalogPromotionState('SALE');
$messageCreate = new CatalogPromotionCreated('SALE');
$messageEnd = new CatalogPromotionEnded('SALE');
$commandBus->dispatch($messageUpdateState, [$startDelayStamp])->willReturn(new Envelope($messageUpdateState))->shouldBeCalled();
$eventBus->dispatch($messageCreate, [$startDelayStamp])->willReturn(new Envelope($messageCreate))->shouldBeCalled();
$commandBus->dispatch($messageUpdateState, [$endDelayStamp])->willReturn(new Envelope($messageUpdateState))->shouldBeCalled();
$eventBus->dispatch($messageEnd, [$endDelayStamp])->willReturn(new Envelope($messageEnd))->shouldBeCalled();
$this->dispatchCatalogPromotionCreatedEvent($catalogPromotion);
@ -79,7 +73,6 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
function it_does_not_dispatch_catalog_promotion_ended_when_catalog_promotion_has_no_end_date_configured(
MessageBusInterface $eventBus,
MessageBusInterface $commandBus,
DelayStampCalculatorInterface $delayStampCalculator,
DateTimeProviderInterface $dateTimeProvider,
CatalogPromotionInterface $catalogPromotion,
@ -96,11 +89,9 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
$delayStampCalculator->calculate(Argument::any(), $startDateTime)->willReturn($startDelayStamp);
$messageUpdateState = new UpdateCatalogPromotionState('SALE');
$messageUpdate = new CatalogPromotionCreated('SALE');
$messageEnd = new CatalogPromotionEnded('SALE');
$commandBus->dispatch($messageUpdateState, [$startDelayStamp])->willReturn(new Envelope($messageUpdateState))->shouldBeCalled();
$eventBus->dispatch($messageUpdate, [$startDelayStamp])->willReturn(new Envelope($messageUpdate))->shouldBeCalled();
$eventBus->dispatch($messageEnd, [Argument::any()])->shouldNotBeCalled();
@ -109,7 +100,6 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
function it_dispatches_catalog_promotion_updated_and_catalog_promotion_ended_events(
MessageBusInterface $eventBus,
MessageBusInterface $commandBus,
DelayStampCalculatorInterface $delayStampCalculator,
DateTimeProviderInterface $dateTimeProvider,
CatalogPromotionInterface $catalogPromotion,
@ -129,13 +119,10 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
$delayStampCalculator->calculate(Argument::any(), $startDateTime)->willReturn($startDelayStamp);
$delayStampCalculator->calculate(Argument::any(), $endDateTime)->willReturn($endDelayStamp);
$messageUpdateState = new UpdateCatalogPromotionState('SALE');
$messageUpdate = new CatalogPromotionUpdated('SALE');
$messageEnd = new CatalogPromotionEnded('SALE');
$commandBus->dispatch($messageUpdateState, [$startDelayStamp])->willReturn(new Envelope($messageUpdateState))->shouldBeCalled();
$eventBus->dispatch($messageUpdate, [$startDelayStamp])->willReturn(new Envelope($messageUpdate))->shouldBeCalled();
$commandBus->dispatch($messageUpdateState, [$endDelayStamp])->willReturn(new Envelope($messageUpdateState))->shouldBeCalled();
$eventBus->dispatch($messageEnd, [$endDelayStamp])->willReturn(new Envelope($messageEnd))->shouldBeCalled();
$this->dispatchCatalogPromotionUpdatedEvent($catalogPromotion);
@ -143,7 +130,6 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
function it_dispatches_catalog_promotion_updated_twice_if_catalog_promotion_is_updated_with_delayed_start(
MessageBusInterface $eventBus,
MessageBusInterface $commandBus,
DelayStampCalculatorInterface $delayStampCalculator,
DateTimeProviderInterface $dateTimeProvider,
CatalogPromotionInterface $catalogPromotion,
@ -163,15 +149,11 @@ final class CatalogPromotionAnnouncerSpec extends ObjectBehavior
$delayStampCalculator->calculate(Argument::any(), $startDateTime)->willReturn($startDelayStamp);
$delayStampCalculator->calculate(Argument::any(), $endDateTime)->willReturn($endDelayStamp);
$messageUpdateState = new UpdateCatalogPromotionState('SALE');
$messageUpdate = new CatalogPromotionUpdated('SALE');
$messageEnd = new CatalogPromotionEnded('SALE');
$commandBus->dispatch($messageUpdateState)->willReturn(new Envelope($messageUpdateState))->shouldBeCalled();
$eventBus->dispatch($messageUpdate)->willReturn(new Envelope($messageUpdate))->shouldBeCalled();
$commandBus->dispatch($messageUpdateState, [$startDelayStamp])->willReturn(new Envelope($messageUpdateState))->shouldBeCalled();
$eventBus->dispatch($messageUpdate, [])->willReturn(new Envelope($messageUpdate))->shouldBeCalled();
$eventBus->dispatch($messageUpdate, [$startDelayStamp])->willReturn(new Envelope($messageUpdate))->shouldBeCalled();
$commandBus->dispatch($messageUpdateState, [$endDelayStamp])->willReturn(new Envelope($messageEnd))->shouldBeCalled();
$eventBus->dispatch($messageEnd, [$endDelayStamp])->willReturn(new Envelope($messageEnd))->shouldBeCalled();
$this->dispatchCatalogPromotionUpdatedEvent($catalogPromotion);

View file

@ -15,10 +15,15 @@ namespace spec\Sylius\Bundle\CoreBundle\CatalogPromotion\Listener;
use Doctrine\ORM\EntityManagerInterface;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\CatalogPromotion\CommandDispatcher\UpdateCatalogPromotionStateCommandDispatcherInterface;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionCreated;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
final class CatalogPromotionCreatedListenerSpec extends ObjectBehavior
{
@ -26,18 +31,34 @@ final class CatalogPromotionCreatedListenerSpec extends ObjectBehavior
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
): void {
$this->beConstructedWith($allProductVariantsCatalogPromotionsProcessor, $catalogPromotionRepository, $entityManager);
$this->beConstructedWith(
$allProductVariantsCatalogPromotionsProcessor,
$catalogPromotionRepository,
$entityManager,
$messageBus,
);
}
function it_processes_catalog_promotion_that_has_just_been_created(
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
CatalogPromotionInterface $catalogPromotion,
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn($catalogPromotion);
$catalogPromotion->getCode()->willReturn('WINTER_MUGS_SALE');
$updateCatalogPromotionStateCommand = new UpdateCatalogPromotionState('WINTER_MUGS_SALE');
$messageBus
->dispatch($updateCatalogPromotionStateCommand)
->willReturn(new Envelope($updateCatalogPromotionStateCommand))
->shouldBeCalled()
;
$allProductVariantsCatalogPromotionsProcessor->process()->shouldBeCalled();
$entityManager->flush()->shouldBeCalled();
@ -48,9 +69,11 @@ final class CatalogPromotionCreatedListenerSpec extends ObjectBehavior
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn(null);
$messageBus->dispatch(Argument::any())->shouldNotBeCalled();
$allProductVariantsCatalogPromotionsProcessor->process()->shouldNotBeCalled();
$entityManager->flush()->shouldNotBeCalled();

View file

@ -15,10 +15,14 @@ namespace spec\Sylius\Bundle\CoreBundle\CatalogPromotion\Listener;
use Doctrine\ORM\EntityManagerInterface;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionEnded;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
final class CatalogPromotionEndedListenerSpec extends ObjectBehavior
{
@ -26,18 +30,34 @@ final class CatalogPromotionEndedListenerSpec extends ObjectBehavior
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
): void {
$this->beConstructedWith($allProductVariantsCatalogPromotionsProcessor, $catalogPromotionRepository, $entityManager);
$this->beConstructedWith(
$allProductVariantsCatalogPromotionsProcessor,
$catalogPromotionRepository,
$entityManager,
$messageBus,
);
}
function it_processes_catalog_promotion_that_has_just_ended(
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
CatalogPromotionInterface $catalogPromotion,
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn($catalogPromotion);
$catalogPromotion->getCode()->willReturn('WINTER_MUGS_SALE');
$updateCatalogPromotionStateCommand = new UpdateCatalogPromotionState('WINTER_MUGS_SALE');
$messageBus
->dispatch($updateCatalogPromotionStateCommand)
->willReturn(new Envelope($updateCatalogPromotionStateCommand))
->shouldBeCalled()
;
$allProductVariantsCatalogPromotionsProcessor->process()->shouldBeCalled();
$entityManager->flush()->shouldBeCalled();
@ -49,10 +69,12 @@ final class CatalogPromotionEndedListenerSpec extends ObjectBehavior
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn(null);
$catalogPromotionRepository->findAll()->shouldNotBeCalled();
$messageBus->dispatch(Argument::any())->shouldNotBeCalled();
$allProductVariantsCatalogPromotionsProcessor->process()->shouldNotBeCalled();
$entityManager->flush()->shouldNotBeCalled();

View file

@ -15,10 +15,14 @@ namespace spec\Sylius\Bundle\CoreBundle\CatalogPromotion\Listener;
use Doctrine\ORM\EntityManagerInterface;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Processor\AllProductVariantsCatalogPromotionsProcessorInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionUpdated;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
final class CatalogPromotionUpdatedListenerSpec extends ObjectBehavior
{
@ -26,18 +30,34 @@ final class CatalogPromotionUpdatedListenerSpec extends ObjectBehavior
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
): void {
$this->beConstructedWith($allProductVariantsCatalogPromotionsProcessor, $catalogPromotionRepository, $entityManager);
$this->beConstructedWith(
$allProductVariantsCatalogPromotionsProcessor,
$catalogPromotionRepository,
$entityManager,
$messageBus,
);
}
function it_processes_catalog_promotion_that_has_just_been_updated(
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
CatalogPromotionInterface $catalogPromotion,
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn($catalogPromotion);
$catalogPromotion->getCode()->willReturn('WINTER_MUGS_SALE');
$updateCatalogPromotionStateCommand = new UpdateCatalogPromotionState('WINTER_MUGS_SALE');
$messageBus
->dispatch($updateCatalogPromotionStateCommand)
->willReturn(new Envelope($updateCatalogPromotionStateCommand))
->shouldBeCalled()
;
$allProductVariantsCatalogPromotionsProcessor->process()->shouldBeCalled();
$entityManager->flush()->shouldBeCalled();
@ -49,10 +69,12 @@ final class CatalogPromotionUpdatedListenerSpec extends ObjectBehavior
AllProductVariantsCatalogPromotionsProcessorInterface $allProductVariantsCatalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn(null);
$catalogPromotionRepository->findAll()->shouldNotBeCalled();
$messageBus->dispatch(Argument::any())->shouldNotBeCalled();
$allProductVariantsCatalogPromotionsProcessor->process()->shouldNotBeCalled();
$entityManager->flush()->shouldNotBeCalled();

View file

@ -3,27 +3,4 @@ Sylius\Component\Core\Model\CatalogPromotion:
code: sale1
name: Sale1
enabled: true
start_date: "<(new \\DateTime('2021-10-12 00:00:00'))>"
end_date: "<(new \\DateTime('2021-10-12 23:59:58'))>"
state: inactive
sale_2:
code: sale2
name: Sale2
enabled: true
start_date: "<(new \\DateTime('2021-10-12 00:00:01'))>"
end_date: "<(new \\DateTime('2021-10-12 23:59:58'))>"
state: inactive
sale_3:
code: sale3
name: Sale3
enabled: true
start_date: "<(new \\DateTime('2021-10-12 00:00:02'))>"
end_date: "<(new \\DateTime('2021-10-12 23:59:59'))>"
state: inactive
sale_4:
code: sale4
name: Sale4
enabled: true
start_date: "<(new \\DateTime('2021-10-12 00:00:03'))>"
end_date: "<(new \\DateTime('2021-10-12 23:59:59'))>"
state: inactive

View file

@ -0,0 +1,29 @@
Sylius\Component\Core\Model\CatalogPromotion:
sale_1:
code: sale1
name: Sale1
enabled: true
start_date: "<(new \\DateTime('2021-10-12 00:00:00'))>"
end_date: "<(new \\DateTime('2021-10-12 23:59:58'))>"
state: inactive
sale_2:
code: sale2
name: Sale2
enabled: true
start_date: "<(new \\DateTime('2021-10-12 00:00:01'))>"
end_date: "<(new \\DateTime('2021-10-12 23:59:58'))>"
state: inactive
sale_3:
code: sale3
name: Sale3
enabled: true
start_date: "<(new \\DateTime('2021-10-12 00:00:02'))>"
end_date: "<(new \\DateTime('2021-10-12 23:59:59'))>"
state: inactive
sale_4:
code: sale4
name: Sale4
enabled: true
start_date: "<(new \\DateTime('2021-10-12 00:00:03'))>"
end_date: "<(new \\DateTime('2021-10-12 23:59:59'))>"
state: inactive

View file

@ -0,0 +1,57 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Tests\Functional;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\KernelInterface;
abstract class AbstractWebTestCase extends BaseWebTestCase
{
public static function setUpBeforeClass(): void
{
static::deleteTmpDir();
}
public static function tearDownAfterClass(): void
{
static::deleteTmpDir();
}
protected static function deleteTmpDir()
{
if (!file_exists($dir = sys_get_temp_dir() . '/sylius_functional_tests')) {
return;
}
$fs = new Filesystem();
$fs->remove($dir);
}
protected static function createKernel(array $options = []): KernelInterface
{
$class = self::getKernelClass();
return new $class(
$options['environment'] ?? $_ENV['APP_ENV'] ?? $_SERVER['APP_ENV'] ?? 'test',
(bool) ($options['debug'] ?? $_ENV['APP_DEBUG'] ?? $_SERVER['APP_DEBUG'] ?? false),
$options['test_case'] ?? null,
);
}
protected static function getKernelClass(): string
{
return 'Sylius\Tests\Functional\app\AppKernel';
}
}

View file

@ -16,62 +16,37 @@ namespace Sylius\Tests\Functional;
use Fidry\AliceDataFixtures\LoaderInterface;
use Fidry\AliceDataFixtures\Persistence\PurgeMode;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Announcer\CatalogPromotionAnnouncer;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Component\Core\Model\CatalogPromotion;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionCreated;
use Sylius\Component\Promotion\Event\CatalogPromotionEnded;
use Sylius\Component\Promotion\Event\CatalogPromotionUpdated;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Messenger\Transport\InMemoryTransport;
class CatalogPromotionAnnouncerTest extends WebTestCase
final class CatalogPromotionAnnouncerTest extends AbstractWebTestCase
{
/** @var Client */
private static $client;
protected function setUp(): void
/** @test */
public function it_puts_catalog_promotion_into_processing_state(): void
{
self::$client = static::createClient();
self::$container = self::$client->getContainer();
$this->createClient(['test_case' => 'CatalogPromotionProcessingState']);
$catalogPromotion = $this->getCatalogPromotion();
/** @var CatalogPromotionAnnouncer $catalogPromotionAnnouncer */
$catalogPromotionAnnouncer = self::$container->get('Sylius\Bundle\CoreBundle\CatalogPromotion\Announcer\CatalogPromotionAnnouncerInterface');
$catalogPromotionAnnouncer->dispatchCatalogPromotionCreatedEvent($catalogPromotion);
$this->assertSame('processing', $catalogPromotion->getState());
}
/** @test */
public function it_announces_catalog_promotion_has_been_created_and_updates_its_state_during_that_process(): void
public function it_activates_catalog_promotion_when_processing_has_been_finished(): void
{
$this->createClient();
$catalogPromotion = $this->getCatalogPromotion();
/** @var CatalogPromotionAnnouncer $catalogPromotionAnnouncer */
$catalogPromotionAnnouncer = self::$container->get('Sylius\Bundle\CoreBundle\CatalogPromotion\Announcer\CatalogPromotionAnnouncerInterface');
$catalogPromotionAnnouncer->dispatchCatalogPromotionCreatedEvent($catalogPromotion);
$catalogPromotionAnnouncer->dispatchCatalogPromotionCreatedEvent($this->getCatalogPromotion());
/* @var InMemoryTransport $transport */
$transport = $this->getContainer()->get('messenger.transport.main');
$this->assertCount(4, $transport->getSent());
$this->assertInstanceOf(UpdateCatalogPromotionState::class, $transport->getSent()[0]->getMessage());
$this->assertInstanceOf(CatalogPromotionCreated::class, $transport->getSent()[1]->getMessage());
$this->assertInstanceOf(UpdateCatalogPromotionState::class, $transport->getSent()[2]->getMessage());
$this->assertInstanceOf(CatalogPromotionEnded::class, $transport->getSent()[3]->getMessage());
}
/** @test */
public function it_announces_catalog_promotion_has_been_updated_and_updates_its_state_during_that_process(): void
{
/** @var CatalogPromotionAnnouncer $catalogPromotionAnnouncer */
$catalogPromotionAnnouncer = self::$container->get('Sylius\Bundle\CoreBundle\CatalogPromotion\Announcer\CatalogPromotionAnnouncerInterface');
$catalogPromotionAnnouncer->dispatchCatalogPromotionUpdatedEvent($this->getCatalogPromotion());
/* @var InMemoryTransport $transport */
$transport = $this->getContainer()->get('messenger.transport.main');
$this->assertCount(4, $transport->getSent());
$this->assertInstanceOf(UpdateCatalogPromotionState::class, $transport->getSent()[0]->getMessage());
$this->assertInstanceOf(CatalogPromotionUpdated::class, $transport->getSent()[1]->getMessage());
$this->assertInstanceOf(UpdateCatalogPromotionState::class, $transport->getSent()[2]->getMessage());
$this->assertInstanceOf(CatalogPromotionEnded::class, $transport->getSent()[3]->getMessage());
$this->assertSame('active', $catalogPromotion->getState());
}
private function getCatalogPromotion(): CatalogPromotionInterface
@ -79,6 +54,7 @@ class CatalogPromotionAnnouncerTest extends WebTestCase
/** @var LoaderInterface $fixtureLoader */
$fixtureLoader = self::$container->get('fidry_alice_data_fixtures.loader.doctrine');
$fixtures = $fixtureLoader->load([__DIR__ . '/../DataFixtures/ORM/resources/catalog_promotions.yml'], [], [], PurgeMode::createDeleteMode());
/** @var CatalogPromotion $catalogPromotion */
$catalogPromotion = $fixtures['sale_1'];

View file

@ -38,7 +38,7 @@ class EligibleCatalogPromotionsProcessorTest extends WebTestCase
/** @var LoaderInterface $fixtureLoader */
$fixtureLoader = self::$container->get('fidry_alice_data_fixtures.loader.doctrine');
$fixtureLoader->load([__DIR__ . '/../DataFixtures/ORM/resources/catalog_promotions.yml'], [], [], PurgeMode::createDeleteMode());
$fixtureLoader->load([__DIR__ . '/../DataFixtures/ORM/resources/scheduled_catalog_promotions.yml'], [], [], PurgeMode::createDeleteMode());
}
/** @test */

View file

@ -0,0 +1,39 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Tests\Functional\app;
use Symfony\Component\Config\Loader\LoaderInterface;
use App\Kernel;
class AppKernel extends Kernel
{
public function __construct(string $environment, bool $debug, private ?string $testCase = null)
{
parent::__construct($environment, $debug);
}
public function getCacheDir(): string
{
return sys_get_temp_dir() . sprintf('/sylius_functional_tests/%s/cache/%s', $this->testCase ?? '', $this->environment);
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
parent::registerContainerConfiguration($loader);
if (null !== $this->testCase) {
$loader->load(__DIR__ . sprintf('/%s/config.yml', $this->testCase));
}
}
}

View file

@ -0,0 +1,3 @@
services:
Sylius\Bundle\CoreBundle\CatalogPromotion\Listener\CatalogPromotionCreatedListener:
class: stdClass