mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 09:02:12 +00:00
feature #14875 [PriceHistory] Add removing price history command feature (TheMilek)
This PR was merged into the 1.13 branch.
Discussion
----------
| Q | A |
|-----------------|--------------------------------------------------------------|
| Branch? | 1.13 <!-- see the comment below --> |
| Bug fix? | no |
| New feature? | yes |
| BC breaks? | no |
| Deprecations? | no <!-- don't forget to update the UPGRADE-*.md file --> |
| License | MIT |
<!--
- Bug fixes must be submitted against the 1.12 branch
- Features and deprecations must be submitted against the 1.13 branch
- Make sure that the correct base branch is set
To be sure you are not breaking any Backward Compatibilities, check the documentation:
https://docs.sylius.com/en/latest/book/organization/backward-compatibility-promise.html
-->
Commits
-------
11bc4d7117 [PriceHistory] Add removing price history command feature
This commit is contained in:
commit
8c2dcb29c3
14 changed files with 584 additions and 3 deletions
|
|
@ -14,18 +14,18 @@ Feature: Deleting old channel pricing entry logs
|
|||
And on "2022-04-20" its original price has been removed
|
||||
And it is "2022-04-29" now
|
||||
|
||||
@todo @domain
|
||||
@domain
|
||||
Scenario: Deleting price history older than 90 days
|
||||
When I delete price history older than 90 days
|
||||
Then there should be 5 price history entries for this product
|
||||
|
||||
@todo @domain
|
||||
@domain
|
||||
Scenario: Deleting price history older than 30 days
|
||||
When I delete price history older than 30 days
|
||||
Then there should be 2 price history entries for this product
|
||||
And this product should have no entry with original price changed to "$25.00"
|
||||
|
||||
@todo @domain
|
||||
@domain
|
||||
Scenario: Deleting price history older than 1 day
|
||||
When I delete price history older than 1 day
|
||||
Then this product's price history should be empty
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
<?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\Behat\Context\Domain;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface;
|
||||
use Sylius\Component\Core\Model\ChannelPricingInterface;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
use Sylius\Component\Product\Resolver\ProductVariantResolverInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final class ManagingPriceHistoryContext implements Context
|
||||
{
|
||||
public function __construct(
|
||||
private RepositoryInterface $channelPricingLogEntryRepository,
|
||||
private ProductVariantResolverInterface $variantResolver,
|
||||
private ChannelPricingLogEntriesRemoverInterface $channelPricingLogEntriesRemover,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I delete price history older than :days day(s)
|
||||
*/
|
||||
public function iDeletePriceHistoryOlderThanDays(int $days): void
|
||||
{
|
||||
$this->channelPricingLogEntriesRemover->remove($days);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^there should be (\d+) price history entries for (this product)$/
|
||||
*/
|
||||
public function thereShouldBeCountPriceHistoryEntriesForThisProduct(int $count, ProductInterface $product): void
|
||||
{
|
||||
$channelPricingLogEntries = $this->channelPricingLogEntryRepository->findBy([
|
||||
'channelPricing' => $this->getChannelPricingFromProduct($product),
|
||||
]);
|
||||
|
||||
Assert::count($channelPricingLogEntries, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(this product) should have no entry with original price changed to ("[^"]+")$/
|
||||
*/
|
||||
public function thisProductShouldHaveNoEntryWithOriginalPriceChangedTo(
|
||||
ProductInterface $product,
|
||||
int $originalPrice,
|
||||
): void {
|
||||
Assert::null($this->channelPricingLogEntryRepository->findOneBy([
|
||||
'channelPricing' => $this->getChannelPricingFromProduct($product),
|
||||
'originalPrice' => $originalPrice,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(this product)'s price history should be empty$/
|
||||
*/
|
||||
public function thisProductsPriceHistoryShouldBeEmpty(ProductInterface $product): void
|
||||
{
|
||||
$this->thereShouldBeCountPriceHistoryEntriesForThisProduct(0, $product);
|
||||
}
|
||||
|
||||
private function getChannelPricingFromProduct(ProductInterface $product): ChannelPricingInterface
|
||||
{
|
||||
$variant = $this->variantResolver->getVariant($product);
|
||||
Assert::notNull($variant);
|
||||
|
||||
$channelPricing = $variant->getChannelPricings()->first();
|
||||
Assert::isInstanceOf($channelPricing, ChannelPricingInterface::class);
|
||||
|
||||
return $channelPricing;
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,12 @@
|
|||
<argument type="service" id="sylius.repository.payment"/>
|
||||
</service>
|
||||
|
||||
<service id="Sylius\Behat\Context\Domain\ManagingPriceHistoryContext">
|
||||
<argument type="service" id="sylius.repository.channel_pricing_log_entry" />
|
||||
<argument type="service" id="sylius.product_variant_resolver.default" />
|
||||
<argument type="service" id="Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.behat.context.domain.managing_products" class="Sylius\Behat\Context\Domain\ManagingProductsContext">
|
||||
<argument type="service" id="sylius.behat.shared_storage" />
|
||||
<argument type="service" id="sylius.repository.product" />
|
||||
|
|
|
|||
|
|
@ -134,6 +134,12 @@
|
|||
|
||||
</service>
|
||||
|
||||
<service id="Sylius\Behat\Context\Setup\PriceHistoryContext">
|
||||
<argument type="service" id="Sylius\Calendar\Tests\Behat\Context\Setup\CalendarContext" />
|
||||
<argument type="service" id="sylius.manager.channel_pricing" />
|
||||
<argument type="service" id="sylius.product_variant_resolver.default" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.behat.context.setup.product" class="Sylius\Behat\Context\Setup\ProductContext">
|
||||
<argument type="service" id="sylius.behat.shared_storage" />
|
||||
<argument type="service" id="sylius.repository.product" />
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ imports:
|
|||
|
||||
- suites/domain/cart/shopping_cart.yml
|
||||
- suites/domain/order/managing_orders.yml
|
||||
- suites/domain/product/managing_price_history.yml
|
||||
- suites/domain/product/managing_product_variants.yml
|
||||
- suites/domain/product/managing_products.yml
|
||||
- suites/domain/promotion/managing_promotion_coupons.yml
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
# This file is part of the Sylius package.
|
||||
# (c) Paweł Jędrzejewski
|
||||
|
||||
default:
|
||||
suites:
|
||||
domain_managing_price_history:
|
||||
contexts:
|
||||
- sylius.behat.context.hook.doctrine_orm
|
||||
|
||||
- sylius.behat.context.transform.channel
|
||||
- sylius.behat.context.transform.lexical
|
||||
- sylius.behat.context.transform.product
|
||||
- sylius.behat.context.transform.shared_storage
|
||||
|
||||
- sylius.behat.context.setup.channel
|
||||
- sylius.behat.context.setup.product
|
||||
- Sylius\Behat\Context\Setup\PriceHistoryContext
|
||||
- Sylius\Calendar\Tests\Behat\Context\Setup\CalendarContext
|
||||
|
||||
- Sylius\Behat\Context\Domain\ManagingPriceHistoryContext
|
||||
filters:
|
||||
tags: "@managing_price_history&&@domain"
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?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\Bundle\CoreBundle\PriceHistory\Command;
|
||||
|
||||
use Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
#[AsCommand(
|
||||
name: 'sylius:price-history:clear',
|
||||
description: 'Clears the price history up to a given number of days ago',
|
||||
)]
|
||||
final class ClearPriceHistoryCommand extends Command
|
||||
{
|
||||
private SymfonyStyle $io;
|
||||
|
||||
public function __construct(private ChannelPricingLogEntriesRemoverInterface $channelPricingLogEntriesRemover)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->addArgument('days', InputArgument::REQUIRED, 'Number of days ago');
|
||||
}
|
||||
|
||||
protected function initialize(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
$this->io = new SymfonyStyle($input, $output);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$days = filter_var($input->getArgument('days'), \FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
|
||||
if (false === $days) {
|
||||
$this->io->error('Number of days must be an integer greater than 0');
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
if ($input->isInteractive()) {
|
||||
$confirmation = $this->io->confirm(sprintf(
|
||||
'Are you sure you want to clear the price history from before %s days ago?',
|
||||
$days,
|
||||
), false);
|
||||
|
||||
if (false === $confirmation) {
|
||||
return Command::INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
$this->channelPricingLogEntriesRemover->remove($days);
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?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\Bundle\CoreBundle\PriceHistory\Event;
|
||||
|
||||
interface OldChannelPricingLogEntriesEvents
|
||||
{
|
||||
public const PRE_REMOVE = 'sylius.old_channel_pricing_log_entries.pre_remove';
|
||||
|
||||
public const POST_REMOVE = 'sylius.old_channel_pricing_log_entries.post_remove';
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?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\Bundle\CoreBundle\PriceHistory\Remover;
|
||||
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Sylius\Bundle\CoreBundle\PriceHistory\Event\OldChannelPricingLogEntriesEvents;
|
||||
use Sylius\Calendar\Provider\DateTimeProviderInterface;
|
||||
use Sylius\Component\Core\Repository\ChannelPricingLogEntryRepositoryInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final class ChannelPricingLogEntriesRemover implements ChannelPricingLogEntriesRemoverInterface
|
||||
{
|
||||
public function __construct(
|
||||
private ChannelPricingLogEntryRepositoryInterface $channelPricingLogEntriesRepository,
|
||||
private ObjectManager $channelPricingLogEntriesManager,
|
||||
private DateTimeProviderInterface $dateTimeProvider,
|
||||
private EventDispatcherInterface $eventDispatcher,
|
||||
private int $batchSize = 100,
|
||||
) {
|
||||
}
|
||||
|
||||
public function remove(int $fromDays): void
|
||||
{
|
||||
$fromDate = $this->getFromDate($fromDays);
|
||||
while ([] !== $oldChannelPricingLogEntries = $this->getBatch($fromDate)) {
|
||||
foreach ($oldChannelPricingLogEntries as $oldChannelPricingLogEntry) {
|
||||
$this->channelPricingLogEntriesManager->remove($oldChannelPricingLogEntry);
|
||||
}
|
||||
|
||||
$this->processDeletion($oldChannelPricingLogEntries);
|
||||
}
|
||||
}
|
||||
|
||||
private function getBatch(\DateTimeInterface $fromDate): array
|
||||
{
|
||||
return $this->channelPricingLogEntriesRepository->findOlderThan($fromDate, $this->batchSize);
|
||||
}
|
||||
|
||||
private function processDeletion(array $deletedChannelPricingLogEntries): void
|
||||
{
|
||||
$this->eventDispatcher->dispatch(new GenericEvent($deletedChannelPricingLogEntries), OldChannelPricingLogEntriesEvents::PRE_REMOVE);
|
||||
$this->channelPricingLogEntriesManager->flush();
|
||||
$this->eventDispatcher->dispatch(new GenericEvent($deletedChannelPricingLogEntries), OldChannelPricingLogEntriesEvents::POST_REMOVE);
|
||||
$this->channelPricingLogEntriesManager->clear();
|
||||
}
|
||||
|
||||
private function getFromDate(int $fromDays): \DateTimeInterface
|
||||
{
|
||||
$now = $this->dateTimeProvider->now();
|
||||
Assert::methodExists($now, 'modify');
|
||||
|
||||
/** @psalm-suppress UndefinedInterfaceMethod */
|
||||
return $now->modify(sprintf('-%d days', $fromDays));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?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\Bundle\CoreBundle\PriceHistory\Remover;
|
||||
|
||||
interface ChannelPricingLogEntriesRemoverInterface
|
||||
{
|
||||
public function remove(int $fromDays): void;
|
||||
}
|
||||
|
|
@ -45,6 +45,7 @@
|
|||
<parameter key="sylius.order_item_quantity_modifier.limit">9999</parameter>
|
||||
<parameter key="env(SYLIUS_UNSECURED_URLS)">yes</parameter>
|
||||
<parameter key="sylius.unsecured_urls">%env(bool:SYLIUS_UNSECURED_URLS)%</parameter>
|
||||
<parameter key="sylius.channel_pricing_log_entry.old_logs_removal_batch_size">100</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
|
|
@ -229,6 +230,14 @@
|
|||
</service>
|
||||
<service id="Sylius\Bundle\CoreBundle\Remover\ReviewerReviewsRemoverInterface" alias="sylius.reviewer_reviews_remover" />
|
||||
|
||||
<service id="Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface" class="Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemover">
|
||||
<argument type="service" id="sylius.repository.channel_pricing_log_entry" />
|
||||
<argument type="service" id="doctrine.orm.entity_manager" />
|
||||
<argument type="service" id="Sylius\Calendar\Provider\DateTimeProviderInterface" />
|
||||
<argument type="service" id="event_dispatcher" />
|
||||
<argument>%sylius.channel_pricing_log_entry.old_logs_removal_batch_size%</argument>
|
||||
</service>
|
||||
|
||||
<service id="sylius.unpaid_orders_state_updater" class="Sylius\Component\Core\Updater\UnpaidOrdersStateUpdater">
|
||||
<argument type="service" id="sylius.repository.order" />
|
||||
<argument type="service" id="sm.factory" />
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@
|
|||
<tag name="console.command" />
|
||||
</service>
|
||||
|
||||
<service id="Sylius\Bundle\CoreBundle\PriceHistory\Command\ClearPriceHistoryCommand">
|
||||
<argument type="service" id="Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface" />
|
||||
<tag name="console.command"/>
|
||||
</service>
|
||||
|
||||
<service id="Sylius\Bundle\CoreBundle\Command\InstallAssetsCommand">
|
||||
<tag name="console.command" />
|
||||
</service>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,124 @@
|
|||
<?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 Tests\Sylius\Bundle\CoreBundle\PriceHistory\Command;
|
||||
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Sylius\Bundle\CoreBundle\PriceHistory\Command\ClearPriceHistoryCommand;
|
||||
use Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemoverInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
|
||||
final class ClearPriceHistoryCommandTest extends TestCase
|
||||
{
|
||||
private CommandTester $commandTester;
|
||||
|
||||
private MockObject $remover;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->remover = $this->createMock(ChannelPricingLogEntriesRemoverInterface::class);
|
||||
|
||||
$this->commandTester = new CommandTester(new ClearPriceHistoryCommand($this->remover));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @dataProvider getInvalidDays
|
||||
*/
|
||||
public function it_does_not_clear_pricing_history_when_number_of_days_is_invalid(mixed $days): void
|
||||
{
|
||||
$this->remover->expects($this->never())->method('remove');
|
||||
|
||||
$this->commandTester->execute(['days' => $days]);
|
||||
|
||||
$this->assertSame(Command::FAILURE, $this->commandTester->getStatusCode());
|
||||
$this->assertStringContainsString(
|
||||
'Number of days must be an integer greater than 0',
|
||||
$this->commandTester->getDisplay(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @dataProvider getValidDays
|
||||
*/
|
||||
public function it_clears_pricing_history_when_non_interactive(int|string $days): void
|
||||
{
|
||||
$this->remover->expects($this->once())->method('remove');
|
||||
|
||||
$this->commandTester->execute(['days' => $days], ['interactive' => false]);
|
||||
|
||||
$this->commandTester->assertCommandIsSuccessful();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_asks_for_confirmation_when_interactive(): void
|
||||
{
|
||||
$this->remover->expects($this->once())->method('remove');
|
||||
|
||||
$this->commandTester->setInputs(['yes']);
|
||||
$this->commandTester->execute(['days' => 30], ['interactive' => true]);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'Are you sure you want to clear the price history from before 30 days ago?',
|
||||
$this->commandTester->getDisplay(),
|
||||
);
|
||||
$this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_nothing_when_user_does_not_confirm(): void
|
||||
{
|
||||
$this->remover->expects($this->never())->method('remove');
|
||||
|
||||
$this->commandTester->setInputs(['no']);
|
||||
$this->commandTester->execute(['days' => 30], ['interactive' => true]);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'Are you sure you want to clear the price history from before 30 days ago?',
|
||||
$this->commandTester->getDisplay(),
|
||||
);
|
||||
$this->assertSame(Command::INVALID, $this->commandTester->getStatusCode());
|
||||
}
|
||||
|
||||
public function getInvalidDays(): iterable
|
||||
{
|
||||
yield [0];
|
||||
yield ['0'];
|
||||
yield [0.0];
|
||||
yield ['0.0'];
|
||||
yield [-1];
|
||||
yield ['-1'];
|
||||
yield [-1.0];
|
||||
yield ['-1.0'];
|
||||
yield [1.1];
|
||||
yield ['1.1'];
|
||||
yield ['a'];
|
||||
}
|
||||
|
||||
public function getValidDays(): iterable
|
||||
{
|
||||
yield [1];
|
||||
yield ['1'];
|
||||
yield [30];
|
||||
yield ['30'];
|
||||
yield [60];
|
||||
yield ['60'];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<?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 spec\Sylius\Bundle\CoreBundle\PriceHistory\Remover;
|
||||
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use Sylius\Bundle\CoreBundle\PriceHistory\Event\OldChannelPricingLogEntriesEvents;
|
||||
use Sylius\Bundle\CoreBundle\PriceHistory\Remover\ChannelPricingLogEntriesRemover;
|
||||
use Sylius\Calendar\Provider\DateTimeProviderInterface;
|
||||
use Sylius\Component\Core\Model\ChannelPricingLogEntryInterface;
|
||||
use Sylius\Component\Core\Repository\ChannelPricingLogEntryRepositoryInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
final class ChannelPricingLogEntriesRemoverSpec extends ObjectBehavior
|
||||
{
|
||||
private const BATCH_SIZE = 1;
|
||||
|
||||
function let(
|
||||
ChannelPricingLogEntryRepositoryInterface $channelPricingLogEntriesRepository,
|
||||
ObjectManager $manager,
|
||||
DateTimeProviderInterface $dateTimeProvider,
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
): void {
|
||||
$this->beConstructedWith(
|
||||
$channelPricingLogEntriesRepository,
|
||||
$manager,
|
||||
$dateTimeProvider,
|
||||
$eventDispatcher,
|
||||
self::BATCH_SIZE,
|
||||
);
|
||||
}
|
||||
|
||||
function it_implements_channel_pricing_log_entries_remover_interface(): void
|
||||
{
|
||||
$this->shouldImplement(ChannelPricingLogEntriesRemover::class);
|
||||
}
|
||||
|
||||
function it_does_nothing_when_no_log_entries_were_found(
|
||||
ChannelPricingLogEntryRepositoryInterface $channelPricingLogEntriesRepository,
|
||||
ObjectManager $manager,
|
||||
DateTimeProviderInterface $dateTimeProvider,
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
): void {
|
||||
$date = new \DateTimeImmutable();
|
||||
$dateTimeProvider->now()->willReturn($date);
|
||||
|
||||
$channelPricingLogEntriesRepository->findOlderThan($date->modify('-1 days'), self::BATCH_SIZE)->willReturn([]);
|
||||
|
||||
$manager->remove(Argument::any())->shouldNotBeCalled();
|
||||
$manager->flush()->shouldNotBeCalled();
|
||||
$manager->clear()->shouldNotBeCalled();
|
||||
|
||||
$eventDispatcher->dispatch(Argument::cetera())->shouldNotBeCalled();
|
||||
|
||||
$this->remove(1);
|
||||
}
|
||||
|
||||
function it_removes_a_single_batch_of_channel_pricing_log_entries_when_there_is_no_more(
|
||||
ChannelPricingLogEntryRepositoryInterface $channelPricingLogEntriesRepository,
|
||||
ObjectManager $manager,
|
||||
DateTimeProviderInterface $dateTimeProvider,
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
ChannelPricingLogEntryInterface $channelPricingLogEntry,
|
||||
): void {
|
||||
$date = new \DateTimeImmutable();
|
||||
$dateTimeProvider->now()->willReturn($date);
|
||||
|
||||
$channelPricingLogEntriesRepository
|
||||
->findOlderThan($date->modify('-1 days'), self::BATCH_SIZE)
|
||||
->willReturn([$channelPricingLogEntry], [])
|
||||
;
|
||||
|
||||
$manager->remove($channelPricingLogEntry)->shouldBeCalled();
|
||||
|
||||
$eventDispatcher->dispatch(
|
||||
new GenericEvent([$channelPricingLogEntry->getWrappedObject()]),
|
||||
OldChannelPricingLogEntriesEvents::PRE_REMOVE,
|
||||
)->shouldBeCalled();
|
||||
$manager->flush()->shouldBeCalled();
|
||||
|
||||
$eventDispatcher->dispatch(
|
||||
new GenericEvent([$channelPricingLogEntry->getWrappedObject()]),
|
||||
OldChannelPricingLogEntriesEvents::POST_REMOVE,
|
||||
)->shouldBeCalled();
|
||||
$manager->clear()->shouldBeCalled();
|
||||
|
||||
$this->remove(1);
|
||||
}
|
||||
|
||||
function it_removes_multiple_batches_of_channel_pricing_log_entries(
|
||||
ChannelPricingLogEntryRepositoryInterface $channelPricingLogEntriesRepository,
|
||||
ObjectManager $manager,
|
||||
DateTimeProviderInterface $dateTimeProvider,
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
ChannelPricingLogEntryInterface $firstChannelPricingLogEntry,
|
||||
ChannelPricingLogEntryInterface $secondChannelPricingLogEntry,
|
||||
): void {
|
||||
$date = new \DateTimeImmutable();
|
||||
$dateTimeProvider->now()->willReturn($date);
|
||||
|
||||
$channelPricingLogEntriesRepository
|
||||
->findOlderThan($date->modify('-1 days'), self::BATCH_SIZE)
|
||||
->willReturn([$firstChannelPricingLogEntry], [$secondChannelPricingLogEntry], [])
|
||||
;
|
||||
|
||||
$eventDispatcher->dispatch(
|
||||
new GenericEvent([$firstChannelPricingLogEntry->getWrappedObject()]),
|
||||
OldChannelPricingLogEntriesEvents::PRE_REMOVE,
|
||||
)->shouldBeCalledTimes(1);
|
||||
$eventDispatcher->dispatch(
|
||||
new GenericEvent([$secondChannelPricingLogEntry->getWrappedObject()]),
|
||||
OldChannelPricingLogEntriesEvents::PRE_REMOVE,
|
||||
)->shouldBeCalledTimes(1);
|
||||
|
||||
$manager->remove($firstChannelPricingLogEntry)->shouldBeCalledTimes(1);
|
||||
$manager->remove($secondChannelPricingLogEntry)->shouldBeCalledTimes(1);
|
||||
|
||||
$eventDispatcher->dispatch(
|
||||
new GenericEvent([$firstChannelPricingLogEntry->getWrappedObject()]),
|
||||
OldChannelPricingLogEntriesEvents::POST_REMOVE,
|
||||
)->shouldBeCalledTimes(1);
|
||||
$eventDispatcher->dispatch(
|
||||
new GenericEvent([$secondChannelPricingLogEntry->getWrappedObject()]),
|
||||
OldChannelPricingLogEntriesEvents::POST_REMOVE,
|
||||
)->shouldBeCalledTimes(1);
|
||||
|
||||
$manager->flush()->shouldBeCalledTimes(2);
|
||||
$manager->clear()->shouldBeCalledTimes(2);
|
||||
|
||||
$this->remove(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue