Protect from menu taxon deletion

This commit is contained in:
Mateusz Zalewski 2020-01-10 15:11:54 +01:00
parent 9b6ce70599
commit afcb228a8c
No known key found for this signature in database
GPG key ID: 9BECA0BB71612E52
6 changed files with 80 additions and 3 deletions

View file

@ -24,7 +24,7 @@ Feature: Deleting a taxon
And the taxon named "Women" should no longer exist in the registry
But the "Shovels" taxon should appear in the registry
@ui
@ui @javascript
Scenario: Deleted taxon should disappear from the registry
Given the store classifies its products as "T-Shirts" and "Caps"
And the store operates on a channel named "Web Store"

View file

@ -393,7 +393,7 @@ final class ManagingTaxonsContext implements Context
public function iShouldBeNotifiedThatICannotDeleteAMenuTaxonOfAnyChannel(): void
{
$this->notificationChecker->checkNotification(
'You cannot delete a menu taxon of any channel',
'You cannot delete a menu taxon of any channel.',
NotificationType::failure()
);
}

View file

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\EventListener;
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Core\Promotion\Updater\Rule\TaxonAwareRuleUpdaterInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
@ -25,17 +26,37 @@ final class TaxonDeletionListener
/** @var SessionInterface */
private $session;
/** @var ChannelRepositoryInterface $channelRepository */
private $channelRepository;
/** @var TaxonAwareRuleUpdaterInterface[] */
private $ruleUpdaters;
public function __construct(
SessionInterface $session,
ChannelRepositoryInterface $channelRepository,
TaxonAwareRuleUpdaterInterface ...$ruleUpdaters
) {
$this->session = $session;
$this->channelRepository = $channelRepository;
$this->ruleUpdaters = $ruleUpdaters;
}
public function protectFromRemovingMenuTaxon(GenericEvent $event): void
{
$taxon = $event->getSubject();
Assert::isInstanceOf($taxon, TaxonInterface::class);
$channel = $this->channelRepository->findOneBy(['menuTaxon' => $taxon]);
if ($channel !== null) {
/** @var FlashBagInterface $flashes */
$flashes = $this->session->getBag('flashes');
$flashes->add('error', 'sylius.taxon.menu_taxon_delete');
$event->stopPropagation();
}
}
public function removeTaxonFromPromotionRules(GenericEvent $event): void
{
$taxon = $event->getSubject();

View file

@ -98,8 +98,10 @@
<service id="sylius.listener.taxon_deletion" class="Sylius\Bundle\CoreBundle\EventListener\TaxonDeletionListener">
<argument type="service" id="session" />
<argument type="service" id="sylius.repository.channel" />
<argument type="service" id="sylius.promotion_rule_updater.total_of_items_from_taxon" />
<argument type="service" id="sylius.promotion_rule_updater.has_taxon" />
<tag name="kernel.event_listener" event="sylius.taxon.pre_delete" method="protectFromRemovingMenuTaxon" />
<tag name="kernel.event_listener" event="sylius.taxon.post_delete" method="removeTaxonFromPromotionRules" />
</service>
</services>

View file

@ -14,6 +14,8 @@ declare(strict_types=1);
namespace spec\Sylius\Bundle\CoreBundle\EventListener;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Core\Promotion\Updater\Rule\TaxonAwareRuleUpdaterInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
@ -24,10 +26,60 @@ final class TaxonDeletionListenerSpec extends ObjectBehavior
{
function let(
SessionInterface $session,
ChannelRepositoryInterface $channelRepository,
TaxonAwareRuleUpdaterInterface $hasTaxonRuleUpdater,
TaxonAwareRuleUpdaterInterface $totalOfItemsFromTaxonRuleUpdater
): void {
$this->beConstructedWith($session, $hasTaxonRuleUpdater, $totalOfItemsFromTaxonRuleUpdater);
$this->beConstructedWith(
$session,
$channelRepository,
$hasTaxonRuleUpdater,
$totalOfItemsFromTaxonRuleUpdater
);
}
function it_does_not_allow_to_remove_taxon_if_any_channel_has_it_as_a_menu_taxon(
SessionInterface $session,
ChannelRepositoryInterface $channelRepository,
GenericEvent $event,
TaxonInterface $taxon,
ChannelInterface $channel,
FlashBagInterface $flashes
): void {
$event->getSubject()->willReturn($taxon);
$channelRepository->findOneBy(['menuTaxon' => $taxon])->willReturn($channel);
$session->getBag('flashes')->willReturn($flashes);
$flashes->add('error', 'sylius.taxon.menu_taxon_delete')->shouldBeCalled();
$event->stopPropagation()->shouldBeCalled();
$this->protectFromRemovingMenuTaxon($event);
}
function it_does_nothing_if_taxon_is_not_a_menu_taxon_of_any_channel(
SessionInterface $session,
ChannelRepositoryInterface $channelRepository,
GenericEvent $event,
TaxonInterface $taxon,
ChannelInterface $channel
): void {
$event->getSubject()->willReturn($taxon);
$channelRepository->findOneBy(['menuTaxon' => $taxon])->willReturn(null);
$session->getBag('flashes')->shouldNotBeCalled();
$this->protectFromRemovingMenuTaxon($event);
}
function it_throws_an_exception_if_an_event_subject_is_not_taxon(GenericEvent $event): void
{
$event->getSubject()->willReturn('wrongSubject');
$this
->shouldThrow(\InvalidArgumentException::class)
->during('protectFromRemovingMenuTaxon', [$event])
;
}
function it_adds_flash_that_promotions_have_been_updated(

View file

@ -26,3 +26,5 @@ sylius:
update_error: 'There was an unexpected problem with updating a product variant. Please, try to update product variant again.'
promotion:
update_rules: 'Some rules of the promotions with codes %codes% have been updated.'
taxon:
menu_taxon_delete: 'You cannot delete a menu taxon of any channel.'