[API] Protect shipping method from removal when in use

This commit is contained in:
Łukasz Chruściel 2020-03-20 09:09:37 +01:00
parent a7c8cc5698
commit 8e46a6062c
No known key found for this signature in database
GPG key ID: 428B9D810DB2ACDF
7 changed files with 118 additions and 2 deletions

View file

@ -11,3 +11,4 @@ api_platform:
exception_to_status:
SM\SMException: 422
Sylius\Bundle\ApiBundle\Exception\CannotRemoveCurrentlyLoggedInUser: 422
Sylius\Bundle\ApiBundle\Exception\ShippingMethodCannotBeRemoved: 422

View file

@ -14,7 +14,7 @@ Feature: Prevent deletion of used shipping method
And the customer chose "DHL Express" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
@ui
@ui @api
Scenario: Being unable to delete a shipping method which is in use
When I try to delete shipping method "DHL Express"
Then I should be notified that it is in use

View file

@ -53,7 +53,7 @@ final class ManagingShippingMethodsContext implements Context
}
/**
* @When I delete shipping method :shippingMethod
* @When I (try to )delete shipping method :shippingMethod
*/
public function iDeleteShippingMethod(ShippingMethodInterface $shippingMethod): void
{
@ -205,6 +205,19 @@ final class ManagingShippingMethodsContext implements Context
);
}
/**
* @Given /^(this shipping method) should still be in the registry$/
*/
public function thisShippingMethodShouldAppearInTheRegistry(ShippingMethodInterface $shippingMethod): void
{
$shippingMethodName = $shippingMethod->getName();
Assert::true(
$this->responseChecker->hasItemWithTranslation($this->client->index(), 'en_US', 'name', $shippingMethodName),
sprintf('Shipping method with name %s does not exists', $shippingMethodName)
);
}
/**
* @Then I should be notified that it has been successfully deleted
*/
@ -353,6 +366,17 @@ final class ManagingShippingMethodsContext implements Context
Assert::true($this->responseChecker->hasItemWithValue($response, 'code', $value));
}
/**
* @Then I should be notified that it is in use
*/
public function iShouldBeNotifiedThatItIsInUse(): void
{
Assert::contains(
$this->responseChecker->getError($this->client->getLastResponse()),
'Cannot delete, the shipping method is in use.'
);
}
/**
* @Then I should be notified that :element is required
*/

View file

@ -10,14 +10,23 @@ default:
- sylius.behat.context.setup.admin_api_security
- sylius.behat.context.setup.channel
- sylius.behat.context.setup.locale
- sylius.behat.context.setup.order
- sylius.behat.context.setup.payment
- sylius.behat.context.setup.product
- sylius.behat.context.setup.shipping
- sylius.behat.context.setup.shipping
- sylius.behat.context.setup.zone
- sylius.behat.context.transform.customer
- sylius.behat.context.transform.address
- sylius.behat.context.transform.channel
- sylius.behat.context.transform.locale
- sylius.behat.context.transform.payment
- sylius.behat.context.transform.product
- sylius.behat.context.transform.shared_storage
- sylius.behat.context.transform.shipping_calculator
- sylius.behat.context.transform.shipping_method
- sylius.behat.context.transform.shipping_method
- sylius.behat.context.transform.zone
- sylius.behat.context.api.admin.managing_shipping_methods

View file

@ -0,0 +1,55 @@
<?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\ApiBundle\DataPersister;
use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
use Sylius\Bundle\ApiBundle\Exception\CannotRemoveCurrentlyLoggedInUser;
use Sylius\Bundle\ApiBundle\Exception\ShippingMethodCannotBeRemoved;
use Sylius\Component\Core\Model\AdminUserInterface;
use Sylius\Component\Core\Model\ShippingMethodInterface;
use Sylius\Component\User\Model\UserInterface;
use Sylius\Component\User\Security\PasswordUpdaterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class ShippingMethodDataPersister implements ContextAwareDataPersisterInterface
{
/** @var ContextAwareDataPersisterInterface */
private $decoratedDataPersister;
public function __construct(
ContextAwareDataPersisterInterface $decoratedDataPersister
) {
$this->decoratedDataPersister = $decoratedDataPersister;
}
public function supports($data, array $context = []): bool
{
return $data instanceof ShippingMethodInterface;
}
public function persist($data, array $context = [])
{
return $this->decoratedDataPersister->persist($data, $context);
}
public function remove($data, array $context = [])
{
try {
return $this->decoratedDataPersister->remove($data, $context);
} catch (ForeignKeyConstraintViolationException $constraintViolationException) {
throw new ShippingMethodCannotBeRemoved();
}
}
}

View file

@ -0,0 +1,22 @@
<?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\ApiBundle\Exception;
final class ShippingMethodCannotBeRemoved extends \RuntimeException
{
public function __construct()
{
parent::__construct('Cannot delete, the shipping method is in use.');
}
}

View file

@ -31,6 +31,11 @@
<tag name="api_platform.data_persister" />
</service>
<service id="sylius.api.data_persister.shipping_method" class="Sylius\Bundle\ApiBundle\DataPersister\ShippingMethodDataPersister">
<argument type="service" id="api_platform.doctrine.orm.data_persister" />
<tag name="api_platform.data_persister" />
</service>
<service id="sylius.api.payment_state_machine_transition_applicator" class="Sylius\Bundle\ApiBundle\Applicator\PaymentStateMachineTransitionApplicator" public="true">
<argument id="sm.factory" type="service" />
</service>