mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-15 09:30:58 +00:00
Add validation for cart item quantity range
This commit is contained in:
parent
06c6fe06f9
commit
0e2772054e
8 changed files with 171 additions and 5 deletions
|
|
@ -16,7 +16,7 @@ Feature: Changing quantity of a product in cart
|
|||
Then I should see "T-Shirt banana" with quantity 2 in my cart
|
||||
And my cart items total should be "$25.08"
|
||||
|
||||
@todo-api @ui @javascript
|
||||
@api @ui @javascript
|
||||
Scenario: Increasing quantity of an item in cart beyond the threshold
|
||||
Given I see the summary of my cart
|
||||
When I change product "T-Shirt banana" quantity to 20000 in my cart
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ final class CartContext implements Context
|
|||
*/
|
||||
public function iShouldBeNotifiedThatTheQuantityOfThisProductMustBeBetween(ProductInterface $product): void
|
||||
{
|
||||
Assert::false($this->responseChecker->hasViolationWithMessage(
|
||||
Assert::true($this->responseChecker->hasViolationWithMessage(
|
||||
$this->shopClient->getLastResponse(),
|
||||
'Quantity must be between 1 and 9999.',
|
||||
));
|
||||
|
|
|
|||
|
|
@ -19,10 +19,11 @@
|
|||
</option>
|
||||
</constraint>
|
||||
<property name="quantity">
|
||||
<constraint name="Range">
|
||||
<constraint name="Sylius\Bundle\CoreBundle\Validator\Constraints\CartItemQuantityRange">
|
||||
<option name="min">1</option>
|
||||
<option name="minMessage">sylius.order_item.quantity.min</option>
|
||||
<option name="groups">sylius</option>
|
||||
<option name="groups">
|
||||
<value>sylius</value>
|
||||
</option>
|
||||
</constraint>
|
||||
<constraint name="NotBlank">
|
||||
<option name="message">sylius.order_item.quantity.not_blank</option>
|
||||
|
|
|
|||
|
|
@ -136,5 +136,11 @@
|
|||
<argument type="service" id="sylius.repository.zone" />
|
||||
<tag name="validator.constraint_validator" alias="sylius_zone_code_exists" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.validator.cart_item_quantity_range" class="Sylius\Bundle\CoreBundle\Validator\Constraints\CartItemQuantityRangeValidator">
|
||||
<argument type="service" id="property_accessor" />
|
||||
<argument>%sylius.order_item_quantity_modifier.limit%</argument>
|
||||
<tag name="validator.constraint_validator" alias="sylius_cart_item_quantity_range" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
|
|
@ -27,5 +27,13 @@
|
|||
<value>sylius_checkout_complete</value>
|
||||
</option>
|
||||
</constraint>
|
||||
<property name="quantity">
|
||||
<constraint name="Sylius\Bundle\CoreBundle\Validator\Constraints\CartItemQuantityRange">
|
||||
<option name="min">1</option>
|
||||
<option name="groups">
|
||||
<value>sylius</value>
|
||||
</option>
|
||||
</constraint>
|
||||
</property>
|
||||
</class>
|
||||
</constraint-mapping>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* 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\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Constraints\Range;
|
||||
|
||||
final class CartItemQuantityRange extends Range
|
||||
{
|
||||
public string $notInRangeMessage = 'sylius.cart_item.quantity.not_in_range';
|
||||
|
||||
public function validatedBy(): string
|
||||
{
|
||||
return 'sylius_cart_item_quantity_range';
|
||||
}
|
||||
|
||||
public function getTargets(): string
|
||||
{
|
||||
return Constraint::PROPERTY_CONSTRAINT;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* 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\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Constraints\RangeValidator;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class CartItemQuantityRangeValidator extends RangeValidator
|
||||
{
|
||||
public function __construct(
|
||||
PropertyAccessorInterface $propertyAccessor,
|
||||
private readonly int $orderItemQuantityModifierLimit,
|
||||
) {
|
||||
parent::__construct($propertyAccessor);
|
||||
}
|
||||
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!$constraint instanceof CartItemQuantityRange) {
|
||||
throw new UnexpectedTypeException($constraint, CartItemQuantityRange::class);
|
||||
}
|
||||
|
||||
$constraint->max = $this->orderItemQuantityModifierLimit;
|
||||
|
||||
parent::validate($value, $constraint);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* 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\Validator\Constraints;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use Sylius\Bundle\CoreBundle\Validator\Constraints\CartItemQuantityRange;
|
||||
use Sylius\Bundle\CoreBundle\Validator\Constraints\CountryCodeExists;
|
||||
use Sylius\Component\Addressing\Model\CountryInterface;
|
||||
use Sylius\Resource\Doctrine\Persistence\RepositoryInterface;
|
||||
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
|
||||
|
||||
final class CartItemQuantityRangeValidatorSpec extends ObjectBehavior
|
||||
{
|
||||
const MESSAGE = 'sylius.cart_item.quantity.not_in_range';
|
||||
|
||||
function let(PropertyAccessorInterface $propertyAccessor, ExecutionContextInterface $context): void
|
||||
{
|
||||
$this->beConstructedWith($propertyAccessor, 17);
|
||||
|
||||
$this->initialize($context);
|
||||
}
|
||||
|
||||
function it_throws_an_exception_if_constraint_is_not_an_instance_of_cart_item_quantity_range(
|
||||
Constraint $constraint,
|
||||
): void {
|
||||
$this
|
||||
->shouldThrow(UnexpectedTypeException::class)
|
||||
->during('validate', [9, $constraint])
|
||||
;
|
||||
}
|
||||
|
||||
function it_does_nothing_if_value_is_empty(
|
||||
ExecutionContextInterface $context,
|
||||
): void {
|
||||
$this->validate(null, new CartItemQuantityRange(min: 1));
|
||||
|
||||
$context->buildViolation(self::MESSAGE)->shouldNotHaveBeenCalled();
|
||||
}
|
||||
|
||||
function it_does_nothing_if_value_is_in_range(
|
||||
RepositoryInterface $countryRepository,
|
||||
ExecutionContextInterface $context,
|
||||
CountryInterface $country,
|
||||
): void {
|
||||
$this->validate(5, new CartItemQuantityRange(min: 1));
|
||||
|
||||
$context->buildViolation(self::MESSAGE)->shouldNotHaveBeenCalled();
|
||||
}
|
||||
|
||||
function it_adds_a_violation_if_value_is_not_in_range(
|
||||
ExecutionContextInterface $context,
|
||||
ConstraintViolationBuilderInterface $constraintViolationBuilder,
|
||||
): void {
|
||||
$constraintViolationBuilder->addViolation()->shouldBeCalled();
|
||||
$constraintViolationBuilder->setCode(CartItemQuantityRange::NOT_IN_RANGE_ERROR)->willReturn($constraintViolationBuilder);
|
||||
$constraintViolationBuilder->atPath(Argument::any())->willReturn($constraintViolationBuilder);
|
||||
$constraintViolationBuilder->setParameter(Argument::cetera())->willReturn($constraintViolationBuilder);
|
||||
|
||||
$context->buildViolation(self::MESSAGE)->shouldBeCalled()->willReturn($constraintViolationBuilder);
|
||||
|
||||
$this->validate(18, new CartItemQuantityRange(min: 1));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue